# HG changeset patch # User Gilles Duboscq # Date 1307565676 -7200 # Node ID e7ba2bad98fb90feb32e86db6d1c0ae45e5ef658 # Parent 9d80049e76bd3433bb26e082dd4885e94ddcda03 Canonicalize LoadField & ArrayLength diff -r 9d80049e76bd -r e7ba2bad98fb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Wed Jun 08 22:41:16 2011 +0200 @@ -55,7 +55,7 @@ public final CiAssumptions assumptions = new CiAssumptions(); public final FrameState placeholderState; - public CompilerGraph graph = new CompilerGraph(); + public CompilerGraph graph = new CompilerGraph(this); private boolean hasExceptionHandlers; private final GraalCompilation parent; diff -r 9d80049e76bd -r e7ba2bad98fb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java Wed Jun 08 22:41:16 2011 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.graph; +import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.graph.*; @@ -30,6 +31,12 @@ private Return returnSingleton; private Unwind unwindSingleton; + private GraalCompilation compilation; + + + public CompilerGraph(GraalCompilation compilation) { + this.compilation = compilation; + } public Return createReturn(Value result) { assert returnSingleton == null; @@ -50,4 +57,9 @@ public Unwind getUnwind() { return unwindSingleton; } + + + public GraalCompilation getCompilation() { + return compilation; + } } diff -r 9d80049e76bd -r e7ba2bad98fb 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 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jun 08 22:41:16 2011 +0200 @@ -69,12 +69,14 @@ */ public void build() { new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph); - new DuplicationPhase().apply(compilation.graph); + printGraph("After GraphBuilding", compilation.graph); + //new DuplicationPhase().apply(compilation.graph); new DeadCodeEliminationPhase().apply(compilation.graph); - printGraph("After GraphBuilding", compilation.graph); + printGraph("After DeadCodeElimination", compilation.graph); if (GraalOptions.Inline) { new InliningPhase(compilation, this).apply(compilation.graph); + printGraph("After Ininling", compilation.graph); } if (GraalOptions.Time) { diff -r 9d80049e76bd -r e7ba2bad98fb 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 Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java Wed Jun 08 22:41:16 2011 +0200 @@ -23,15 +23,19 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.graph.*; +import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; +import com.sun.cri.ri.*; /** * The {@code ArrayLength} instruction gets the length of an array. */ public final class ArrayLength extends FloatingNode { + private static final ArrayLengthCanonicalizerOp CANONICALIZER = new ArrayLengthCanonicalizerOp(); private static final int INPUT_COUNT = 1; private static final int INPUT_ARRAY = 0; @@ -98,4 +102,43 @@ ArrayLength x = new ArrayLength(null, into); return x; } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class ArrayLengthCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + 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 instanceof LoadField) { + constantValue = ((LoadField) array).constantValue(); + } else if (array.isConstant()) { + constantValue = array.asConstant(); + } + if (constantValue != null && constantValue.isNonNull()) { + Graph graph = node.graph(); + if (graph instanceof CompilerGraph) { + RiRuntime runtime = ((CompilerGraph) graph).getCompilation().runtime; + return Constant.forInt(runtime.getArrayLength(constantValue), graph); + } + } + return arrayLength; + } + } } diff -r 9d80049e76bd -r e7ba2bad98fb 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 Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Wed Jun 08 22:41:16 2011 +0200 @@ -23,6 +23,8 @@ package com.oracle.max.graal.compiler.ir; 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.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -31,6 +33,7 @@ * 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(); private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; @@ -89,9 +92,57 @@ return false; } + /** + * Gets a constant value to which this load can be reduced. + * + * @return {@code null} if this load cannot be reduced to a constant + */ + public CiConstant constantValue() { + if (isStatic()) { + return field.constantValue(null); + } else if (object().isConstant()) { + return field.constantValue(object().asConstant()); + } + return null; + } + @Override public Node copy(Graph into) { LoadField x = new LoadField(null, field, into); return x; } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == CanonicalizerOp.class) { + return (T) CANONICALIZER; + } + return super.lookup(clazz); + } + + private static class LoadFieldCanonicalizerOp implements CanonicalizerOp { + @Override + public Node canonical(Node node) { + LoadField loadField = (LoadField) node; + Graph graph = node.graph(); + CiConstant constant = null; + if (graph instanceof CompilerGraph) { + RiMethod method = ((CompilerGraph) graph).getCompilation().method; + if (loadField.isStatic() && !method.isClassInitializer()) { + constant = loadField.field().constantValue(null); + } + } + if (!loadField.isStatic()) { + Value object = loadField.object(); + if (object.isConstant()) { + constant = loadField.field().constantValue(object.asConstant()); + } + } + if (constant != null) { + return new Constant(constant, graph); + } + return loadField; + } + } } diff -r 9d80049e76bd -r e7ba2bad98fb 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 Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Wed Jun 08 22:41:16 2011 +0200 @@ -60,6 +60,7 @@ Node canonical = op.canonical(n); if (canonical != n) { n.replace(canonical); + //System.out.println("-->" + n + " canonicalized to " + canonical); GraalMetrics.NodesCanonicalized++; } } diff -r 9d80049e76bd -r e7ba2bad98fb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java Wed Jun 08 22:41:16 2011 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.graph.*; @@ -35,8 +36,13 @@ @Override protected void run(Graph graph) { + GraalCompilation compilation = null; + if (graph instanceof CompilerGraph) { + compilation = ((CompilerGraph) graph).getCompilation(); + } + // Create duplicate graph. - CompilerGraph duplicate = new CompilerGraph(); + CompilerGraph duplicate = new CompilerGraph(compilation); Map replacements = new HashMap(); replacements.put(graph.start(), duplicate.start()); duplicate.addDuplicate(graph.getNodes(), replacements); diff -r 9d80049e76bd -r e7ba2bad98fb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Jun 08 21:21:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Jun 08 22:41:16 2011 +0200 @@ -150,7 +150,7 @@ System.out.printf("Building graph for %s, locals: %d, stack: %d\n", name, method.maxLocals(), method.maxStackSize()); } - CompilerGraph graph = new CompilerGraph(); + CompilerGraph graph = new CompilerGraph(compilation); new GraphBuilderPhase(compilation, method, true, true).apply(graph); boolean withReceiver = !Modifier.isStatic(method.accessFlags());