# HG changeset patch # User Gilles Duboscq # Date 1307552045 -7200 # Node ID d5f6a22dd959a5d5bd39bcd27084a90b7d45b5d4 # Parent 43224fe0f24064454ffb1e18ce54af3e2de3c647 Canonicalization of FloatArithmetic nodes diff -r 43224fe0f240 -r d5f6a22dd959 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Jun 08 18:54:05 2011 +0200 @@ -40,7 +40,6 @@ public static int InlinedFinalizerChecks; public static int InlineForcedMethods; public static int InlineForbiddenMethods; - public static int InlinedJsrs; public static int BlocksDeleted; public static int BytecodesCompiled; public static int CodeBytesEmitted; diff -r 43224fe0f240 -r d5f6a22dd959 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Wed Jun 08 18:54:05 2011 +0200 @@ -24,7 +24,7 @@ import java.io.*; import java.util.*; -import java.util.Map.*; +import java.util.Map.Entry; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.schedule.*; @@ -52,7 +52,7 @@ private final HashSet> omittedClasses = new HashSet>(); private final PrintStream stream; - private final List noBlockNodes = new LinkedList(); + private final Set noBlockNodes = new HashSet(); /** * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream. @@ -111,7 +111,7 @@ */ public void print(Graph graph, String title, boolean shortNames) { stream.printf(" %n", escape(title)); - + noBlockNodes.clear(); Schedule schedule = null; try { schedule = new Schedule(); @@ -228,6 +228,7 @@ } } } + // add all framestates and phis to their blocks for (Node node : block.getInstructions()) { if (node instanceof Instruction && ((Instruction) node).stateAfter() != null) { diff -r 43224fe0f240 -r d5f6a22dd959 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jun 08 18:54:05 2011 +0200 @@ -73,8 +73,10 @@ } new GraphBuilderPhase(compilation, compilation.method, false).apply(compilation.graph); - new DuplicationPhase().apply(compilation.graph); + verifyAndPrint("After GraphBuilder"); + //new DuplicationPhase().apply(compilation.graph); new DeadCodeEliminationPhase().apply(compilation.graph); + verifyAndPrint("After DeadCodeElimination"); if (GraalOptions.Inline) { new InliningPhase(compilation, this).apply(compilation.graph); @@ -90,6 +92,8 @@ if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase().apply(graph); verifyAndPrint("After Canonicalization"); + new DeadCodeEliminationPhase().apply(compilation.graph); + verifyAndPrint("After DeadCodeElimination"); } new SplitCriticalEdgesPhase().apply(graph); diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; public final class FloatAdd extends FloatArithmetic { + private static final FloatAddCanonicalizerOp CANONICALIZER = new FloatAddCanonicalizerOp(); 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); @@ -44,4 +46,51 @@ return x; } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class FloatAddCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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); + } + } else if (y.isConstant()) { + if (kind == CiKind.Float) { + float c = y.asConstant().asFloat(); + if (c == 0.0f) { + return x; + } + } else { + assert kind == CiKind.Long; + double c = y.asConstant().asDouble(); + if (c == 0.0) { + return x; + } + } + } + return add; + } + } } diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,24 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; - -/** - * - */ public final class FloatDiv extends FloatArithmetic { + private static final FloatDivCanonicalizerOp CANONICALIZER = new FloatDivCanonicalizerOp(); - /** - * @param opcode - * @param kind - * @param x - * @param y - * @param isStrictFP - * @param graph - */ 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); } @@ -55,4 +45,33 @@ return x; } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class FloatDivCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -31,6 +32,7 @@ * */ public final class FloatMul extends FloatArithmetic { + private static final FloatMulCanonicalizerOp CANONICALIZER = new FloatMulCanonicalizerOp(); /** * @param opcode @@ -54,4 +56,51 @@ return new FloatMul(kind, null, null, isStrictFP(), into); } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class FloatMulCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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); + } + } 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); + } + } + } + return mul; + } + } } diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,24 +22,15 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; -/** - * - */ public final class FloatRem extends FloatArithmetic { + private static final FloatRemCanonicalizerOp CANONICALIZER = new FloatRemCanonicalizerOp(); - /** - * @param opcode - * @param kind - * @param x - * @param y - * @param isStrictFP - * @param graph - */ 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); } @@ -54,4 +45,32 @@ return new FloatRem(kind, null, null, isStrictFP(), into); } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class FloatRemCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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; + } + } } diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; public final class FloatSub extends FloatArithmetic { + private static final FloatSubCanonicalizerOp CANONICALIZER = new FloatSubCanonicalizerOp(); 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); @@ -43,4 +45,67 @@ return new FloatSub(kind, null, null, isStrictFP(), into); } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class FloatSubCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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); + } + } 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 if (x.isConstant()) { + // TODO (gd) check that Negate impl for floating point is really faster/better than 0.0 - x + if (kind == CiKind.Float) { + float c = x.asConstant().asFloat(); + if (c == 0.0f) { + return new Negate(y, graph); + } + } else { + assert kind == CiKind.Double; + double c = x.asConstant().asDouble(); + if (c == 0.0) { + return new Negate(y, graph); + } + } + } + return sub; + } + } } diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java Wed Jun 08 18:54:05 2011 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.max.graal.compiler.ir; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; public final class IntegerRem extends IntegerArithmetic { + private static final IntegerRemCanonicalizerOp CANONICALIZER = new IntegerRemCanonicalizerOp(); public IntegerRem(CiKind kind, Value x, Value y, Graph graph) { super(kind, kind == CiKind.Int ? Bytecodes.IREM : Bytecodes.LREM, x, y, graph); @@ -43,4 +45,41 @@ return new IntegerRem(kind, null, null, into); } + @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) { + 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 + } + 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 rem; + } + } } diff -r 43224fe0f240 -r d5f6a22dd959 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 Wed Jun 08 15:43:43 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Wed Jun 08 18:54:05 2011 +0200 @@ -78,17 +78,9 @@ 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; - } + long c = y.asConstant().asLong(); + if (c == 0) { + return x; } } else if (x.isConstant()) { long c = x.asConstant().asLong();