# HG changeset patch # User Gilles Duboscq # Date 1312909169 -7200 # Node ID 65c865bba4c2126acba23f9d97406d9b8cc41a73 # Parent 82266dbf5a5a8769f4a111255c6268e4b7c1ca09# Parent 3e21ab23406b4fa708d8b8ec7e6782b9bc232f78 Merge diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,74 +22,54 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "&") -public final class And extends Logic { - private static final AndCanonicalizerOp CANONICALIZER = new AndCanonicalizerOp(); +public final class And extends Logic implements Canonicalizable { public And(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IAND : Bytecodes.LAND, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x() == y()) { + return x(); } - return super.lookup(clazz); - } - - private static class AndCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - assert node instanceof And; - And and = (And) node; - CiKind kind = and.kind; - Graph graph = and.graph(); - Value x = and.x(); - Value y = and.y(); - if (x == y) { - return x; + if (x().isConstant() && !y().isConstant()) { + swapOperands(); + } + if (x().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph()); } - if (x.isConstant() && !y.isConstant()) { - and.swapOperands(); - Value t = y; - y = x; - x = t; - } - if (x.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() & y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() & y.asConstant().asLong(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Int) { + int c = y().asConstant().asInt(); + if (c == -1) { + return x(); + } + if (c == 0) { + return Constant.forInt(0, graph()); } - } else if (y.isConstant()) { - if (kind == CiKind.Int) { - int c = y.asConstant().asInt(); - if (c == -1) { - return x; - } - if (c == 0) { - return Constant.forInt(0, graph); - } - } else { - assert kind == CiKind.Long; - long c = y.asConstant().asLong(); - if (c == -1) { - return x; - } - if (c == 0) { - return Constant.forLong(0, graph); - } + } else { + assert kind == CiKind.Long; + long c = y().asConstant().asLong(); + if (c == -1) { + return x(); + } + if (c == 0) { + return Constant.forLong(0, graph()); } } - return and; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Tue Aug 09 18:59:29 2011 +0200 @@ -33,8 +33,7 @@ /** * The {@code ArrayLength} instruction gets the length of an array. */ -public final class ArrayLength extends FloatingNode { - private static final ArrayLengthCanonicalizerOp CANONICALIZER = new ArrayLengthCanonicalizerOp(); +public final class ArrayLength extends FloatingNode implements Canonicalizable { @Input private Value array; @@ -49,6 +48,7 @@ /** * Constructs a new ArrayLength instruction. + * * @param array the instruction producing the array * @param newFrameState the state after executing this instruction */ @@ -67,40 +67,23 @@ out.print(array()).print(".length"); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (array() instanceof NewArray) { + Value length = ((NewArray) array()).dimension(0); + assert length != null; + return length; } - return super.lookup(clazz); - } - - private static class ArrayLengthCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - ArrayLength arrayLength = (ArrayLength) node; - Value array = arrayLength.array(); - if (array instanceof NewArray) { - Value length = ((NewArray) array).length(); - if (array instanceof NewMultiArray) { - length = ((NewMultiArray) array).dimension(0); - } - assert length != null; - return length; - } - CiConstant constantValue = null; - if (array.isConstant()) { - constantValue = array.asConstant(); - } + CiConstant constantValue = null; + if (array().isConstant()) { + constantValue = array().asConstant(); if (constantValue != null && constantValue.isNonNull()) { - Graph graph = node.graph(); - if (graph instanceof CompilerGraph) { - RiRuntime runtime = ((CompilerGraph) graph).runtime(); - return Constant.forInt(runtime.getArrayLength(constantValue), graph); + if (graph() instanceof CompilerGraph) { + RiRuntime runtime = ((CompilerGraph) graph()).runtime(); + return Constant.forInt(runtime.getArrayLength(constantValue), graph()); } } - return arrayLength; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,6 +23,7 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.ir.Phi.PhiType; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.compiler.phases.LoweringPhase.*; import com.oracle.max.graal.graph.*; @@ -33,7 +34,7 @@ * LinearInductionVariable that is computed in the loops thanks to Phi(init, this + stride). * This will keep at least one register busy in the whole loop body */ -public class BasicInductionVariable extends LinearInductionVariable { +public class BasicInductionVariable extends LinearInductionVariable implements Canonicalizable{ public static final BIVLoweringOp LOWERING = new BIVLoweringOp(); @Input private LoopCounter loopCounter; @@ -87,15 +88,21 @@ return newDIV; } + @Override + public Node canonical(NotifyReProcess reProcess) { + if (this.init().isConstant() && this.init().asConstant().asLong() == 0 + && this.stride().isConstant() && this.stride().asConstant().asLong() == 1) { + return this.loopCounter(); + } + return this; + } + @SuppressWarnings("unchecked") @Override public T lookup(Class clazz) { if (clazz == LoweringOp.class) { return (T) LOWERING; } - if (clazz == CanonicalizerOp.class) { - return (T) CANON; - } return super.lookup(clazz); } @@ -115,16 +122,4 @@ return phi; } } - - private static CanonicalizerOp CANON = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - BasicInductionVariable biv = (BasicInductionVariable) node; - if (biv.init().isConstant() && biv.init().asConstant().asLong() == 0 - && biv.stride().isConstant() && biv.stride().asConstant().asLong() == 1) { - return biv.loopCounter(); - } - return biv; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,7 +23,7 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; @@ -33,10 +33,11 @@ /** * The {@code CheckCast} instruction represents a {@link Bytecodes#CHECKCAST}. */ -public final class CheckCast extends TypeCheck { +public final class CheckCast extends TypeCheck implements Canonicalizable { /** * Creates a new CheckCast instruction. + * * @param targetClass the class being cast to * @param object the instruction producing the object * @param graph @@ -47,6 +48,7 @@ /** * Gets the declared type of the result of this instruction. + * * @return the declared type of the result */ @Override @@ -56,6 +58,7 @@ /** * Gets the exact type of the result of this instruction. + * * @return the exact type of the result */ @Override @@ -70,34 +73,24 @@ @Override public void print(LogStream out) { - out.print("checkcast("). - print(object()). - print(","). - print(targetClassInstruction()). - print(") "). - print(CiUtil.toJavaName(targetClass())); + out.print("checkcast(").print(object()).print(",").print(targetClassInstruction()).print(") ").print(CiUtil.toJavaName(targetClass())); } - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - CheckCast checkCast = (CheckCast) node; - Value object = checkCast.object(); - RiType exactType = object.exactType(); - if (exactType != null) { - return Constant.forBoolean(exactType.isSubtypeOf(checkCast.targetClass()), node.graph()); + @Override + public Node canonical(NotifyReProcess reProcess) { + if (object().exactType() != null) { + return object(); + } + CiConstant constant = object().asConstant(); + if (constant != null) { + assert constant.kind == CiKind.Object; + if (constant.isNull()) { + return object(); + } else { + // this should never happen - non-null constants are always expected to provide an exactType + assert false; } - CiConstant constant = object.asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - if (constant.isNull()) { - return Constant.forBoolean(true, node.graph()); - } else { - // this should never happen - non-null constants are always expected to provide an exactType - assert false; - } - } - return checkCast; } - }; + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Tue Aug 09 18:59:29 2011 +0200 @@ -27,6 +27,7 @@ import com.oracle.max.graal.compiler.*; 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.*; @@ -39,7 +40,8 @@ * into variants that do not materialize the value (CompareIf, CompareGuard...) * */ -public final class Compare extends BooleanNode { +public final class Compare extends BooleanNode implements Canonicalizable { + @Input private Value x; @Input private Value y; @@ -66,6 +68,7 @@ /** * Constructs a new Compare instruction. + * * @param x the instruction producing the first input to the instruction * @param condition the condition (comparison operation) * @param y the instruction that produces the second input to this instruction @@ -81,6 +84,7 @@ /** * Gets the condition (comparison operation) for this instruction. + * * @return the condition */ public Condition condition() { @@ -89,19 +93,20 @@ /** * Checks whether unordered inputs mean true or false. + * * @return {@code true} if unordered inputs produce true */ public boolean unorderedIsTrue() { return unorderedIsTrue; } - public void setUnorderedIsTrue(boolean unorderedIsTrue) { this.unorderedIsTrue = unorderedIsTrue; } /** * Swaps the operands to this if and mirrors the condition (e.g. > becomes <). + * * @see Condition#mirror() */ public void swapOperands() { @@ -122,12 +127,7 @@ @Override public void print(LogStream out) { - out.print("comp "). - print(x()). - print(' '). - print(condition().operator). - print(' '). - print(y()); + out.print("comp ").print(x()).print(' ').print(condition().operator).print(' ').print(y()); } @Override @@ -135,15 +135,6 @@ return "Comp " + condition.operator; } - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - @Override public Map getDebugProperties() { Map properties = super.getDebugProperties(); @@ -151,107 +142,104 @@ return properties; } - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - Compare compare = (Compare) node; - if (compare.x().isConstant() && !compare.y().isConstant()) { // move constants to the left (y) - 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(), compare.unorderedIsTrue()); - if (result != null) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("folded condition " + constX + " " + compare.condition() + " " + constY); - } - return Constant.forBoolean(result, compare.graph()); - } else { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind); - } - } - } - - if (compare.y().isConstant()) { - if (compare.x() instanceof MaterializeNode) { - return optimizeMaterialize(compare, compare.y().asConstant(), (MaterializeNode) compare.x()); - } else if (compare.x() instanceof NormalizeCompare) { - return optimizeNormalizeCmp(compare, compare.y().asConstant(), (NormalizeCompare) compare.x()); - } - } - - if (compare.x() == compare.y() && compare.x().kind != CiKind.Float && compare.x().kind != CiKind.Double) { - return Constant.forBoolean(compare.condition().check(1, 1), compare.graph()); - } - if ((compare.condition == Condition.NE || compare.condition == Condition.EQ) && compare.x().kind == CiKind.Object) { - Value object = null; - if (compare.x().isNullConstant()) { - object = compare.y(); - } else if (compare.y().isNullConstant()) { - object = compare.x(); - } - if (object != null) { - IsNonNull nonNull = new IsNonNull(object, compare.graph()); - if (compare.condition == Condition.NE) { - return nonNull; - } else { - assert compare.condition == Condition.EQ; - return new NegateBooleanNode(nonNull, compare.graph()); - } + private Node optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode) { + if (constant.kind == CiKind.Int) { + boolean isFalseCheck = (constant.asInt() == 0); + if (condition == Condition.EQ || condition == Condition.NE) { + if (condition == Condition.NE) { + isFalseCheck = !isFalseCheck; } - } - boolean allUsagesNegate = true; - for (Node usage : compare.usages()) { - if (!(usage instanceof NegateBooleanNode)) { - allUsagesNegate = false; - break; - } - } - if (allUsagesNegate) { - compare.negate(); - for (Node usage : compare.usages().snapshot()) { - usage.replaceAtUsages(compare); + BooleanNode result = materializeNode.condition(); + if (isFalseCheck) { + result = new NegateBooleanNode(result, graph()); } - } - return compare; - } - - private Node optimizeMaterialize(Compare compare, CiConstant constant, MaterializeNode materializeNode) { - if (constant.kind == CiKind.Int) { - boolean isFalseCheck = (constant.asInt() == 0); - if (compare.condition == Condition.EQ || compare.condition == Condition.NE) { - if (compare.condition == Condition.NE) { - isFalseCheck = !isFalseCheck; - } - BooleanNode result = materializeNode.condition(); - if (isFalseCheck) { - result = new NegateBooleanNode(result, compare.graph()); - } - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Removed materialize replacing with " + result); - } - return result; - } - } - return compare; - } - - private Node optimizeNormalizeCmp(Compare compare, CiConstant constant, NormalizeCompare normalizeNode) { - if (constant.kind == CiKind.Int && constant.asInt() == 0) { - Condition condition = compare.condition(); - if (normalizeNode == compare.y()) { - condition = condition.mirror(); - } - Compare result = new Compare(normalizeNode.x(), condition, normalizeNode.y(), compare.graph()); - boolean isLess = condition == Condition.LE || condition == Condition.LT || condition == Condition.BE || condition == Condition.BT; - result.unorderedIsTrue = condition != Condition.EQ && (condition == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess())); if (GraalOptions.TraceCanonicalizer) { - TTY.println("Replaced Compare+NormalizeCompare with " + result); + TTY.println("Removed materialize replacing with " + result); } return result; } - return compare; + } + return this; + } + + private Node optimizeNormalizeCmp(CiConstant constant, NormalizeCompare normalizeNode) { + if (constant.kind == CiKind.Int && constant.asInt() == 0) { + Condition condition = condition(); + if (normalizeNode == y()) { + condition = condition.mirror(); + } + Compare result = new Compare(normalizeNode.x(), condition, normalizeNode.y(), graph()); + boolean isLess = condition == Condition.LE || condition == Condition.LT || condition == Condition.BE || condition == Condition.BT; + result.unorderedIsTrue = condition != Condition.EQ && (condition == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess())); + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Replaced Compare+NormalizeCompare with " + result); + } + return result; + } + return this; + } + + @Override + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && !y().isConstant()) { // move constants to the left (y) + swapOperands(); + } else if (x().isConstant() && y().isConstant()) { + CiConstant constX = x().asConstant(); + CiConstant constY = y().asConstant(); + Boolean result = condition().foldCondition(constX, constY, ((CompilerGraph) graph()).runtime(), unorderedIsTrue()); + if (result != null) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("folded condition " + constX + " " + condition() + " " + constY); + } + return Constant.forBoolean(result, graph()); + } else { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("if not removed %s %s %s (%s %s)", constX, condition(), constY, constX.kind, constY.kind); + } + } } - }; + + if (y().isConstant()) { + if (x() instanceof MaterializeNode) { + return optimizeMaterialize(y().asConstant(), (MaterializeNode) x()); + } else if (x() instanceof NormalizeCompare) { + return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompare) x()); + } + } + + if (x() == y() && x().kind != CiKind.Float && x().kind != CiKind.Double) { + return Constant.forBoolean(condition().check(1, 1), graph()); + } + if ((condition == Condition.NE || condition == Condition.EQ) && x().kind == CiKind.Object) { + Value object = null; + if (x().isNullConstant()) { + object = y(); + } else if (y().isNullConstant()) { + object = x(); + } + if (object != null) { + IsNonNull nonNull = new IsNonNull(object, graph()); + if (condition == Condition.NE) { + return nonNull; + } else { + assert condition == Condition.EQ; + return new NegateBooleanNode(nonNull, graph()); + } + } + } + boolean allUsagesNegate = true; + for (Node usage : usages()) { + if (!(usage instanceof NegateBooleanNode)) { + allUsagesNegate = false; + break; + } + } + if (allUsagesNegate) { + negate(); + for (Node usage : usages().snapshot()) { + usage.replaceAtUsages(this); + } + } + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java Tue Aug 09 18:59:29 2011 +0200 @@ -26,8 +26,8 @@ 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.Phi.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.ir.Phi.PhiType; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; @@ -35,11 +35,11 @@ import com.sun.cri.ci.*; /** - * The {@code Conditional} class represents a comparison that yields one of two values. - * Note that these nodes are not built directly from the bytecode but are introduced - * by conditional expression elimination. + * The {@code Conditional} class represents a comparison that yields one of two values. Note that these nodes are not + * built directly from the bytecode but are introduced by conditional expression elimination. */ -public class Conditional extends Binary { +public class Conditional extends Binary implements Canonicalizable { + @Input private BooleanNode condition; public BooleanNode condition() { @@ -53,6 +53,7 @@ /** * Constructs a new IfOp. + * * @param x the instruction producing the first value to be compared * @param condition the condition of the comparison * @param y the instruction producing the second value to be compared @@ -88,23 +89,12 @@ @Override public void print(LogStream out) { - out.print(x()). - print(' '). - print(condition()). - print(' '). - print(y()). - print(" ? "). - print(trueValue()). - print(" : "). - print(falseValue()); + out.print(x()).print(' ').print(condition()).print(' ').print(y()).print(" ? ").print(trueValue()).print(" : ").print(falseValue()); } @SuppressWarnings("unchecked") @Override public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } if (clazz == LIRGeneratorOp.class) { return (T) LIRGEN; } @@ -112,9 +102,11 @@ } public static class ConditionalStructure { + public final If ifNode; public final Phi phi; public final Merge merge; + public ConditionalStructure(If ifNode, Phi phi, Merge merge) { this.ifNode = ifNode; this.phi = phi; @@ -143,50 +135,6 @@ return new ConditionalStructure(ifNode, phi, merge); } - private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - Conditional conditional = (Conditional) node; - BooleanNode condition = conditional.condition(); - Value trueValue = conditional.trueValue(); - Value falseValue = conditional.falseValue(); - if (condition instanceof Constant) { - Constant c = (Constant) condition; - if (c.asConstant().asBoolean()) { - return trueValue; - } else { - return falseValue; - } - } - if (trueValue == falseValue) { - return trueValue; - } - 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) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("> Conditional canon'ed to ~Materialize"); - } - reProcess.reProccess(condition); // because we negate it - return new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph()); - } else if (trueInt == 1 && falseInt == 0) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("> Conditional canon'ed to Materialize"); - } - return new MaterializeNode(condition, node.graph()); - } - } 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; - } - }; - private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() { @Override @@ -258,4 +206,42 @@ } } }; + + @Override + public Node canonical(NotifyReProcess reProcess) { + if (condition instanceof Constant) { + Constant c = (Constant) condition; + if (c.asConstant().asBoolean()) { + return trueValue(); + } else { + return falseValue(); + } + } + if (trueValue() == falseValue()) { + return trueValue(); + } + if (!(this 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) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Conditional canon'ed to ~Materialize"); + } + reProcess.reProccess(condition); // because we negate it + return new MaterializeNode(new NegateBooleanNode(condition, graph()), graph()); + } else if (trueInt == 1 && falseInt == 0) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Conditional canon'ed to Materialize"); + } + return new MaterializeNode(condition, graph()); + } + } else if (falseValue() instanceof Constant && !(trueValue() instanceof Constant)) { + Value temp = trueValue(); + setTrueValue(falseValue()); + setFalseValue(temp); + condition = new NegateBooleanNode(condition, graph()); + setCondition(condition); + } + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java Tue Aug 09 18:59:29 2011 +0200 @@ -25,13 +25,13 @@ import com.oracle.max.graal.compiler.*; 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.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; +public final class FixedGuard extends FixedNodeWithNext implements Canonicalizable { -public final class FixedGuard extends FixedNodeWithNext { @Input private final NodeInputList conditions = new NodeInputList(this); public FixedGuard(BooleanNode node, Graph graph) { @@ -57,40 +57,28 @@ conditions.add(x); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FixedGuard fixedGuard = (FixedGuard) node; - for (BooleanNode n : fixedGuard.conditions.snapshot()) { - if (n instanceof Constant) { - Constant c = (Constant) n; - if (c.asConstant().asBoolean()) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Removing redundant fixed guard " + fixedGuard); - } - fixedGuard.conditions.remove(n); - } else { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Replacing fixed guard " + fixedGuard + " with deoptimization node"); - } - return new Deoptimize(DeoptAction.InvalidateRecompile, fixedGuard.graph()); + public Node canonical(NotifyReProcess reProcess) { + for (BooleanNode n : conditions.snapshot()) { + if (n instanceof Constant) { + Constant c = (Constant) n; + if (c.asConstant().asBoolean()) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Removing redundant fixed guard " + this); } + conditions.remove(n); + } else { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Replacing fixed guard " + this + " with deoptimization node"); + } + return new Deoptimize(DeoptAction.InvalidateRecompile, graph()); } } + } - if (fixedGuard.conditions.isEmpty()) { - return fixedGuard.next(); - } - return fixedGuard; + if (conditions.isEmpty()) { + return next(); } - }; + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java Tue Aug 09 18:59:29 2011 +0200 @@ -29,58 +29,38 @@ import com.sun.cri.ci.*; @NodeInfo(shortName = "+") -public final class FloatAdd extends FloatArithmetic { - private static final FloatAddCanonicalizerOp CANONICALIZER = new FloatAddCanonicalizerOp(); +public final class FloatAdd extends FloatArithmetic implements Canonicalizable { public FloatAdd(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, kind == CiKind.Double ? Bytecodes.DADD : Bytecodes.FADD, x, y, isStrictFP, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && !y().isConstant()) { + swapOperands(); } - return super.lookup(clazz); - } - - private static class FloatAddCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FloatAdd add = (FloatAdd) node; - Value x = add.x(); - Value y = add.y(); - CiKind kind = add.kind; - Graph graph = add.graph(); - if (x.isConstant() && !y.isConstant()) { - add.swapOperands(); - Value t = y; - y = x; - x = t; + if (x().isConstant()) { + if (kind == CiKind.Float) { + return Constant.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph()); } - if (x.isConstant()) { - if (kind == CiKind.Float) { - return Constant.forFloat(x.asConstant().asFloat() + y.asConstant().asFloat(), graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(x.asConstant().asDouble() + y.asConstant().asDouble(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Float) { + float c = y().asConstant().asFloat(); + if (c == 0.0f) { + return x(); } - } else if (y.isConstant()) { - if (kind == CiKind.Float) { - float c = y.asConstant().asFloat(); - if (c == 0.0f) { - return x; - } - } else { - assert kind == CiKind.Double; - double c = y.asConstant().asDouble(); - if (c == 0.0) { - return x; - } + } else { + assert kind == CiKind.Double; + double c = y().asConstant().asDouble(); + if (c == 0.0) { + return x(); } } - return add; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,46 +22,29 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "/") -public final class FloatDiv extends FloatArithmetic { - private static final FloatDivCanonicalizerOp CANONICALIZER = new FloatDivCanonicalizerOp(); +public final class FloatDiv extends FloatArithmetic implements Canonicalizable { public FloatDiv(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, kind == CiKind.Double ? Bytecodes.DDIV : Bytecodes.FDIV, x, y, isStrictFP, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && y().isConstant()) { + if (kind == CiKind.Float) { + return Constant.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); + } } - return super.lookup(clazz); + return this; } - - private static class FloatDivCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FloatDiv div = (FloatDiv) node; - Value x = div.x(); - Value y = div.y(); - if (x.isConstant() && y.isConstant()) { - CiKind kind = div.kind; - Graph graph = div.graph(); - if (kind == CiKind.Float) { - return Constant.forFloat(x.asConstant().asFloat() / y.asConstant().asFloat(), graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(x.asConstant().asDouble() / y.asConstant().asDouble(), graph); - } - } - return div; - } - } - } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,64 +22,45 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "*") -public final class FloatMul extends FloatArithmetic { - private static final FloatMulCanonicalizerOp CANONICALIZER = new FloatMulCanonicalizerOp(); +public final class FloatMul extends FloatArithmetic implements Canonicalizable { public FloatMul(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, kind == CiKind.Double ? Bytecodes.DMUL : Bytecodes.FMUL, x, y, isStrictFP, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && !y().isConstant()) { + swapOperands(); } - return super.lookup(clazz); - } - - private static class FloatMulCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FloatMul mul = (FloatMul) node; - Value x = mul.x(); - Value y = mul.y(); - CiKind kind = mul.kind; - Graph graph = mul.graph(); - if (x.isConstant() && !y.isConstant()) { - mul.swapOperands(); - Value t = y; - y = x; - x = t; + if (x().isConstant()) { + if (kind == CiKind.Float) { + return Constant.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph()); } - if (x.isConstant()) { - if (kind == CiKind.Float) { - return Constant.forFloat(x.asConstant().asFloat() * y.asConstant().asFloat(), graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(x.asConstant().asDouble() * y.asConstant().asDouble(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Float) { + float c = y().asConstant().asFloat(); + if (c == 0.0f) { + return Constant.forFloat(0.0f, graph()); } - } else if (y.isConstant()) { - if (kind == CiKind.Float) { - float c = y.asConstant().asFloat(); - if (c == 0.0f) { - return Constant.forFloat(0.0f, graph); - } - } else { - assert kind == CiKind.Double; - double c = y.asConstant().asDouble(); - if (c == 0.0) { - return Constant.forDouble(0.0, graph); - } + } else { + assert kind == CiKind.Double; + double c = y().asConstant().asDouble(); + if (c == 0.0) { + return Constant.forDouble(0.0, graph()); } } - return mul; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,45 +22,29 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "%") -public final class FloatRem extends FloatArithmetic { - private static final FloatRemCanonicalizerOp CANONICALIZER = new FloatRemCanonicalizerOp(); +public final class FloatRem extends FloatArithmetic implements Canonicalizable { public FloatRem(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, kind == CiKind.Double ? Bytecodes.DREM : Bytecodes.FREM, x, y, isStrictFP, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && y().isConstant()) { + if (kind == CiKind.Float) { + return Constant.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph()); + } } - return super.lookup(clazz); - } - - private static class FloatRemCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FloatRem rem = (FloatRem) node; - Value x = rem.x(); - Value y = rem.y(); - if (x.isConstant() && y.isConstant()) { - CiKind kind = rem.kind; - Graph graph = rem.graph(); - if (kind == CiKind.Float) { - return Constant.forFloat(x.asConstant().asFloat() % y.asConstant().asFloat(), graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(x.asConstant().asDouble() % y.asConstant().asDouble(), graph); - } - } - return rem; - } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,68 +22,52 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "-") -public final class FloatSub extends FloatArithmetic { - private static final FloatSubCanonicalizerOp CANONICALIZER = new FloatSubCanonicalizerOp(); +public final class FloatSub extends FloatArithmetic implements Canonicalizable { public FloatSub(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, kind == CiKind.Double ? Bytecodes.DSUB : Bytecodes.FSUB, x, y, isStrictFP, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x() == y()) { + if (kind == CiKind.Float) { + return Constant.forFloat(0.0f, graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(0.0, graph()); + } } - return super.lookup(clazz); - } - - private static class FloatSubCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - FloatSub sub = (FloatSub) node; - Value x = sub.x(); - Value y = sub.y(); - CiKind kind = sub.kind; - Graph graph = sub.graph(); - if (x == y) { - if (kind == CiKind.Float) { - return Constant.forFloat(0.0f, graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(0.0, graph); - } + if (x().isConstant() && y().isConstant()) { + if (kind == CiKind.Float) { + return Constant.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph()); + } else { + assert kind == CiKind.Double; + return Constant.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph()); } - if (x.isConstant() && y.isConstant()) { - if (kind == CiKind.Float) { - return Constant.forFloat(x.asConstant().asFloat() - y.asConstant().asFloat(), graph); - } else { - assert kind == CiKind.Double; - return Constant.forDouble(x.asConstant().asDouble() - y.asConstant().asDouble(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Float) { + float c = y().asConstant().asFloat(); + if (c == 0.0f) { + return x(); } - } else if (y.isConstant()) { - if (kind == CiKind.Float) { - float c = y.asConstant().asFloat(); - if (c == 0.0f) { - return x; - } - return new FloatAdd(kind, x, Constant.forFloat(-c, graph), sub.isStrictFP(), graph); - } else { - assert kind == CiKind.Double; - double c = y.asConstant().asDouble(); - if (c == 0.0) { - return x; - } - return new FloatAdd(kind, x, Constant.forDouble(-c, graph), sub.isStrictFP(), graph); + return new FloatAdd(kind, x(), Constant.forFloat(-c, graph()), isStrictFP(), graph()); + } else { + assert kind == CiKind.Double; + double c = y().asConstant().asDouble(); + if (c == 0.0) { + return x(); } + return new FloatAdd(kind, x(), Constant.forDouble(-c, graph()), isStrictFP(), graph()); } - return sub; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Tue Aug 09 18:59:29 2011 +0200 @@ -29,8 +29,8 @@ import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; +public final class GuardNode extends FloatingNode implements Canonicalizable { -public final class GuardNode extends FloatingNode { @Input private FixedNode anchor; @Input private BooleanNode node; @@ -70,29 +70,17 @@ out.print("guard node ").print(node()); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (node() instanceof Constant) { + Constant c = (Constant) node(); + if (c.asConstant().asBoolean()) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Removing redundant floating guard " + this); + } + return Node.Null; + } } - return super.lookup(clazz); + return this; } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - GuardNode guard = (GuardNode) node; - if (guard.node() instanceof Constant) { - Constant c = (Constant) guard.node(); - if (c.asConstant().asBoolean()) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Removing redundant floating guard " + guard); - } - return Node.Null; - } - } - return guard; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Tue Aug 09 18:59:29 2011 +0200 @@ -24,18 +24,18 @@ 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.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; /** - * The {@code If} instruction represents a branch that can go one of two directions - * depending on the outcome of a comparison. + * The {@code If} instruction represents a branch that can go one of two directions depending on the outcome of a + * comparison. */ -public final class If extends ControlSplit { +public final class If extends ControlSplit implements Canonicalizable { - @Input private BooleanNode compare; + @Input private BooleanNode compare; public BooleanNode compare() { return compare; @@ -53,6 +53,7 @@ /** * Gets the block corresponding to the true successor. + * * @return the true successor */ public FixedNode trueSuccessor() { @@ -61,24 +62,24 @@ /** * Gets the block corresponding to the false successor. + * * @return the false successor */ public FixedNode falseSuccessor() { return blockSuccessor(1); } - public void setTrueSuccessor(FixedNode node) { setBlockSuccessor(0, node); } - public void setFalseSuccessor(FixedNode node) { setBlockSuccessor(1, node); } /** * Gets the block corresponding to the specified outcome of the branch. + * * @param istrue {@code true} if the true successor is requested, {@code false} otherwise * @return the corresponding successor */ @@ -101,64 +102,47 @@ @Override public void print(LogStream out) { - out.print("if "). - print(compare()). - print(" then "). - print(trueSuccessor()). - print(" else "). - print(falseSuccessor()); + out.print("if ").print(compare()).print(" then ").print(trueSuccessor()).print(" else ").print(falseSuccessor()); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (compare() instanceof Constant) { + Constant c = (Constant) compare(); + if (c.asConstant().asBoolean()) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Replacing if " + this + " with true branch"); + } + return trueSuccessor(); + } else { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Replacing if " + this + " with false branch"); + } + return falseSuccessor(); + } } - return super.lookup(clazz); - } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - If ifNode = (If) node; - if (ifNode.compare() instanceof Constant) { - Constant c = (Constant) ifNode.compare(); - if (c.asConstant().asBoolean()) { + if (trueSuccessor() instanceof EndNode && falseSuccessor() instanceof EndNode) { + EndNode trueEnd = (EndNode) trueSuccessor(); + EndNode falseEnd = (EndNode) falseSuccessor(); + 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 (compare().usages().size() == 1 && /* ifNode.compare().hasSideEffets() */true) { // TODO (gd) ifNode.compare().hasSideEffets() ? if (GraalOptions.TraceCanonicalizer) { - TTY.println("Replacing if " + ifNode + " with true branch"); + TTY.println("> Useless if with side effects Canon'ed to guard"); } - return ifNode.trueSuccessor(); + ValueAnchor anchor = new ValueAnchor(compare(), graph()); + anchor.setNext(next); + return anchor; } else { if (GraalOptions.TraceCanonicalizer) { - TTY.println("Replacing if " + ifNode + " with false branch"); + TTY.println("> Useless if Canon'ed away"); } - return ifNode.falseSuccessor(); + return next; } } - if (ifNode.trueSuccessor() instanceof EndNode && ifNode.falseSuccessor() instanceof EndNode) { - EndNode trueEnd = (EndNode) ifNode.trueSuccessor(); - EndNode falseEnd = (EndNode) ifNode.falseSuccessor(); - 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() ? - 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 { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("> Useless if Canon'ed away"); - } - return next; - } - } - } - return ifNode; } - }; + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,19 +23,19 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; 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.*; /** * The {@code InstanceOf} instruction represents an instanceof test. */ -public final class InstanceOf extends TypeCheck { +public final class InstanceOf extends TypeCheck implements Canonicalizable { /** * Constructs a new InstanceOf instruction. + * * @param targetClass the target class of the instanceof check * @param object the instruction producing the object input to this instruction * @param graph @@ -53,35 +53,21 @@ out.print("instanceof(").print(object()).print(") ").print(CiUtil.toJavaName(targetClass())); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (object().exactType() != null) { + return Constant.forBoolean(object().exactType().isSubtypeOf(targetClass()), graph()); } - return super.lookup(clazz); + CiConstant constant = object().asConstant(); + if (constant != null) { + assert constant.kind == CiKind.Object; + if (constant.isNull()) { + return Constant.forBoolean(false, graph()); + } else { + // this should never happen - non-null constants are always expected to provide an exactType + assert false; + } + } + return this; } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - InstanceOf isInstance = (InstanceOf) node; - Value object = isInstance.object(); - RiType exactType = object.exactType(); - if (exactType != null) { - return Constant.forBoolean(exactType.isSubtypeOf(isInstance.targetClass()), node.graph()); - } - CiConstant constant = object.asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - if (constant.isNull()) { - return Constant.forBoolean(false, node.graph()); - } else { - // this should never happen - non-null constants are always expected to provide an exactType - assert false; - } - } - return isInstance; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,65 +22,45 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "+") -public final class IntegerAdd extends IntegerArithmeticNode { - private static final IntegerAddCanonicalizerOp CANONICALIZER = new IntegerAddCanonicalizerOp(); +public final class IntegerAdd extends IntegerArithmeticNode implements Canonicalizable { public IntegerAdd(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IADD : Bytecodes.LADD, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && !y().isConstant()) { + swapOperands(); } - return super.lookup(clazz); - } - - private static class IntegerAddCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IntegerAdd add = (IntegerAdd) node; - Value x = add.x(); - Value y = add.y(); - CiKind kind = add.kind; - Graph graph = add.graph(); - if (x.isConstant() && !y.isConstant()) { - add.swapOperands(); - Value t = y; - y = x; - x = t; + if (x().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph()); } - if (x.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() + y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() + y.asConstant().asLong(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Int) { + int c = y().asConstant().asInt(); + if (c == 0) { + return x(); } - } else if (y.isConstant()) { - if (kind == CiKind.Int) { - int c = y.asConstant().asInt(); - if (c == 0) { - return x; - } - } else { - assert kind == CiKind.Long; - long c = y.asConstant().asLong(); - if (c == 0) { - return x; - } + } else { + assert kind == CiKind.Long; + long c = y().asConstant().asLong(); + if (c == 0) { + return x(); } } - return add; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,54 +22,38 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "/") -public final class IntegerDiv extends IntegerArithmeticNode { - private static final IntegerDivCanonicalizerOp CANONICALIZER = new IntegerDivCanonicalizerOp(); +public final class IntegerDiv extends IntegerArithmeticNode implements Canonicalizable { public IntegerDiv(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IDIV : Bytecodes.LDIV, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && y().isConstant()) { + long yConst = y().asConstant().asLong(); + if (yConst == 0) { + return this; // this will trap, can not canonicalize + } + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() / (int) yConst, graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() / yConst, graph()); + } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 1) { + return x(); + } } - return super.lookup(clazz); - } - - private static class IntegerDivCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IntegerDiv div = (IntegerDiv) node; - Value x = div.x(); - Value y = div.y(); - CiKind kind = div.kind; - Graph graph = div.graph(); - if (x.isConstant() && y.isConstant()) { - long yConst = y.asConstant().asLong(); - if (yConst == 0) { - return div; // this will trap, can not canonicalize - } - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() / (int) yConst, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() / yConst, graph); - } - } else if (y.isConstant()) { - long c = y.asConstant().asLong(); - if (c == 1) { - return x; - } - } - return div; - } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,62 +22,43 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "*") -public final class IntegerMul extends IntegerArithmeticNode { - private static final IntegerMulCanonicalizerOp CANONICALIZER = new IntegerMulCanonicalizerOp(); +public final class IntegerMul extends IntegerArithmeticNode implements Canonicalizable { public IntegerMul(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IMUL : Bytecodes.LMUL, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && !y().isConstant()) { + swapOperands(); } - return super.lookup(clazz); - } - - private static class IntegerMulCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IntegerMul mul = (IntegerMul) node; - Value x = mul.x(); - Value y = mul.y(); - CiKind kind = mul.kind; - Graph graph = mul.graph(); - if (x.isConstant() && !y.isConstant()) { - mul.swapOperands(); - Value t = y; - y = x; - x = t; + if (x().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph()); } - if (x.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() * y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() * y.asConstant().asLong(), graph); - } - } else if (y.isConstant()) { - long c = y.asConstant().asLong(); - if (c == 1) { - return x; - } - if (c == 0) { - return Constant.forInt(0, graph); - } - if (c > 0 && CiUtil.isPowerOf2(c)) { - return new LeftShift(kind, x, Constant.forInt(CiUtil.log2(c), graph), graph); - } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 1) { + return x(); } - return mul; + if (c == 0) { + return Constant.forInt(0, graph()); + } + if (c > 0 && CiUtil.isPowerOf2(c)) { + return new LeftShift(kind, x(), Constant.forInt(CiUtil.log2(c), graph()), graph()); + } } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,54 +22,43 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "%") -public final class IntegerRem extends IntegerArithmeticNode { - private static final IntegerRemCanonicalizerOp CANONICALIZER = new IntegerRemCanonicalizerOp(); +public final class IntegerRem extends IntegerArithmeticNode implements Canonicalizable { public IntegerRem(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IREM : Bytecodes.LREM, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static class IntegerRemCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IntegerRem rem = (IntegerRem) node; - Value x = rem.x(); - Value y = rem.y(); - CiKind kind = rem.kind; - Graph graph = rem.graph(); - if (x.isConstant() && y.isConstant()) { - long yConst = y.asConstant().asLong(); - if (yConst == 0) { - return rem; // this will trap, can not canonicalize - } + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant() && y().isConstant()) { + long yConst = y().asConstant().asLong(); + if (yConst == 0) { + return this; // this will trap, can not canonicalize + } + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() % (int) yConst, graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() % yConst, graph()); + } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 1 || c == -1) { if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() % (int) yConst, graph); + return Constant.forInt(0, graph()); } else { assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() % yConst, graph); - } - } else if (y.isConstant()) { - long c = y.asConstant().asLong(); - if (c == 1) { - return x; + return Constant.forLong(0, graph()); } } - return rem; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,69 +22,53 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "-") -public final class IntegerSub extends IntegerArithmeticNode { - private static final IntegerSubCanonicalizerOp CANONICALIZER = new IntegerSubCanonicalizerOp(); +public final class IntegerSub extends IntegerArithmeticNode implements Canonicalizable { public IntegerSub(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.ISUB : Bytecodes.LSUB, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x() == y()) { + if (kind == CiKind.Int) { + return Constant.forInt(0, graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(0, graph()); + } } - return super.lookup(clazz); - } - - private static class IntegerSubCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IntegerSub sub = (IntegerSub) node; - Value x = sub.x(); - Value y = sub.y(); - CiKind kind = sub.kind; - Graph graph = sub.graph(); - if (x == y) { - if (kind == CiKind.Int) { - return Constant.forInt(0, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(0, graph); - } + if (x().isConstant() && y().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph()); } - if (x.isConstant() && y.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() - y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() - y.asConstant().asLong(), graph); - } - } else if (y.isConstant()) { - long c = y.asConstant().asLong(); - if (c == 0) { - return x; - } - if (kind == CiKind.Int) { - return new IntegerAdd(kind, x, Constant.forInt((int) -c, graph), graph); - } else { - assert kind == CiKind.Long; - return new IntegerAdd(kind, x, Constant.forLong(-c, graph), graph); - } - } else if (x.isConstant()) { - long c = x.asConstant().asLong(); - if (c == 0) { - return new Negate(y, graph); - } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 0) { + return x(); } - return sub; + if (kind == CiKind.Int) { + return new IntegerAdd(kind, x(), Constant.forInt((int) -c, graph()), graph()); + } else { + assert kind == CiKind.Long; + return new IntegerAdd(kind, x(), Constant.forLong(-c, graph()), graph()); + } + } else if (x().isConstant()) { + long c = x().asConstant().asLong(); + if (c == 0) { + return new Negate(y(), graph()); + } } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,7 +23,7 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -32,9 +32,9 @@ /** * The {@code NullCheck} class represents an explicit null check instruction. */ -public final class IsNonNull extends BooleanNode { +public final class IsNonNull extends BooleanNode implements Canonicalizable { - @Input private Value object; + @Input private Value object; public Value object() { return object; @@ -47,6 +47,7 @@ /** * Constructs a new NullCheck instruction. + * * @param object the instruction producing the object to check against null * @param graph */ @@ -78,29 +79,16 @@ out.print("null_check(").print(object()).print(')'); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (object() instanceof NewInstance || object() instanceof NewArray) { + return Constant.forBoolean(true, graph()); } - return super.lookup(clazz); + CiConstant constant = object().asConstant(); + if (constant != null) { + assert constant.kind == CiKind.Object; + return Constant.forBoolean(constant.isNonNull(), graph()); + } + return this; } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IsNonNull isNonNull = (IsNonNull) node; - Value object = isNonNull.object(); - if (object instanceof NewInstance || object instanceof NewArray) { - return Constant.forBoolean(true, node.graph()); - } - CiConstant constant = object.asConstant(); - if (constant != null) { - assert constant.kind == CiKind.Object; - return Constant.forBoolean(constant.isNonNull(), node.graph()); - } - return isNonNull; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java Tue Aug 09 18:59:29 2011 +0200 @@ -25,7 +25,7 @@ import java.util.*; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -34,9 +34,9 @@ /** * The {@code TypeCheck} class represents an explicit type check instruction. */ -public final class IsType extends BooleanNode { +public final class IsType extends BooleanNode implements Canonicalizable { - @Input private Value object; + @Input private Value object; public Value object() { return object; @@ -51,6 +51,7 @@ /** * Constructs a new IsType instruction. + * * @param object the instruction producing the object to check against the given type * @param graph */ @@ -94,26 +95,12 @@ return properties; } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (object().exactType() != null) { + return Constant.forBoolean(object().exactType() == type(), graph()); } - return super.lookup(clazz); + // constants return the correct exactType, so they are handled by the code above + return this; } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - IsType isType = (IsType) node; - Value object = isType.object(); - RiType exactType = object.exactType(); - if (exactType != null) { - return Constant.forBoolean(exactType == isType.type, node.graph()); - } - // constants return the correct exactType, so they are handled by the code above - return isType; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,84 +22,67 @@ */ package com.oracle.max.graal.compiler.ir; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; 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.*; @NodeInfo(shortName = "<<") -public final class LeftShift extends Shift { - private static final LeftShiftCanonicalizerOp CANONICALIZER = new LeftShiftCanonicalizerOp(); +public final class LeftShift extends Shift implements Canonicalizable { public LeftShift(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.ISHL : Bytecodes.LSHL, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static class LeftShiftCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - LeftShift leftShift = (LeftShift) node; - CiKind kind = leftShift.kind; - Graph graph = leftShift.graph(); - Value value = leftShift.x(); - Value y = leftShift.y(); - if (y.isConstant()) { - int amount = y.asConstant().asInt(); - int originalAmout = amount; - int mask; + public Node canonical(NotifyReProcess reProcess) { + if (y().isConstant()) { + int amount = y().asConstant().asInt(); + int originalAmout = amount; + int mask; + if (kind == CiKind.Int) { + mask = 0x1f; + } else { + assert kind == CiKind.Long; + mask = 0x3f; + } + amount &= mask; + if (x().isConstant()) { if (kind == CiKind.Int) { - mask = 0x1f; + return Constant.forInt(x().asConstant().asInt() << amount, graph()); } else { assert kind == CiKind.Long; - mask = 0x3f; - } - amount &= mask; - if (value.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(value.asConstant().asInt() << amount, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(value.asConstant().asLong() << amount, graph); - } - } - if (amount == 0) { - return value; + return Constant.forLong(x().asConstant().asLong() << amount, graph()); } - if (value instanceof Shift) { - Shift other = (Shift) value; - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof LeftShift) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return Constant.forInt(0, graph); - } - return new LeftShift(kind, other.x(), Constant.forInt(total, graph), graph); - } else if ((other instanceof RightShift || other instanceof UnsignedRightShift) && otherAmount == amount) { - if (kind == CiKind.Long) { - return new And(kind, other.x(), Constant.forLong(-1L << amount, graph), graph); - } else { - assert kind == CiKind.Int; - return new And(kind, other.x(), Constant.forInt(-1 << amount, graph), graph); - } + } + if (amount == 0) { + return x(); + } + if (x() instanceof Shift) { + Shift other = (Shift) x(); + if (other.y().isConstant()) { + int otherAmount = other.y().asConstant().asInt() & mask; + if (other instanceof LeftShift) { + int total = amount + otherAmount; + if (total != (total & mask)) { + return Constant.forInt(0, graph()); + } + return new LeftShift(kind, other.x(), Constant.forInt(total, graph()), graph()); + } else if ((other instanceof RightShift || other instanceof UnsignedRightShift) && otherAmount == amount) { + if (kind == CiKind.Long) { + return new And(kind, other.x(), Constant.forLong(-1L << amount, graph()), graph()); + } else { + assert kind == CiKind.Int; + return new And(kind, other.x(), Constant.forInt(-1 << amount, graph()), graph()); } } } - if (originalAmout != amount) { - return new LeftShift(kind, value, Constant.forInt(amount, graph), graph); - } } - return leftShift; + if (originalAmout != amount) { + return new LeftShift(kind, x(), Constant.forInt(amount, graph()), graph()); + } } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,10 +23,8 @@ package com.oracle.max.graal.compiler.ir; 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.Canonicalizable; 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.*; import com.sun.cri.ri.*; @@ -34,11 +32,11 @@ /** * The {@code LoadField} instruction represents a read of a static or instance field. */ -public final class LoadField extends AccessField { - private static final LoadFieldCanonicalizerOp CANONICALIZER = new LoadFieldCanonicalizerOp(); +public final class LoadField extends AccessField implements Canonicalizable { /** * Creates a new LoadField instance. + * * @param object the receiver object * @param field the compiler interface field * @param isStatic indicates if the field is static @@ -52,6 +50,7 @@ /** * Gets the declared type of the field being accessed. + * * @return the declared type of the field being accessed. */ @Override @@ -60,9 +59,9 @@ } /** - * Gets the exact type of the field being accessed. If the field type is - * a primitive array or an instance class and the class is loaded and final, - * then the exact type is the same as the declared type. Otherwise it is {@code null} + * Gets the exact type of the field being accessed. If the field type is a primitive array or an instance class and + * the class is loaded and final, then the exact type is the same as the declared type. Otherwise it is {@code null} + * * @return the exact type of the field if known; {@code null} otherwise */ @Override @@ -78,12 +77,7 @@ @Override public void print(LogStream out) { - out.print(object()). - print("."). - print(field.name()). - print(" [field: "). - print(CiUtil.format("%h.%n:%t", field, false)). - print("]"); + out.print(object()).print(".").print(field.name()).print(" [field: ").print(CiUtil.format("%h.%n:%t", field, false)).print("]"); } @Override @@ -105,35 +99,17 @@ return null; } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } else if (clazz == LoweringOp.class) { - return (T) LoweringPhase.DELEGATE_TO_RUNTIME; + public Node canonical(NotifyReProcess reProcess) { + CiConstant constant = null; + if (isStatic()) { + constant = field().constantValue(null); + } else if (object().isConstant()) { + constant = field().constantValue(object().asConstant()); } - return super.lookup(clazz); - } - - private static class LoadFieldCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - LoadField loadField = (LoadField) node; - Graph graph = node.graph(); - CiConstant constant = null; - if (loadField.isStatic()) { - constant = loadField.field().constantValue(null); - } else { - Value object = loadField.object(); - if (object.isConstant()) { - constant = loadField.field().constantValue(object.asConstant()); - } - } - if (constant != null) { - return new Constant(constant, graph); - } - return loadField; + if (constant != null) { + return new Constant(constant, graph()); } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java Tue Aug 09 18:59:29 2011 +0200 @@ -31,10 +31,10 @@ /** * The {@code NegateOp} instruction negates its operand. */ -public final class Negate extends FloatingNode { - private static final NegateCanonicalizerOp CANONICALIZER = new NegateCanonicalizerOp(); +public final class Negate extends FloatingNode implements Canonicalizable { - @Input private Value x; + @Input + private Value x; public Value x() { return x; @@ -47,6 +47,7 @@ /** * Creates new NegateOp instance. + * * @param x the instruction producing the value that is input to this instruction */ public Negate(Value x, Graph graph) { @@ -69,33 +70,23 @@ out.print("- ").print(x()); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x().isConstant()) { + switch (x().kind) { + case Int: + return Constant.forInt(-x().asConstant().asInt(), graph()); + case Long: + return Constant.forLong(-x().asConstant().asLong(), graph()); + case Float: + return Constant.forFloat(-x().asConstant().asFloat(), graph()); + case Double: + return Constant.forDouble(-x().asConstant().asDouble(), graph()); + } } - return super.lookup(clazz); - } - - private static class NegateCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - Negate negate = (Negate) node; - Value x = negate.x(); - Graph graph = negate.graph(); - if (x.isConstant()) { - switch (x.kind) { - case Int: return Constant.forInt(-x.asConstant().asInt(), graph); - case Long: return Constant.forLong(-x.asConstant().asLong(), graph); - case Float: return Constant.forFloat(-x.asConstant().asFloat(), graph); - case Double: return Constant.forDouble(-x.asConstant().asDouble(), graph); - } - } - if (x instanceof Negate) { - return ((Negate) x).x(); - } - return negate; + if (x() instanceof Negate) { + return ((Negate) x()).x(); } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java Tue Aug 09 18:59:29 2011 +0200 @@ -23,14 +23,14 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; -public final class NegateBooleanNode extends BooleanNode { +public final class NegateBooleanNode extends BooleanNode implements Canonicalizable { - @Input private BooleanNode value; + @Input private BooleanNode value; public BooleanNode value() { return value; @@ -55,26 +55,13 @@ out.print(value()).print("!"); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (value() instanceof NegateBooleanNode) { + return ((NegateBooleanNode) value()).value(); + } else if (value() instanceof Constant) { + return Constant.forBoolean(!value().asConstant().asBoolean(), graph()); } - return super.lookup(clazz); + return this; } - - private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - @Override - 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()); - } - return negateNode; - } - }; } diff -r 82266dbf5a5a -r 65c865bba4c2 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java Tue Aug 09 18:59:29 2011 +0200 @@ -33,7 +33,7 @@ */ public final class NewMultiArray extends NewArray { - @Input private final NodeInputList dimensions; + @Input private final NodeInputList dimensions; @Override public Value dimension(int index) { diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,73 +22,54 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "|") -public final class Or extends Logic { - private static final OrCanonicalizerOp CANONICALIZER = new OrCanonicalizerOp(); +public final class Or extends Logic implements Canonicalizable { public Or(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IOR : Bytecodes.LOR, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x() == y()) { + return x(); } - return super.lookup(clazz); - } - - private static class OrCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - Or or = (Or) node; - CiKind kind = or.kind; - Graph graph = or.graph(); - Value x = or.x(); - Value y = or.y(); - if (x == y) { - return x; - } - if (x.isConstant() && !y.isConstant()) { - or.swapOperands(); - Value t = y; - y = x; - x = t; + if (x().isConstant() && !y().isConstant()) { + swapOperands(); + } + if (x().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph()); } - if (x.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() | y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() | y.asConstant().asLong(), graph); + } else if (y().isConstant()) { + if (kind == CiKind.Int) { + int c = y().asConstant().asInt(); + if (c == -1) { + return Constant.forInt(-1, graph()); + } + if (c == 0) { + return x(); } - } else if (y.isConstant()) { - if (kind == CiKind.Int) { - int c = y.asConstant().asInt(); - if (c == -1) { - return Constant.forInt(-1, graph); - } - if (c == 0) { - return x; - } - } else { - assert kind == CiKind.Long; - long c = y.asConstant().asLong(); - if (c == -1) { - return Constant.forLong(-1, graph); - } - if (c == 0) { - return x; - } + } else { + assert kind == CiKind.Long; + long c = y().asConstant().asLong(); + if (c == -1) { + return Constant.forLong(-1, graph()); + } + if (c == 0) { + return x(); } } - return or; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Tue Aug 09 18:59:29 2011 +0200 @@ -27,20 +27,20 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; 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.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; /** - * The {@code Phi} instruction represents the merging of dataflow - * in the instruction graph. It refers to a join block and a variable. + * The {@code Phi} instruction represents the merging of dataflow in the instruction graph. It refers to a join block + * and a variable. */ -public final class Phi extends FloatingNode { +public final class Phi extends FloatingNode implements Canonicalizable { - @Input private Merge merge; + @Input private Merge merge; - @Input private final NodeInputList values = new NodeInputList(this); + @Input private final NodeInputList values = new NodeInputList(this); public Merge merge() { return merge; @@ -52,9 +52,9 @@ } public static enum PhiType { - Value, // normal value phis - Memory, // memory phis - Virtual // phis used for VirtualObjectField merges + Value, // normal value phis + Memory, // memory phis + Virtual // phis used for VirtualObjectField merges } private final PhiType type; @@ -82,8 +82,8 @@ } /** - * Get the instruction that produces the value associated with the i'th predecessor - * of the join block. + * Get the instruction that produces the value associated with the i'th predecessor of the join block. + * * @param i the index of the predecessor * @return the instruction that produced the value in the i'th predecessor */ @@ -97,6 +97,7 @@ /** * Get the number of inputs to this phi (i.e. the number of predecessors to the join block). + * * @return the number of inputs in this phi */ public int valueCount() { @@ -145,9 +146,10 @@ } @Override - public Iterable dataInputs() { + public Iterable< ? extends Node> dataInputs() { final Iterator< ? extends Node> input = super.dataInputs().iterator(); return new Iterable() { + @Override public Iterator iterator() { return new FilteringIterator(input, Merge.class); @@ -155,58 +157,42 @@ }; } - - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (valueCount() != 2 || merge().endCount() != 2) { + return this; + } + 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 this; + } + Node end0 = merge().endAt(0); + Node end1 = merge().endAt(1); + Node endPred0 = end0.predecessor(); + Node endPred1 = end1.predecessor(); + if (endPred0 != endPred1 || !(endPred0 instanceof If)) { + return this; } - return super.lookup(clazz); + If ifNode = (If) endPred0; + boolean inverted = ifNode.trueSuccessor() == end1; + Value trueValue = valueAt(inverted ? 1 : 0); + Value falseValue = valueAt(inverted ? 0 : 1); + if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) { + return this; + } + if ((!(trueValue instanceof Constant) && trueValue.usages().size() == 1) || (!(falseValue instanceof Constant) && falseValue.usages().size() == 1)) { + return this; + } + 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 this; + } + if (GraalOptions.TraceCanonicalizer) { + TTY.println("> Phi canon'ed to Conditional"); + } + reProcess.reProccess(ifNode); + return new Conditional(ifNode.compare(), trueValue, falseValue, graph()); } - - private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - - @Override - 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); - Node endPred0 = end0.predecessor(); - Node endPred1 = end1.predecessor(); - if (endPred0 != endPred1 || !(endPred0 instanceof If)) { - return phiNode; - } - If ifNode = (If) endPred0; - boolean inverted = ifNode.trueSuccessor() == end1; - Value trueValue = phiNode.valueAt(inverted ? 1 : 0); - Value falseValue = phiNode.valueAt(inverted ? 0 : 1); - 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; - } - 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 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Tue Aug 09 18:59:29 2011 +0200 @@ -25,7 +25,7 @@ import com.oracle.max.graal.compiler.*; 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.Canonicalizable; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -34,7 +34,8 @@ /** * This instruction is used to perform the finalizer registration at the end of the java.lang.Object constructor. */ -public final class RegisterFinalizer extends StateSplit { +public final class RegisterFinalizer extends StateSplit implements Canonicalizable { + @Input private Value object; public Value object() { @@ -56,58 +57,43 @@ v.visitRegisterFinalizer(this); } - @SuppressWarnings("unchecked") - @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { - - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - RegisterFinalizer finalizer = (RegisterFinalizer) node; - Value object = finalizer.object(); - - RiType declaredType = object.declaredType(); - RiType exactType = object.exactType(); - if (exactType == null && declaredType != null) { - exactType = declaredType.exactType(); - } - - boolean needsCheck = true; - if (exactType != null) { - // we have an exact type - needsCheck = exactType.hasFinalizer(); - } else { - // if either the declared type of receiver or the holder can be assumed to have no finalizers - if (declaredType != null && !declaredType.hasFinalizableSubclass()) { - if (((CompilerGraph) node.graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) { - needsCheck = false; - } - } - } - - if (needsCheck) { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Could not canonicalize finalizer " + object + " (declaredType=" + declaredType + ", exactType=" + exactType + ")"); - } - } else { - if (GraalOptions.TraceCanonicalizer) { - TTY.println("Canonicalized finalizer for object " + object); - } - return finalizer.next(); - } - - return finalizer; - } - }; - @Override public void print(LogStream out) { out.print("register finalizer ").print(object()); } + + @Override + public Node canonical(NotifyReProcess reProcess) { + RiType declaredType = object.declaredType(); + RiType exactType = object.exactType(); + if (exactType == null && declaredType != null) { + exactType = declaredType.exactType(); + } + + boolean needsCheck = true; + if (exactType != null) { + // we have an exact type + needsCheck = exactType.hasFinalizer(); + } else { + // if either the declared type of receiver or the holder can be assumed to have no finalizers + if (declaredType != null && !declaredType.hasFinalizableSubclass()) { + if (((CompilerGraph) graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) { + needsCheck = false; + } + } + } + + if (needsCheck) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Could not canonicalize finalizer " + object + " (declaredType=" + declaredType + ", exactType=" + exactType + ")"); + } + } else { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Canonicalized finalizer for object " + object); + } + return next(); + } + + return this; + } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,76 +22,60 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = ">>") -public final class RightShift extends Shift { - private static final RighShiftCanonicalizerOp CANONICALIZER = new RighShiftCanonicalizerOp(); +public final class RightShift extends Shift implements Canonicalizable { public RightShift(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.ISHR : Bytecodes.LSHR, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static class RighShiftCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - RightShift rightShift = (RightShift) node; - CiKind kind = rightShift.kind; - Graph graph = rightShift.graph(); - Value value = rightShift.x(); - Value y = rightShift.y(); - if (y.isConstant()) { - int amount = y.asConstant().asInt(); - int originalAmout = amount; - int mask; + public Node canonical(NotifyReProcess reProcess) { + if (y().isConstant()) { + int amount = y().asConstant().asInt(); + int originalAmout = amount; + int mask; + if (kind == CiKind.Int) { + mask = 0x1f; + } else { + assert kind == CiKind.Long; + mask = 0x3f; + } + amount &= mask; + if (x().isConstant()) { if (kind == CiKind.Int) { - mask = 0x1f; + return Constant.forInt(x().asConstant().asInt() >> amount, graph()); } else { assert kind == CiKind.Long; - mask = 0x3f; + return Constant.forLong(x().asConstant().asLong() >> amount, graph()); } - amount &= mask; - if (value.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(value.asConstant().asInt() >> amount, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(value.asConstant().asLong() >> amount, graph); + } + if (amount == 0) { + return x(); + } + if (x() instanceof Shift) { + Shift other = (Shift) x(); + if (other.y().isConstant()) { + int otherAmount = other.y().asConstant().asInt() & mask; + if (other instanceof RightShift) { + int total = amount + otherAmount; + if (total != (total & mask)) { + return Constant.forInt(0, graph()); + } + return new RightShift(kind, other.x(), Constant.forInt(total, graph()), graph()); } } - if (amount == 0) { - return value; - } - if (value instanceof Shift) { - Shift other = (Shift) value; - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof RightShift) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return Constant.forInt(0, graph); - } - return new RightShift(kind, other.x(), Constant.forInt(total, graph), graph); - } - } - } - if (originalAmout != amount) { - return new RightShift(kind, value, Constant.forInt(amount, graph), graph); - } } - return rightShift; + if (originalAmout != amount) { + return new RightShift(kind, x(), Constant.forInt(amount, graph()), graph()); + } } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,83 +22,67 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = ">>>") -public final class UnsignedRightShift extends Shift { - private static final UnsignedRightShiftCanonicalizerOp CANONICALIZER = new UnsignedRightShiftCanonicalizerOp(); +public final class UnsignedRightShift extends Shift implements Canonicalizable { public UnsignedRightShift(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IUSHR : Bytecodes.LUSHR, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; - } - return super.lookup(clazz); - } - - private static class UnsignedRightShiftCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - UnsignedRightShift ushr = (UnsignedRightShift) node; - CiKind kind = ushr.kind; - Graph graph = ushr.graph(); - Value value = ushr.x(); - Value y = ushr.y(); - if (y.isConstant()) { - int amount = y.asConstant().asInt(); - int originalAmout = amount; - int mask; + public Node canonical(NotifyReProcess reProcess) { + if (y().isConstant()) { + int amount = y().asConstant().asInt(); + int originalAmout = amount; + int mask; + if (kind == CiKind.Int) { + mask = 0x1f; + } else { + assert kind == CiKind.Long; + mask = 0x3f; + } + amount &= mask; + if (x().isConstant()) { if (kind == CiKind.Int) { - mask = 0x1f; + return Constant.forInt(x().asConstant().asInt() >>> amount, graph()); } else { assert kind == CiKind.Long; - mask = 0x3f; - } - amount &= mask; - if (value.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(value.asConstant().asInt() >>> amount, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(value.asConstant().asLong() >>> amount, graph); - } - } - if (amount == 0) { - return value; + return Constant.forLong(x().asConstant().asLong() >>> amount, graph()); } - if (value instanceof Shift) { - Shift other = (Shift) value; - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; - if (other instanceof UnsignedRightShift) { - int total = amount + otherAmount; - if (total != (total & mask)) { - return Constant.forInt(0, graph); - } - return new UnsignedRightShift(kind, other.x(), Constant.forInt(total, graph), graph); - } else if (other instanceof LeftShift && otherAmount == amount) { - if (kind == CiKind.Long) { - return new And(kind, other.x(), Constant.forLong(-1L >>> amount, graph), graph); - } else { - assert kind == CiKind.Int; - return new And(kind, other.x(), Constant.forInt(-1 >>> amount, graph), graph); - } + } + if (amount == 0) { + return x(); + } + if (x() instanceof Shift) { + Shift other = (Shift) x(); + if (other.y().isConstant()) { + int otherAmount = other.y().asConstant().asInt() & mask; + if (other instanceof UnsignedRightShift) { + int total = amount + otherAmount; + if (total != (total & mask)) { + return Constant.forInt(0, graph()); + } + return new UnsignedRightShift(kind, other.x(), Constant.forInt(total, graph()), graph()); + } else if (other instanceof LeftShift && otherAmount == amount) { + if (kind == CiKind.Long) { + return new And(kind, other.x(), Constant.forLong(-1L >>> amount, graph()), graph()); + } else { + assert kind == CiKind.Int; + return new And(kind, other.x(), Constant.forInt(-1 >>> amount, graph()), graph()); } } } - if (originalAmout != amount) { - return new UnsignedRightShift(kind, value, Constant.forInt(amount, graph), graph); - } } - return ushr; + if (originalAmout != amount) { + return new UnsignedRightShift(kind, x(), Constant.forInt(amount, graph()), graph()); + } } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java Tue Aug 09 18:59:29 2011 +0200 @@ -22,73 +22,53 @@ */ 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.*; import com.sun.cri.ci.*; @NodeInfo(shortName = "^") -public final class Xor extends Logic { - private static final XorCanonicalizerOp CANONICALIZER = new XorCanonicalizerOp(); +public final class Xor extends Logic implements Canonicalizable { public Xor(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IXOR : Bytecodes.LXOR, x, y, graph); } - @SuppressWarnings("unchecked") @Override - public T lookup(Class clazz) { - if (clazz == CanonicalizerOp.class) { - return (T) CANONICALIZER; + public Node canonical(NotifyReProcess reProcess) { + if (x() == y()) { + if (kind == CiKind.Int) { + return Constant.forInt(0, graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(0L, graph()); + } + } + if (x().isConstant() && !y().isConstant()) { + swapOperands(); } - return super.lookup(clazz); - } - - private static class XorCanonicalizerOp implements CanonicalizerOp { - @Override - public Node canonical(Node node, NotifyReProcess reProcess) { - assert node instanceof Xor; - Xor xor = (Xor) node; - CiKind kind = xor.kind; - Graph graph = xor.graph(); - Value x = xor.x(); - Value y = xor.y(); - if (x == y) { - if (kind == CiKind.Int) { - return Constant.forInt(0, graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(0L, graph); + if (x().isConstant()) { + if (kind == CiKind.Int) { + return Constant.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph()); + } else { + assert kind == CiKind.Long; + return Constant.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph()); + } + } else if (y().isConstant()) { + if (kind == CiKind.Int) { + int c = y().asConstant().asInt(); + if (c == 0) { + return x(); + } + } else { + assert kind == CiKind.Long; + long c = y().asConstant().asLong(); + if (c == 0) { + return x(); } } - if (x.isConstant() && !y.isConstant()) { - xor.swapOperands(); - Value t = y; - y = x; - x = t; - } - if (x.isConstant()) { - if (kind == CiKind.Int) { - return Constant.forInt(x.asConstant().asInt() ^ y.asConstant().asInt(), graph); - } else { - assert kind == CiKind.Long; - return Constant.forLong(x.asConstant().asLong() ^ y.asConstant().asLong(), graph); - } - } else if (y.isConstant()) { - if (kind == CiKind.Int) { - int c = y.asConstant().asInt(); - if (c == 0) { - return x; - } - } else { - assert kind == CiKind.Long; - long c = y.asConstant().asLong(); - if (c == 0) { - return x; - } - } - } - return xor; } + return this; } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Tue Aug 09 18:59:29 2011 +0200 @@ -53,13 +53,12 @@ } }; for (Node node : nodeWorkList) { - CanonicalizerOp op = node.lookup(CanonicalizerOp.class); - if (op != null) { + if (node instanceof Canonicalizable) { if (GraalOptions.TraceCanonicalizer) { TTY.println("Canonicalizer: work on " + node); } graph.mark(); - Node canonical = op.canonical(node, reProcess); + Node canonical = ((Canonicalizable) node).canonical(reProcess); if (canonical != node) { node.replaceAndDelete(canonical); nodeWorkList.replaced(canonical, node, false, EdgeType.USAGES); @@ -76,7 +75,7 @@ void reProccess(Node n); } - public interface CanonicalizerOp extends Op { - Node canonical(Node node, NotifyReProcess reProcess); + public interface Canonicalizable { + Node canonical(NotifyReProcess reProcess); } } diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Tue Aug 09 18:59:29 2011 +0200 @@ -845,7 +845,7 @@ private void genGetStatic(int cpi, RiField field) { RiType holder = field.holder(); - boolean isInitialized = field.isResolved() && field.holder().isInitialized(); + boolean isInitialized = field.isResolved() && holder.isInitialized(); CiConstant constantValue = null; if (isInitialized) { constantValue = field.constantValue(null); @@ -867,7 +867,7 @@ private void genPutStatic(int cpi, RiField field) { RiType holder = field.holder(); - Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && field.holder().isInitialized()); + Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && holder.isInitialized()); Value value = frameState.pop(field.kind().stackKind()); if (container != null) { StoreField store = new StoreField(container, field, value, graph); diff -r 82266dbf5a5a -r 65c865bba4c2 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 Tue Aug 09 18:53:11 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java Tue Aug 09 18:59:29 2011 +0200 @@ -26,12 +26,14 @@ 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.NotifyReProcess; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; -public final class FPConversionNode extends FloatingNode { +public final class FPConversionNode extends FloatingNode implements Canonicalizable { + @Input private Value value; public Value value() { @@ -48,16 +50,12 @@ this.setValue(value); } - @SuppressWarnings("unchecked") @Override public T lookup(Class clazz) { if (clazz == LIRGeneratorOp.class) { return (T) LIRGEN; } - if (clazz == CanonicalizerOp.class) { - return (T) CANON; - } return super.lookup(clazz); } @@ -66,29 +64,8 @@ out.print("fp conversion node ").print(value()); } - 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() { - private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() { @Override public void generate(Node n, LIRGenerator generator) { FPConversionNode conv = (FPConversionNode) n; @@ -98,4 +75,21 @@ generator.lir().move(tmp, reg); } }; + + @Override + public Node canonical(NotifyReProcess reProcess) { + if (value instanceof Constant) { + CiKind fromKind = value.kind; + if (kind == CiKind.Int && fromKind == CiKind.Float) { + return Constant.forInt(Float.floatToRawIntBits(((Constant) value).asConstant().asFloat()), graph()); + } else if (kind == CiKind.Long && fromKind == CiKind.Double) { + return Constant.forLong(Double.doubleToRawLongBits(((Constant) value).asConstant().asDouble()), graph()); + } else if (kind == CiKind.Float && fromKind == CiKind.Int) { + return Constant.forFloat(Float.intBitsToFloat(((Constant) value).asConstant().asInt()), graph()); + } else if (kind == CiKind.Double && fromKind == CiKind.Long) { + return Constant.forDouble(Double.longBitsToDouble(((Constant) value).asConstant().asLong()), graph()); + } + } + return this; + } }