# HG changeset patch # User Gilles Duboscq # Date 1312558835 -7200 # Node ID ce7cf6d16b3876075f369fb181f42ef002c762a9 # Parent a64b615ba63092f6e95cc716643b461364459704 Reintroduce Conditional (IfOp) using the new infrastructure, fix the Cmov support in the backend, use x86 cmov when possible, make it work with floating point comparison conditions, make MaterializeNode a subclass of Conditional, fix nasty bug related to introducing LIR jumps in an existing LIRBlock in MaterializeNode/Conditional Canonicalize FDConversionNode if input is constant diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Fri Aug 05 17:40:35 2011 +0200 @@ -246,7 +246,6 @@ if (GraalOptions.Time) { GraalTimers.LIR_CREATE.stop(); } - if (GraalOptions.PrintLIR && !TTY.isSuppressed()) { LIRList.printLIR(hir.linearScanOrder()); } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Aug 05 17:40:35 2011 +0200 @@ -581,23 +581,11 @@ LIRItem xin = xitem; LIRItem yin = yitem; - if (kind.isLong()) { - // for longs, only conditions "eql", "neq", "lss", "geq" are valid; - // mirror for other conditions - if (cond == Condition.GT || cond == Condition.LE) { - cond = cond.mirror(); - xin = yitem; - yin = xitem; - } - xin.setDestroysRegister(); + if (kind.isFloat() || kind.isDouble()) { + cond = floatingPointCondition(cond); } + xin.loadItem(); - if (kind.isLong() && yin.result().isConstant() && yin.instruction.asConstant().asLong() == 0 && (cond == Condition.EQ || cond == Condition.NE)) { - // dont load item - } else if (kind.isLong() || kind.isFloat() || kind.isDouble()) { - // longs cannot handle constants at right side - yin.loadItem(); - } CiValue left = xin.result(); CiValue right = yin.result(); @@ -1858,4 +1846,6 @@ ((Value) n).accept(generator); } }; + + public abstract Condition floatingPointCondition(Condition cond); } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Fri Aug 05 17:40:35 2011 +0200 @@ -136,6 +136,8 @@ graph.stopRecordModifications(); } + new ConvertConditionalPhase().apply(graph); + new LoweringPhase(compilation.runtime).apply(graph); if (GraalOptions.Lower) { new MemoryPhase().apply(graph); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -62,7 +63,7 @@ private static class AndCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { assert node instanceof And; And and = (And) node; CiKind kind = and.kind; diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.graph.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; @@ -109,7 +110,7 @@ private static class ArrayLengthCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { ArrayLength arrayLength = (ArrayLength) node; Value array = arrayLength.array(); if (array instanceof NewArray) { diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -97,7 +98,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { CheckCast checkCast = (CheckCast) node; Value object = checkCast.object(); RiType exactType = object.exactType(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.max.graal.compiler.ir; +import java.util.*; + import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.graph.*; @@ -77,8 +79,8 @@ return (Value) inputs().set(super.inputCount() + INPUT_Y, n); } - Condition condition; - boolean unorderedIsTrue; + private Condition condition; + private boolean unorderedIsTrue; /** * Constructs a new Compare instruction. @@ -131,6 +133,11 @@ setY(t); } + public void negate() { + condition = condition.negate(); + unorderedIsTrue = !unorderedIsTrue; + } + @Override public void accept(ValueVisitor v) { } @@ -160,6 +167,13 @@ } @Override + public Map getDebugProperties() { + Map properties = super.getDebugProperties(); + properties.put("unorderedIsTrue", unorderedIsTrue()); + return properties; + } + + @Override public Node copy(Graph into) { Compare x = new Compare(null, condition, null, into); x.unorderedIsTrue = unorderedIsTrue; @@ -168,17 +182,14 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { Compare compare = (Compare) node; if (compare.x().isConstant() && !compare.y().isConstant()) { // move constants to the left (y) - Value x = compare.x(); - compare.setX(compare.y()); - compare.setY(x); - compare.condition = compare.condition.mirror(); + compare.swapOperands(); } else if (compare.x().isConstant() && compare.y().isConstant()) { CiConstant constX = compare.x().asConstant(); CiConstant constY = compare.y().asConstant(); - Boolean result = compare.condition().foldCondition(constX, constY, ((CompilerGraph) node.graph()).runtime()); + Boolean result = compare.condition().foldCondition(constX, constY, ((CompilerGraph) node.graph()).runtime(), compare.unorderedIsTrue()); if (result != null) { if (GraalOptions.TraceCanonicalizer) { TTY.println("folded condition " + constX + " " + compare.condition() + " " + constY); @@ -219,6 +230,20 @@ } } } + boolean allUsagesNegate = true; + List usages = new ArrayList(compare.usages()); + for (Node usage : usages) { + if (!(usage instanceof NegateBooleanNode)) { + allUsagesNegate = false; + break; + } + } + if (allUsagesNegate) { + compare.negate(); + for (Node usage : usages) { + usage.replaceAtUsages(compare); + } + } return compare; } @@ -229,7 +254,7 @@ if (compare.condition == Condition.NE) { isFalseCheck = !isFalseCheck; } - BooleanNode result = materializeNode.value(); + BooleanNode result = materializeNode.condition(); if (isFalseCheck) { result = new NegateBooleanNode(result, compare.graph()); } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Fri Aug 05 17:40:35 2011 +0200 @@ -171,7 +171,7 @@ * @return {@link Boolean#TRUE} if the comparison is known to be true, * {@link Boolean#FALSE} if the comparison is known to be false, {@code null} otherwise. */ - public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime) { + public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime, boolean unorderedIsTrue) { switch (lt.kind) { case Boolean: case Int: { @@ -211,7 +211,44 @@ } break; } - // XXX: folding of floating comparisons should be possible + case Float: { + float x = lt.asFloat(); + float y = rt.asFloat(); + if (Float.isNaN(x) || Float.isNaN(y)) { + return unorderedIsTrue; + } + switch (this) { + case EQ: return x == y; + case NE: return x != y; + case BT: + case LT: return x < y; + case BE: + case LE: return x <= y; + case AT: + case GT: return x > y; + case AE: + case GE: return x >= y; + } + } + case Double: { + double x = lt.asDouble(); + double y = rt.asDouble(); + if (Double.isNaN(x) || Double.isNaN(y)) { + return unorderedIsTrue; + } + switch (this) { + case EQ: return x == y; + case NE: return x != y; + case BT: + case LT: return x < y; + case BE: + case LE: return x <= y; + case AT: + case GT: return x > y; + case AE: + case GE: return x >= y; + } + } } return null; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; -import com.oracle.max.asm.*; +import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.gen.LIRGenerator.LIRGeneratorOp; -import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; +import com.oracle.max.graal.compiler.util.*; +import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -37,10 +39,11 @@ * Note that these nodes are not built directly from the bytecode but are introduced * by conditional expression elimination. */ -public final class Conditional extends Binary { +public class Conditional extends Binary { - private static final int INPUT_COUNT = 1; + private static final int INPUT_COUNT = 2; private static final int INPUT_CONDITION = 0; + private static final int INPUT_STATE = 1; private static final int SUCCESSOR_COUNT = 0; @@ -62,6 +65,14 @@ inputs().set(super.inputCount() + INPUT_CONDITION, n); } + public FrameState stateDuring() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE); + } + + public void setStateDuring(FrameState n) { + inputs().set(super.inputCount() + INPUT_STATE, n); + } + /** * Constructs a new IfOp. * @param x the instruction producing the first value to be compared @@ -89,6 +100,14 @@ return y(); } + public Value setTrueValue(Value value) { + return setX(value); + } + + public Value setFalseValue(Value value) { + return setY(value); + } + @Override public boolean valueEqual(Node i) { if (i instanceof Conditional) { @@ -130,7 +149,7 @@ private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { Conditional conditional = (Conditional) node; BooleanNode condition = conditional.condition(); Value trueValue = conditional.trueValue(); @@ -146,17 +165,31 @@ if (trueValue == falseValue) { return trueValue; } - if (trueValue instanceof Constant && falseValue instanceof Constant + if (!(conditional instanceof MaterializeNode) && trueValue instanceof Constant && falseValue instanceof Constant && trueValue.kind == CiKind.Int && falseValue.kind == CiKind.Int) { int trueInt = trueValue.asConstant().asInt(); int falseInt = falseValue.asConstant().asInt(); if (trueInt == 0 && falseInt == 1) { - TTY.println("> Conditional canon'ed to Materialize"); - return new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph()); + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Conditional canon'ed to ~Materialize"); + } + reProcess.reProccess(condition); // because we negate it + MaterializeNode materializeNode = new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph()); + materializeNode.setStateDuring(conditional.stateDuring()); + return materializeNode; } else if (trueInt == 1 && falseInt == 0) { - TTY.println("> Conditional canon'ed to Materialize"); - return new MaterializeNode(condition, node.graph()); + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Conditional canon'ed to Materialize"); + } + MaterializeNode materializeNode = new MaterializeNode(condition, node.graph()); + materializeNode.setStateDuring(conditional.stateDuring()); + return materializeNode; } + } else if (falseValue instanceof Constant && !(trueValue instanceof Constant)) { + conditional.setTrueValue(falseValue); + conditional.setFalseValue(trueValue); + condition = new NegateBooleanNode(condition, node.graph()); + conditional.setCondition(condition); } return conditional; } @@ -174,39 +207,52 @@ Condition cond = null; CiValue left = null; CiValue right = null; + boolean floating = false; + boolean unOrderedIsSecond = false; + boolean negate = false; + while (condition instanceof NegateBooleanNode) { + negate = !negate; + condition = ((NegateBooleanNode) condition).value(); + } if (condition instanceof Compare) { Compare compare = (Compare) condition; Value x = compare.x(); Value y = compare.y(); + cond = compare.condition(); + if (x.kind.isFloatOrDouble()) { + floating = true; + unOrderedIsSecond = !compare.unorderedIsTrue(); + cond = generator.floatingPointCondition(cond); + } left = generator.load(x); if (!generator.canInlineAsConstant(y)) { right = generator.load(y); } else { right = generator.makeOperand(y); } - cond = compare.condition; } else if (condition instanceof IsNonNull) { IsNonNull isNonNull = (IsNonNull) condition; left = generator.load(isNonNull.object()); right = CiConstant.NULL_OBJECT; cond = Condition.NE; + } else if (condition instanceof Constant) { + generator.lir().move(result, condition.asConstant()); + } else { + throw Util.shouldNotReachHere("Currently not implemented because we can not create blocks during LIRGen : " + condition); } CiValue tVal = generator.makeOperand(conditional.trueValue()); CiValue fVal = generator.makeOperand(conditional.falseValue()); if (cond != null) { + if (negate) { + cond = cond.negate(); + } assert left != null && right != null; generator.lir().cmp(cond, left, right); - generator.lir().cmove(cond, tVal, fVal, result); - } else { - LIRBlock trueSuccessor = new LIRBlock(new Label(), null); - generator.emitBooleanBranch(condition, trueSuccessor, null, null); - LIRList lir = generator.lir(); - lir.move(fVal, result); - Label label = new Label(); - lir.branch(Condition.TRUE, label); - lir.branchDestination(trueSuccessor.label); - lir.move(tVal, result); - lir.branchDestination(label); + if (floating) { + generator.lir().fcmove(cond, tVal, fVal, result, unOrderedIsSecond); + } else { + generator.lir().cmove(cond, tVal, fVal, result); + } } } }; diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java Fri Aug 05 17:40:35 2011 +0200 @@ -28,6 +28,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.Deoptimize.DeoptAction; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -77,7 +78,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FixedGuard fixedGuard = (FixedGuard) node; Iterator iter = fixedGuard.variableInputs().iterator(); while (iter.hasNext()) { diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -57,7 +58,7 @@ private static class FloatAddCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FloatAdd add = (FloatAdd) node; Value x = add.x(); Value y = add.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class FloatDivCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FloatDiv div = (FloatDiv) node; Value x = div.x(); Value y = div.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -67,7 +68,7 @@ private static class FloatMulCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FloatMul mul = (FloatMul) node; Value x = mul.x(); Value y = mul.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class FloatRemCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FloatRem rem = (FloatRem) node; Value x = rem.x(); Value y = rem.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class FloatSubCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { FloatSub sub = (FloatSub) node; Value x = sub.x(); Value y = sub.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -45,7 +46,7 @@ } /** - * The instruction that produces the object tested against null. + * The instruction that produces the tested boolean value. */ public BooleanNode node() { return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE); @@ -91,7 +92,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { GuardNode guard = (GuardNode) node; if (guard.node() instanceof Constant) { Constant c = (Constant) guard.node(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Fri Aug 05 17:40:35 2011 +0200 @@ -25,6 +25,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -146,7 +147,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { If ifNode = (If) node; if (ifNode.compare() instanceof Constant) { Constant c = (Constant) ifNode.compare(); @@ -165,15 +166,22 @@ if (ifNode.trueSuccessor() instanceof EndNode && ifNode.falseSuccessor() instanceof EndNode) { EndNode trueEnd = (EndNode) ifNode.trueSuccessor(); EndNode falseEnd = (EndNode) ifNode.falseSuccessor(); - if (trueEnd.merge() == falseEnd.merge() && trueEnd.merge().phis().size() == 0) { + Merge merge = trueEnd.merge(); + if (merge == falseEnd.merge() && merge.phis().size() == 0) { + FixedNode next = merge.next(); + merge.setNext(null); //disconnect to avoid next from having 2 preds if (ifNode.compare().usages().size() == 1 && /*ifNode.compare().hasSideEffets()*/ true) { // TODO (gd) ifNode.compare().hasSideEffets() ? - TTY.println("> Useless if with side effects Canon'ed to guard"); - FixedGuard guard = new FixedGuard(ifNode.compare(), node.graph()); - guard.setNext(trueEnd.merge().next()); - return guard; + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Useless if with side effects Canon'ed to guard"); + } + ValueAnchor anchor = new ValueAnchor(ifNode.compare(), node.graph()); + anchor.setNext(next); + return anchor; } else { - TTY.println("> Useless if Canon'ed away"); - return trueEnd.merge().next(); + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Useless if Canon'ed away"); + } + return next; } } } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -85,7 +86,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { InstanceOf isInstance = (InstanceOf) node; Value object = isInstance.object(); RiType exactType = object.exactType(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class IntegerAddCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IntegerAdd add = (IntegerAdd) node; Value x = add.x(); Value y = add.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class IntegerDivCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IntegerDiv div = (IntegerDiv) node; Value x = div.x(); Value y = div.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class IntegerMulCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IntegerMul mul = (IntegerMul) node; Value x = mul.x(); Value y = mul.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class IntegerRemCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IntegerRem rem = (IntegerRem) node; Value x = rem.x(); Value y = rem.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -56,7 +57,7 @@ private static class IntegerSubCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IntegerSub sub = (IntegerSub) node; Value x = sub.x(); Value y = sub.y(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -120,7 +121,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IsNonNull isNonNull = (IsNonNull) node; Value object = isNonNull.object(); if (object instanceof NewInstance || object instanceof NewArray) { diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java Fri Aug 05 17:40:35 2011 +0200 @@ -26,6 +26,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -140,7 +141,7 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { IsType isType = (IsType) node; Value object = isType.object(); RiType exactType = object.exactType(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java Fri Aug 05 17:40:35 2011 +0200 @@ -23,6 +23,7 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -57,7 +58,7 @@ private static class LeftShiftCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { LeftShift leftShift = (LeftShift) node; CiKind kind = leftShift.kind; Graph graph = leftShift.graph(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Fri Aug 05 17:40:35 2011 +0200 @@ -25,6 +25,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.LoweringPhase.LoweringOp; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -127,7 +128,7 @@ private static class LoadFieldCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { LoadField loadField = (LoadField) node; Graph graph = node.graph(); CiConstant constant = null; diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,48 +22,17 @@ */ package com.oracle.max.graal.compiler.ir; -import com.oracle.max.asm.*; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -public final class MaterializeNode extends FloatingNode { - private static final int INPUT_COUNT = 1; - private static final int INPUT_VALUE = 0; +public final class MaterializeNode extends Conditional { + private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; - @Override - protected int inputCount() { - return super.inputCount() + INPUT_COUNT; - } - - @Override - protected int successorCount() { - return super.successorCount() + SUCCESSOR_COUNT; - } - - /** - * The instruction which produces the input value to this instruction. - */ - public BooleanNode value() { - return (BooleanNode) inputs().get(super.inputCount() + INPUT_VALUE); - } - - public void setValue(BooleanNode n) { - inputs().set(super.inputCount() + INPUT_VALUE, n); - } public MaterializeNode(BooleanNode value, Graph graph) { - super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph); - setValue(value); - } - - @Override - public void accept(ValueVisitor v) { + super(value, Constant.forInt(1, graph), Constant.forInt(0, graph), graph); } @Override @@ -71,35 +40,9 @@ return (i instanceof MaterializeNode); } - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == LIRGenerator.LIRGeneratorOp.class) { - return (T) LIR_GENERATOR_OP; - } - return super.lookup(clazz); - } - - public static final LIRGenerator.LIRGeneratorOp LIR_GENERATOR_OP = new LIRGenerator.LIRGeneratorOp() { - - @Override - public void generate(Node n, LIRGenerator generator) { - LIRBlock trueSuccessor = new LIRBlock(new Label(), null); - generator.emitBooleanBranch(((MaterializeNode) n).value(), trueSuccessor, null, null); - CiValue result = generator.createResultVariable((Value) n); - LIRList lir = generator.lir(); - lir.move(CiConstant.FALSE, result); - Label label = new Label(); - lir.branch(Condition.TRUE, label); - lir.branchDestination(trueSuccessor.label); - lir.move(CiConstant.TRUE, result); - lir.branchDestination(label); - } - }; - @Override public void print(LogStream out) { - out.print("materialize(").print(value().toString()).print(')'); + out.print("materialize(").print(condition().toString()).print(')'); } @Override diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java Fri Aug 05 17:40:35 2011 +0200 @@ -23,6 +23,7 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; @@ -116,7 +117,7 @@ private static class NegateCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { Negate negate = (Negate) node; Value x = negate.x(); Graph graph = negate.graph(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -89,17 +90,13 @@ private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { NegateBooleanNode negateNode = (NegateBooleanNode) node; Value value = negateNode.value(); if (value instanceof NegateBooleanNode) { return ((NegateBooleanNode) value).value(); } else if (value instanceof Constant) { return Constant.forBoolean(!value.asConstant().asBoolean(), node.graph()); - } else if (value instanceof Compare) { - Compare compare = (Compare) value; - compare.condition = compare.condition.negate(); - return compare; } return negateNode; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.max.graal.compiler.ir; +import java.util.*; + import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -48,7 +50,7 @@ @Override public void accept(ValueVisitor v) { - v.visitMaterialize(this); + v.visitNormalizeCompare(this); } @Override @@ -65,6 +67,13 @@ return new NormalizeCompare(opcode, kind, null, null, into); } + @Override + public Map getDebugProperties() { + Map properties = super.getDebugProperties(); + properties.put("isUnorderedLess", isUnorderedLess()); + return properties; + } + public boolean isUnorderedLess() { return this.opcode == Bytecodes.FCMPL || this.opcode == Bytecodes.DCMPL; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -66,7 +67,7 @@ private static class OrCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { Or or = (Or) node; CiKind kind = or.kind; Graph graph = or.graph(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,9 +24,11 @@ import java.util.*; +import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.ir.StateSplit.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; +import com.oracle.max.graal.compiler.ir.StateSplit.FilteringIterator; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -188,12 +190,15 @@ private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { Phi phiNode = (Phi) node; if (phiNode.valueCount() != 2 || phiNode.merge().endCount() != 2) { return phiNode; } Merge merge = phiNode.merge(); + if (merge.phis().size() > 1) { // XXX (gd) disable canonicalization of multiple conditional while we are not able to fuse them and the potentially leftover If in the backend + return phiNode; + } Node end0 = merge.endAt(0); Node end1 = merge.endAt(1); if (end0.predecessors().size() != 1 || end1.predecessors().size() != 1) { @@ -211,11 +216,25 @@ boolean inverted = ifNode.trueSuccessor() == end1; Value trueValue = phiNode.valueAt(inverted ? 1 : 0); Value falseValue = phiNode.valueAt(inverted ? 0 : 1); - if (trueValue.kind != CiKind.Int || falseValue.kind != CiKind.Int) { + if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) { + return phiNode; + } + if ((!(trueValue instanceof Constant) && trueValue.usages().size() == 1) || (!(falseValue instanceof Constant) && falseValue.usages().size() == 1)) { return phiNode; } - TTY.println("> Phi canon'ed to Conditional"); - return new Conditional(ifNode.compare(), trueValue, falseValue, node.graph()); + BooleanNode compare = ifNode.compare(); + while (compare instanceof NegateBooleanNode) { + compare = ((NegateBooleanNode) compare).value(); + } + if (!(compare instanceof Compare || compare instanceof IsNonNull || compare instanceof NegateBooleanNode || compare instanceof Constant)) { + return phiNode; + } + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Phi canon'ed to Conditional"); + } + reProcess.reProccess(ifNode); + Conditional conditional = new Conditional(ifNode.compare(), trueValue, falseValue, node.graph()); + return conditional; } }; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Fri Aug 05 17:40:35 2011 +0200 @@ -26,6 +26,7 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -83,7 +84,7 @@ private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { RegisterFinalizer finalizer = (RegisterFinalizer) node; Value object = finalizer.object(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -57,7 +58,7 @@ private static class RighShiftCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { RightShift rightShift = (RightShift) node; CiKind kind = rightShift.kind; Graph graph = rightShift.graph(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -57,7 +58,7 @@ private static class UnsignedRightShiftCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { UnsignedRightShift ushr = (UnsignedRightShift) node; CiKind kind = ushr.kind; Graph graph = ushr.graph(); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Fri Aug 05 17:40:35 2011 +0200 @@ -35,7 +35,7 @@ public abstract void visitArrayLength(ArrayLength i); public abstract void visitMerge(Merge i); public abstract void visitCheckCast(CheckCast i); - public abstract void visitMaterialize(NormalizeCompare i); + public abstract void visitNormalizeCompare(NormalizeCompare i); public abstract void visitConstant(Constant i); public abstract void visitConvert(Convert i); public abstract void visitExceptionObject(ExceptionObject i); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java Fri Aug 05 17:40:35 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -63,7 +64,7 @@ private static class XorCanonicalizerOp implements CanonicalizerOp { @Override - public Node canonical(Node node) { + public Node canonical(Node node, NotifyReProcess reProcess) { assert node instanceof Xor; Xor xor = (Xor) node; CiKind kind = xor.kind; diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java Fri Aug 05 17:40:35 2011 +0200 @@ -276,8 +276,14 @@ emitCompare2Int(op.code, op.operand1(), op.operand2(), op.result(), op); break; + case FCmove: + emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, false); + break; + case UFCmove: + emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, true); + break; case Cmove: - emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result()); + emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), false, false); break; case Shl: @@ -418,7 +424,7 @@ protected abstract void emitSignificantBitOp(boolean most, CiValue inOpr1, CiValue dst); - protected abstract void emitConditionalMove(Condition condition, CiValue inOpr1, CiValue inOpr2, CiValue dst); + protected abstract void emitConditionalMove(Condition condition, CiValue inOpr1, CiValue inOpr2, CiValue dst, boolean mayBeUnordered, boolean unorderedcmovOpr1); protected abstract void emitCompare2Int(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIROp2 op); @@ -470,4 +476,15 @@ protected abstract void reg2reg(CiValue src, CiValue dest); + protected abstract boolean trueOnUnordered(Condition condition); + + protected abstract boolean falseOnUnordered(Condition condition); + + protected boolean mayBeTrueOnUnordered(Condition condition) { + return trueOnUnordered(condition) || !falseOnUnordered(condition); + } + + protected boolean mayBeFalseOnUnordered(Condition condition) { + return falseOnUnordered(condition) || !trueOnUnordered(condition); + } } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Fri Aug 05 17:40:35 2011 +0200 @@ -195,6 +195,10 @@ append(new LIROp2(LIROpcode.Cmove, condition, src1, src2, dst)); } + public void fcmove(Condition condition, CiValue src1, CiValue src2, CiValue dst, boolean unorderedIsSecond) { + append(new LIROp2(unorderedIsSecond ? LIROpcode.FCmove : LIROpcode.UFCmove, condition, src1, src2, dst)); + } + public void abs(CiValue from, CiValue to, CiValue tmp) { append(new LIROp2(LIROpcode.Abs, from, tmp, to)); } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java Fri Aug 05 17:40:35 2011 +0200 @@ -63,7 +63,7 @@ public LIROp2(LIROpcode opcode, Condition condition, CiValue opr1, CiValue opr2, CiValue result) { super(opcode, result, null, false, 0, 0, opr1, opr2); this.condition = condition; - assert opcode == LIROpcode.Cmove : "Instruction opcode should be of type LIROpcode.Cmove"; + assert opcode == LIROpcode.Cmove || opcode == LIROpcode.FCmove || opcode == LIROpcode.UFCmove : "Instruction opcode should be of type LIROpcode.Cmove"; } /** @@ -156,7 +156,7 @@ * @return condition the condition of this instruction */ public Condition condition() { - assert code == LIROpcode.Cmp || code == LIROpcode.Cmove : "Field access only valid for cmp and cmove"; + assert code == LIROpcode.Cmp || code == LIROpcode.Cmove || code == LIROpcode.FCmove || code == LIROpcode.UFCmove : "Field access only valid for cmp and cmove"; return condition; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java Fri Aug 05 17:40:35 2011 +0200 @@ -59,6 +59,8 @@ Ucmpfd2i, Cmpfd2i, Cmove, + FCmove, + UFCmove, Add, Sub, Mul, diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Fri Aug 05 17:40:35 2011 +0200 @@ -40,25 +40,38 @@ @Override protected void run(Graph graph) { - NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE); + final NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE); if (newNodes) { nodeWorkList.addAll(graph.getNewNodes()); } + NotifyReProcess reProcess = new NotifyReProcess() { + @Override + public void reProccess(Node n) { + nodeWorkList.addAgain(n); + } + }; for (Node node : nodeWorkList) { CanonicalizerOp op = node.lookup(CanonicalizerOp.class); if (op != null) { - Node canonical = op.canonical(node); + graph.mark(); + Node canonical = op.canonical(node, reProcess); if (canonical != node) { node.replaceAndDelete(canonical); - nodeWorkList.replaced(canonical, node, true, EdgeType.USAGES); - //System.out.println("-->" + n + " canonicalized to " + canonical); + nodeWorkList.replaced(canonical, node, false, EdgeType.USAGES); + for (Node newNode : graph.getNewNodes()) { + nodeWorkList.add(newNode); + } GraalMetrics.NodesCanonicalized++; } } } } + public interface NotifyReProcess { + void reProccess(Node n); + } + public interface CanonicalizerOp extends Op { - Node canonical(Node node); + Node canonical(Node node, NotifyReProcess reProcess); } } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java Fri Aug 05 17:40:35 2011 +0200 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.compiler.phases; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.ir.Phi.PhiType; +import com.oracle.max.graal.compiler.schedule.*; +import com.oracle.max.graal.compiler.value.*; +import com.oracle.max.graal.graph.*; + + +/** + * Temporary phase that converts Conditional/Materialize Nodes that can not be LIRGenered properly for now. + * Currently LIRGenerating something like + * BRANCHcc L1 // (compare, instanceof...) + * mov res, fVal + * jmp L2 + * L1: + * mov res, tVal + * L2: + * + * or + * + * mov res, tVal + * BRANCHcc L1: + * mov res, fVal + * L1: + * + * may create a few problems around register allocation: + * - in the first construct, register allocation may decide to spill an other variable to allocate res, resulting ina spilling that is done only in one branch : + * BRANCHcc L1 // (compare, instanceof...) + * mov SpillSplot, res + * mov res, fVal + * jmp L2 + * L1: + * mov res, tVal + * L2: + * + * - in the second construct the register allocator will thing that the first definition of res is not used and BRANCHcc may need some temporary register + * the allocator could then allocate the same register for res and this temporary + */ +public class ConvertConditionalPhase extends Phase { + + @Override + protected void run(Graph graph) { + IdentifyBlocksPhase schedule = null; + for (Conditional conditional : graph.getNodes(Conditional.class)) { + BooleanNode condition = conditional.condition(); + while (condition instanceof NegateBooleanNode) { + condition = ((NegateBooleanNode) condition).value(); + } + if (!(condition instanceof Compare || condition instanceof IsNonNull || condition instanceof NegateBooleanNode || condition instanceof Constant)) { + If ifNode = new If(conditional.condition(), 0.5, graph); + EndNode trueEnd = new EndNode(graph); + EndNode falseEnd = new EndNode(graph); + ifNode.setTrueSuccessor(trueEnd); + ifNode.setFalseSuccessor(falseEnd); + Merge merge = new Merge(graph); + merge.addEnd(trueEnd); + merge.addEnd(falseEnd); + Phi phi = new Phi(conditional.kind, merge, PhiType.Value, graph); + phi.addInput(conditional.trueValue()); + phi.addInput(conditional.falseValue()); + //recreate framestate + FrameState stateDuring = conditional.stateDuring(); + FrameStateBuilder builder = new FrameStateBuilder(stateDuring); + builder.push(phi.kind, phi); + merge.setStateAfter(builder.create(stateDuring.bci)); + // schedule the if... + if (schedule == null) { + schedule = new IdentifyBlocksPhase(false, false); + schedule.apply(graph); + } + schedule.assignBlockToNode(conditional); + Block block = schedule.getNodeToBlock().get(conditional); + FixedNodeWithNext prev; + Node firstNode = block.firstNode(); + if (firstNode instanceof Merge) { + prev = (Merge) firstNode; + } else if (firstNode instanceof EndNode) { + EndNode end = (EndNode) firstNode; + Node pred = end.singlePredecessor(); + Anchor anchor = new Anchor(graph); + pred.successors().replace(end, anchor); + anchor.setNext(end); + prev = anchor; + } else if (firstNode instanceof StartNode) { + StartNode start = (StartNode) firstNode; + Anchor anchor = new Anchor(graph); + anchor.setNext((FixedNode) start.next()); + start.setNext(anchor); + prev = anchor; + } else if (firstNode instanceof If) { + Node pred = firstNode.singlePredecessor(); + Anchor anchor = new Anchor(graph); + pred.successors().replace(firstNode, anchor); + anchor.setNext((If) firstNode); + prev = anchor; + } else { + prev = (FixedNodeWithNext) firstNode; + } + merge.setNext(prev.next()); + prev.setNext(ifNode); + conditional.replaceAndDelete(phi); + } else { + FrameState stateDuring = conditional.stateDuring(); + conditional.setStateDuring(null); + if (stateDuring != null && stateDuring.usages().size() == 0) { + stateDuring.delete(); + } + } + } + } +} diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Fri Aug 05 17:40:35 2011 +0200 @@ -759,7 +759,9 @@ Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type.isResolved()); Value object = frameState.apop(); if (typeInstruction != null) { - frameState.ipush(append(new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph))); + MaterializeNode materialize = new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph); + materialize.setStateDuring(frameState.create(bci())); + frameState.ipush(append(materialize)); } else { frameState.ipush(appendConstant(CiConstant.INT_0)); } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/RematerializationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/RematerializationPhase.java Mon Aug 01 18:30:25 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.text.*; -import java.util.*; - -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.graph.*; - - -public class RematerializationPhase extends Phase { - - private NodeMap nodeToBlock; - private HashMap newNodesToBlock; - private List blocks; - private UsageProbability[] probablityCache; - private boolean ignoreUsages; - - @Override - protected void run(Graph graph) { - Iterable modifiedNodes = graph.getModifiedNodes(); - graph.stopRecordModifications(); - NodeWorkList work = graph.createNodeWorkList(); - for (Node modified : modifiedNodes) { - if (modified instanceof FloatingNode) { - work.add(modified); - } - } - - if (work.isEmpty()) { - return; - } - - final IdentifyBlocksPhase s = new IdentifyBlocksPhase(true); - s.apply(graph); - - newNodesToBlock = new HashMap(); - nodeToBlock = s.getNodeToBlock(); - blocks = s.getBlocks(); - probablityCache = new UsageProbability[blocks.size()]; - - for (Node node : work) { - if (node instanceof Phi || node instanceof Local || node instanceof Constant || node instanceof LocationNode) { - continue; - } - boolean delay = false; - for (Node usage : node.usages()) { - if (usage instanceof FloatingNode && !(usage instanceof Phi) && work.isInQueue(usage)) { - delay = true; - break; - } - } - if (delay) { - work.addAgain(node); - continue; - } - Arrays.fill(probablityCache, null); - ignoreUsages = true; - Block block = nodeToBlock.get(node); - if (block == null) { - continue; - } - UsageProbability usageProbability = usageProbability(node, block); - if (usageProbability.probability < GraalOptions.MinimumUsageProbability) { - if (ignoreUsages) { - ignoreUsages = false; - Arrays.fill(probablityCache, null); - usageProbability = usageProbability(node, block); // recompute with usage maps - } - //TTY.println("going to remarterialize " + node + " at " + block + " : " + toString(usageProbability)); - boolean first = true; - for (Block sux : block.getSuccessors()) { - if (first) { - first = false; - continue; - } - usageProbability = usageProbability(node, sux); - List usages = new LinkedList(); - for (Node usage : usageProbability.usages) { - usages.add(usage); - } - if (!usages.isEmpty()) { - Node copy = node.copyWithEdges(); - newNodesToBlock.put(copy, sux); - GraalMetrics.Rematerializations++; - //TTY.println("> Rematerialized " + node + " : " + toString(usageProbability)); - for (Node usage : usages) { - usage.inputs().replace(node, copy); - if (usageProbability.phiUsages != null) { - Set phis = usageProbability.phiUsages.get(usage); - if (phis != null) { - for (Phi phi : phis) { - int index = phi.merge().phiPredecessorIndex(usage); - assert phi.valueAt(index) == node; - phi.setValueAt(index, (Value) copy); - } - } - } - } - } - } - } - } - } - - private UsageProbability usageProbability(Node n, Block b) { - UsageProbability cached = probablityCache[b.blockID()]; - if (cached != null) { - return cached; - } - if (ignoreUsages) { - GraalMetrics.PartialUsageProbability++; - } else { - GraalMetrics.FullUsageProbability++; - } - for (Node usage : n.usages()) { - if (usage instanceof Phi) { - Phi phi = (Phi) usage; - Merge merge = phi.merge(); - for (int i = 0; i < phi.valueCount(); i++) { - if (phi.valueAt(i) == n) { - insertUsageInCache(merge.phiPredecessorAt(i), phi); - } - } - } else { - insertUsageInCache(usage); - } - } - return usageProbability0(n, b); - } - - private void insertUsageInCache(Node usage) { - insertUsageInCache(usage, null); - } - - private void insertUsageInCache(Node usage, Phi phi) { - Block block = block(usage); - if (block == null) { - return; - } - int blockID = block.blockID(); - UsageProbability usageProbability = probablityCache[blockID]; - if (usageProbability == null) { - usageProbability = new UsageProbability(usage); - probablityCache[blockID] = usageProbability; - } else if (!ignoreUsages) { - usageProbability.usages.mark(usage); - } - if (phi != null) { - usageProbability.addPhiUsage(phi, usage); - } - } - - private Block block(Node node) { - Block block; - if (!nodeToBlock.isNew(node)) { - block = nodeToBlock.get(node); - } else { - block = newNodesToBlock.get(node); - assert block != null; - } - return block; - } - - private UsageProbability usageProbability0(Node n, Block b) { - //System.out.println("usageProbability0(" + n.id() + ", " + b + ")"); - UsageProbability cached = probablityCache[b.blockID()]; - if (cached != null && (cached.computed || ignoreUsages)) { - return cached; - } - UsageProbability result = cached; - if (result == null) { - result = new UsageProbability(n.graph()); - } - if (b.getSuccessors().size() > 0) { - if (b.isLoopEnd()) { - Block loopHeader = b.getSuccessors().get(0); - assert loopHeader.isLoopHeader(); - UsageProbability headerUsages = probablityCache[loopHeader.blockID()]; - if (headerUsages != null) { - result.merge(headerUsages, 1.0); - } - } else if (b.getSuccessors().size() == 1) { - result.merge(usageProbability0(n, b.getSuccessors().get(0)), 1.0); - } else { - Node lastNode = b.lastNode(); - if (lastNode instanceof Invoke) { - result.merge(usageProbability0(n, nodeToBlock.get(((Invoke) lastNode).next())), 1.0); - result.merge(usageProbability0(n, nodeToBlock.get(((Invoke) lastNode).exceptionEdge())), 0.0); - } else if (lastNode instanceof ControlSplit) { - ControlSplit split = (ControlSplit) lastNode; - for (int i = 0; i < split.blockSuccessorCount(); i++) { - result.merge(usageProbability0(n, nodeToBlock.get(split.blockSuccessor(i))), split.probability(i)); - } - } else { - throw Util.shouldNotReachHere(); - } - } - } - probablityCache[b.blockID()] = result; - result.computed = true; - return result; - } - - private class UsageProbability { - double probability; - NodeBitMap usages; - NodeMap> phiUsages; - boolean computed; - - public UsageProbability(Node usage) { - if (!ignoreUsages) { - usages = usage.graph().createNodeBitMap(); - usages.mark(usage); - } - probability = 1.0; - } - - public UsageProbability(Graph graph) { - if (!ignoreUsages) { - usages = graph.createNodeBitMap(); - } - probability = 0.0; - } - - public void merge(UsageProbability sux, double suxProbability) { - if (!ignoreUsages) { - usages.setUnion(sux.usages); - } - probability += suxProbability * sux.probability; - } - - public void addPhiUsage(Phi phi, Node usage) { - if (phiUsages == null) { - phiUsages = phi.graph().createNodeMap(); - } - Set phis = phiUsages.get(usage); - if (phis == null) { - phis = new HashSet(2); - phiUsages.set(usage, phis); - } - phis.add(phi); - } - } - - private String toString(UsageProbability up) { - NumberFormat nf = NumberFormat.getPercentInstance(); - StringBuilder sb = new StringBuilder("p="); - sb.append(nf.format(up.probability)); - if (up.usages != null) { - sb.append(" U=["); - for (Node n : up.usages) { - sb.append(n); - sb.append(", "); - } - sb.append("]"); - } - return sb.toString(); - } -} - diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Fri Aug 05 17:40:35 2011 +0200 @@ -311,7 +311,7 @@ } } - private void assignBlockToNode(Node n) { + public void assignBlockToNode(Node n) { if (n == null) { return; } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Fri Aug 05 17:40:35 2011 +0200 @@ -533,15 +533,17 @@ } else { unorderedLabel = op.unorderedBlock().label; } - masm.jcc(ConditionFlag.parity, unorderedLabel); + if (unorderedLabel != op.label() || !trueOnUnordered(op.cond())) { + masm.jcc(ConditionFlag.parity, unorderedLabel); + } // Checkstyle: off switch (op.cond()) { case EQ : acond = ConditionFlag.equal; break; case NE : acond = ConditionFlag.notEqual; break; - case LT : acond = ConditionFlag.below; break; - case LE : acond = ConditionFlag.belowEqual; break; - case GE : acond = ConditionFlag.aboveEqual; break; - case GT : acond = ConditionFlag.above; break; + case BT : acond = ConditionFlag.below; break; + case BE : acond = ConditionFlag.belowEqual; break; + case AE : acond = ConditionFlag.aboveEqual; break; + case AT : acond = ConditionFlag.above; break; default : throw Util.shouldNotReachHere(); } } else { @@ -710,7 +712,8 @@ } @Override - protected void emitConditionalMove(Condition condition, CiValue opr1, CiValue opr2, CiValue result) { + protected void emitConditionalMove(Condition condition, CiValue opr1, CiValue opr2, CiValue result, boolean mayBeUnordered, boolean unorderedcmovOpr1) { + //TTY.println("cmov " + condition + " " + opr1 + " : " + opr2 + " mayBeUnordered:" + mayBeUnordered + " pcmovop=" + (unorderedcmovOpr1 ? 1 : 2)); ConditionFlag acond; ConditionFlag ncond; switch (condition) { @@ -774,13 +777,17 @@ def = opr2; other = opr1; // and flip the condition + condition = condition.negate(); ConditionFlag tcond = acond; acond = ncond; ncond = tcond; + unorderedcmovOpr1 = !unorderedcmovOpr1; } if (def.isRegister()) { - reg2reg(def, result); + if (def.asRegister() != result.asRegister()) { + reg2reg(def, result); + } } else if (def.isStackSlot()) { stack2reg(def, result, result.kind); } else { @@ -788,30 +795,24 @@ const2reg(def, result, null); } - if (!other.isConstant()) { + boolean cmovOnParity = (unorderedcmovOpr1 && mayBeTrueOnUnordered(condition.negate())) || (!unorderedcmovOpr1 && mayBeFalseOnUnordered(condition.negate())); + if (!other.isConstant() && !(cmovOnParity && def.isConstant())) { // optimized version that does not require a branch - TTY.println("> emitting cmov"); - if (other.isRegister()) { - assert other.asRegister() != result.asRegister() : "other already overwritten by previous move"; - if (other.kind.isInt()) { - masm.cmovl(ncond, result.asRegister(), other.asRegister()); - } else { - masm.cmovq(ncond, result.asRegister(), other.asRegister()); - } - } else { - assert other.isStackSlot(); - CiStackSlot otherSlot = (CiStackSlot) other; - if (other.kind.isInt()) { - masm.cmovl(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); - } else { - masm.cmovq(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); - } + //TTY.println("> emitting cmov" + (mayBeUnordered && cmovOnParity ? " (with parity check)" : "")); + cmov(result, ncond, other); + if (mayBeUnordered && cmovOnParity) { + cmov(result, ConditionFlag.parity, unorderedcmovOpr1 ? def : other); } - } else { + //TTY.println("> emitting jumps instead of cmov"); // conditional move not available, use emit a branch and move Label skip = new Label(); + Label mov = new Label(); + if (mayBeUnordered && ((mayBeTrueOnUnordered(condition) && !unorderedcmovOpr1) || (mayBeFalseOnUnordered(condition) && unorderedcmovOpr1))) { + masm.jcc(ConditionFlag.parity, unorderedcmovOpr1 ? skip : mov); + } masm.jcc(acond, skip); + masm.bind(mov); if (other.isRegister()) { reg2reg(other, result); } else if (other.isStackSlot()) { @@ -824,6 +825,25 @@ } } + private void cmov(CiValue result, ConditionFlag ncond, CiValue other) { + if (other.isRegister()) { + assert other.asRegister() != result.asRegister() : "other already overwritten by previous move"; + if (other.kind.isInt()) { + masm.cmovl(ncond, result.asRegister(), other.asRegister()); + } else { + masm.cmovq(ncond, result.asRegister(), other.asRegister()); + } + } else { + assert other.isStackSlot(); + CiStackSlot otherSlot = (CiStackSlot) other; + if (other.kind.isInt()) { + masm.cmovl(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); + } else { + masm.cmovq(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot)); + } + } + } + @Override protected void emitArithOp(LIROpcode code, CiValue left, CiValue right, CiValue dest, LIRDebugInfo info) { assert info == null : "should never be used : idiv/irem and ldiv/lrem not handled by this method"; @@ -1273,8 +1293,8 @@ case Double : masm.ucomisd(reg1, tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) opr2).asDouble()))); break; case Long : case Word : { - if (c.asLong() == 0) { - masm.cmpq(reg1, 0); + if (NumUtil.isInt(c.asLong())) { + masm.cmpq(reg1, (int) c.asLong()); } else { masm.movq(rscratch1, c.asLong()); masm.cmpq(reg1, rscratch1); @@ -1304,10 +1324,21 @@ case Short : case Int : masm.cmpl(left, right.asInt()); break; case Long : - case Word : assert NumUtil.isInt(right.asLong()); - masm.cmpq(left, right.asInt()); break; - case Object : assert right.isNull(); - masm.cmpq(left, 0); break; + case Word : if (NumUtil.isInt(right.asLong())) { + masm.cmpq(left, (int) right.asLong()); + } else { + masm.movq(rscratch1, right.asLong()); + masm.cmpq(left, rscratch1); + + } + break; + case Object : if (right.isNull()) { + masm.cmpq(left, 0); + } else { + movoop(rscratch1, right); + masm.cmpq(left, rscratch1); + } + break; default : throw Util.shouldNotReachHere(); } } else { @@ -2238,6 +2269,51 @@ tasm.recordExceptionHandlers(after, info); } + @Override + public boolean falseOnUnordered(Condition condition) { + switch(condition) { + case AE: + case NE: + case GT: + case AT: + return true; + case EQ: + case LE: + case BE: + case BT: + case LT: + case GE: + case OF: + case NOF: + return false; + default: + throw Util.shouldNotReachHere(); + } + } + + @Override + public boolean trueOnUnordered(Condition condition) { + switch(condition) { + case AE: + case NE: + case GT: + case AT: + return false; + case EQ: + case LE: + case BE: + case BT: + return true; + case LT: + case GE: + case OF: + case NOF: + return false; + default: + throw Util.shouldNotReachHere(); + } + } + protected void stop(String msg) { if (GraalOptions.GenAssertionCode) { // TODO: pass a pointer to the message diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Fri Aug 05 17:40:35 2011 +0200 @@ -408,7 +408,7 @@ } @Override - public void visitMaterialize(NormalizeCompare x) { + public void visitNormalizeCompare(NormalizeCompare x) { LIRItem left = new LIRItem(x.x(), this); LIRItem right = new LIRItem(x.y(), this); if (!x.kind.isVoid() && x.x().kind.isLong()) { @@ -463,4 +463,20 @@ public void visitValueAnchor(ValueAnchor valueAnchor) { // nothing to do for ValueAnchors } + + @Override + public Condition floatingPointCondition(Condition cond) { + switch(cond) { + case LT: + return Condition.BT; + case LE: + return Condition.BE; + case GT: + return Condition.AT; + case GE: + return Condition.AE; + default : + return cond; + } + } } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java Fri Aug 05 17:40:35 2011 +0200 @@ -86,15 +86,12 @@ } private static Collection colorCFGDownToMerge(Node from, T color, NodeMap colors) { - //System.out.println("colorCFGDownToMerge(" + from + ", " + color + ", colors)"); NodeFlood work = from.graph().createNodeFlood(); Collection merges = new LinkedList(); work.add(from); for (Node node : work) { - //System.out.println("colorToMerge : work on " + node); Node current = node; while (current != null) { - //System.out.println("colorToMerge : current " + current); if (current instanceof Merge) { merges.add((Merge) current); break; @@ -123,7 +120,6 @@ } } } - //System.out.println("return " + merges); return merges; } @@ -149,7 +145,6 @@ Set colors = new HashSet(); try { for (Node node : work) { - //System.out.println("Split : work on " + node); if (node instanceof Phi) { Phi phi = (Phi) node; Merge merge = phi.merge(); @@ -163,7 +158,6 @@ phi.setValueAt(i, replace); } else { if (lambda.explore(v) && coloring.get(v) == null && !work.isNew(v)) { - //System.out.println("Split : Add input " + input + " to work from " + node); work.add(v); } } @@ -175,7 +169,6 @@ colors.clear(); T originalColoringColor = coloring.get(node); if (originalColoringColor == null && internalColoring.get(node) != null) { - //System.out.println("Split : ori == null && intern != null -> continue"); continue; } if (originalColoringColor == null) { @@ -183,7 +176,6 @@ if (usage instanceof Phi) { Phi phi = (Phi) usage; Merge merge = phi.merge(); - //System.out.println("Split merge : " + merge + ".endCount = " + merge.endCount() + " phi " + phi + ".valueCount : " + phi.valueCount()); for (int i = 0; i < phi.valueCount(); i++) { Value v = phi.valueAt(i); if (v == node) { @@ -196,7 +188,6 @@ } else { T color = internalColoring.get(usage); if (color == null) { - //System.out.println("Split : color from " + usage + " is null : " + (lambda.explore(usage) ? "Should be colored" : "Should be white")); if (lambda.explore(usage)) { delay = true; break; @@ -207,7 +198,6 @@ } } if (delay) { - //System.out.println("Split : delay"); work.addAgain(node); continue; } @@ -215,7 +205,6 @@ colors.add(originalColoringColor); } if (colors.size() == 1) { - //System.out.println("Split : 1 color, coloring, fixing"); T color = colors.iterator().next(); internalColoring.put(node, color); lambda.fixNode(node, color); @@ -288,7 +277,6 @@ if (node instanceof StateSplit) { FrameState stateAfter = ((StateSplit) node).stateAfter(); if (stateAfter != null && lambda.explore(stateAfter) && !work.isNew(stateAfter)) { - //System.out.println("Split : Add framestate to work"); if (!(node instanceof Merge && coloring.get(((Merge) node).next()) == null)) { // not dangling colored merge work.add(stateAfter); } @@ -309,7 +297,6 @@ for (Node input : node.dataInputs()) { if (lambda.explore(input) && coloring.get(input) == null && !work.isNew(input)) { - //System.out.println("Split : Add input " + input + " to work from " + node); work.add(input); } } diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java Fri Aug 05 17:40:35 2011 +0200 @@ -276,32 +276,13 @@ LoopEnd loopEnd = loop.loopBegin().loopEnd(); PeelingResult peeling = preparePeeling(loop, loopEnd); GraalCompilation compilation = GraalCompilation.compilation(); + if (compilation.compiler.isObserved()) { compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After peeling preparation", loopEnd.graph(), true, false)); } - /*System.out.println("Peeling : "); - System.out.println(" begin = " + peeling.begin); - System.out.println(" end = " + peeling.end); - System.out.println(" Phis :"); - for (Entry entry : peeling.phis.entries()) { - System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); - } - System.out.println(" Exits :"); - for (Entry entry : peeling.exits.entries()) { - System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); - } - System.out.println(" PhiInits :"); - for (Entry entry : peeling.phiInits.entries()) { - System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); - } - System.out.println(" DataOut :"); - for (Entry entry : peeling.dataOut.entries()) { - System.out.println(" - " + entry.getKey() + " -> " + entry.getValue()); - }*/ + rewirePeeling(peeling, loop); - /*if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false)); - }*/ + loop.invalidateCached(); // update parents Loop parent = loop.parent(); @@ -355,7 +336,6 @@ for (Entry dataEntry : peeling.dataOut.entries()) { if (dataEntry.getValue() == p) { dataEntry.setValue(init); - //System.out.println("Patch dataOut : " + dataEntry.getKey() + " -> " + dataEntry.getValue()); } } } @@ -484,14 +464,6 @@ colors.set(exitPoint, exitPoint); } - /*System.out.println("newExitValues"); - for (Entry> entry : newExitValues.entries()) { - System.out.println(" - " + entry.getKey() + " :"); - for (Entry entry2 : entry.getValue().entries()) { - System.out.println(" + " + entry2.getKey() + " -> " + entry2.getValue()); - } - }*/ - // color GraphUtil.colorCFGDown(colors, new ColoringLambda() { @Override @@ -548,7 +520,6 @@ private Value getValueAt(Node point, NodeMap valueMap, CiKind kind) { Value value = valueMap.get(point); if (value != null) { - //System.out.println("getValueAt(" + point + ", valueMap, kind) = (cached) " + value); return value; } Merge merge = (Merge) point; @@ -570,24 +541,16 @@ for (EndNode end : merge.cfgPredecessors()) { phi.addInput(getValueAt(colors.get(end), valueMap, kind)); } - //System.out.println("getValueAt(" + point + ", valueMap, kind) = (new-phi) " + phi); return phi; } else { assert v != null; valueMap.set(point, v); - //System.out.println("getValueAt(" + point + ", valueMap, kind) = (unique) " + v); return v; } } @Override public boolean explore(Node n) { - /*System.out.println("Explore " + n + "?"); - System.out.println(" - exitFS : " + (!exitFrameStates.isNew(n) && exitFrameStates.isMarked(n))); - System.out.println(" - !inOrBefore : " + (!inOrBefore.isNew(n) && !inOrBefore.isMarked(n))); - System.out.println(" - inputs > 0 : " + (n.inputs().size() > 0)); - System.out.println(" - !danglingMergeFrameState : " + (!danglingMergeFrameState(n)));*/ - return exitFrameStates.isNotNewMarked(n) - || (inOrBefore.isNotNewNotMarked(n) && n.inputs().size() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum + return exitFrameStates.isNotNewMarked(n) || (inOrBefore.isNotNewNotMarked(n) && n.inputs().size() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum } public boolean afterColoringFramestate(Node n) { if (!(n instanceof FrameState)) { @@ -611,7 +574,6 @@ } @Override public void fixNode(Node node, Node color) { - //System.out.println("fixNode(" + node + ", " + color + ")"); if (color == null) { // 'white' it out : make non-explorable if (!exitFrameStates.isNew(node)) { @@ -660,22 +622,12 @@ return (Merge) color; } }); - - /*if (compilation.compiler.isObserved()) { - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After split from colors", graph, true, false)); - }*/ } private static PeelingResult preparePeeling(Loop loop, FixedNode from) { LoopBegin loopBegin = loop.loopBegin(); Graph graph = loopBegin.graph(); NodeBitMap marked = computeLoopNodesFrom(loop, from); - GraalCompilation compilation = GraalCompilation.compilation(); - /*if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("marked", marked); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After computeLoopNodesFrom", loopBegin.graph(), true, false, debug)); - }*/ if (from == loopBegin.loopEnd()) { clearWithState(from, marked); } @@ -728,20 +680,8 @@ } } - //GraalCompilation compilation = GraalCompilation.compilation(); - if (compilation.compiler.isObserved()) { - Map debug = new HashMap(); - debug.put("marked", marked); - compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Before addDuplicate loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug)); - } - Map duplicates = graph.addDuplicate(marked, replacements); - /*System.out.println("Dup mapping :"); - for (Entry entry : duplicates.entrySet()) { - System.out.println(" - " + entry.getKey().id() + " -> " + entry.getValue().id()); - }*/ - NodeMap dataOutMapping = graph.createNodeMap(); for (Node n : dataOut) { Node newOut = duplicates.get(n); @@ -809,7 +749,6 @@ NodeFlood work = graph.createNodeFlood(); work.addAll(cfgNodes); for (Node n : work) { - //inOrAfter.mark(n); markWithState(n, inOrAfter); if (full) { for (Node sux : n.successors()) { diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Fri Aug 05 17:40:35 2011 +0200 @@ -47,6 +47,16 @@ private final RiMethod method; + public FrameStateBuilder(FrameState fs) { + this.method = fs.method; + this.graph = fs.graph(); + this.locals = new Value[method.maxLocals()]; + int stackSize = Math.max(1, method.maxStackSize()); + this.stack = new Value[stackSize]; + this.locks = new ArrayList(); + this.initializeFrom(fs); + } + public FrameStateBuilder(RiMethod method, Graph graph) { assert graph != null; this.method = method; diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Fri Aug 05 17:40:35 2011 +0200 @@ -478,7 +478,7 @@ graph.setReturn(ret); return graph; } - } else if (holderName.equals("Ljava/lang/Float;")) { + } else if (holderName.equals("Ljava/lang/Float;")) { //XXX (gd) the non-raw versions of (F/D)2(I/L) should return a sanitized NaN in the NaN case. also check NaN case for (I/L)2(F/D) if (fullName.equals("floatToRawIntBits(F)I") || fullName.equals("floatToIntBits(F)I")) { CompilerGraph graph = new CompilerGraph(this); Return ret = new Return(new FPConversionNode(CiKind.Int, new Local(CiKind.Float, 0, graph), graph), graph); diff -r a64b615ba630 -r ce7cf6d16b38 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java Mon Aug 01 18:30:25 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java Fri Aug 05 17:40:35 2011 +0200 @@ -24,7 +24,9 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.gen.LIRGenerator.LIRGeneratorOp; import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -40,9 +42,6 @@ return super.inputCount() + INPUT_COUNT; } - /** - * The instruction that produces the object tested against null. - */ public Value value() { return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); } @@ -60,17 +59,11 @@ @SuppressWarnings("unchecked") @Override public T lookup(Class clazz) { - if (clazz == LIRGenerator.LIRGeneratorOp.class) { - return (T) new LIRGenerator.LIRGeneratorOp() { - @Override - public void generate(Node n, LIRGenerator generator) { - FPConversionNode conv = (FPConversionNode) n; - CiValue reg = generator.createResultVariable(conv); - CiValue value = generator.load(conv.value()); - CiValue tmp = generator.forceToSpill(value, conv.kind, false); - generator.lir().move(tmp, reg); - } - }; + if (clazz == LIRGeneratorOp.class) { + return (T) LIRGEN; + } + if (clazz == CanonicalizerOp.class) { + return (T) CANON; } return super.lookup(clazz); } @@ -89,4 +82,37 @@ public Node copy(Graph into) { return new FPConversionNode(kind, null, into); } + + private static final CanonicalizerOp CANON = new CanonicalizerOp() { + @Override + public Node canonical(Node node, NotifyReProcess reProcess) { + FPConversionNode conv = (FPConversionNode) node; + Value value = conv.value(); + if (value instanceof Constant) { + CiKind toKind = conv.kind; + CiKind fromKind = value.kind; + if (toKind == CiKind.Int && fromKind == CiKind.Float) { + return Constant.forInt(Float.floatToRawIntBits(((Constant) value).asConstant().asFloat()), node.graph()); + } else if (toKind == CiKind.Long && fromKind == CiKind.Double) { + return Constant.forLong(Double.doubleToRawLongBits(((Constant) value).asConstant().asDouble()), node.graph()); + } else if (toKind == CiKind.Float && fromKind == CiKind.Int) { + return Constant.forFloat(Float.intBitsToFloat(((Constant) value).asConstant().asInt()), node.graph()); + } else if (toKind == CiKind.Double && fromKind == CiKind.Long) { + return Constant.forDouble(Double.longBitsToDouble(((Constant) value).asConstant().asLong()), node.graph()); + } + } + return conv; + } + }; + + private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() { + @Override + public void generate(Node n, LIRGenerator generator) { + FPConversionNode conv = (FPConversionNode) n; + CiValue reg = generator.createResultVariable(conv); + CiValue value = generator.load(conv.value()); + CiValue tmp = generator.forceToSpill(value, conv.kind, false); + generator.lir().move(tmp, reg); + } + }; }