changeset 2918:e7ba2bad98fb

Canonicalize LoadField & ArrayLength
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Wed, 08 Jun 2011 22:41:16 +0200
parents 9d80049e76bd
children 5429750cb94c
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java
diffstat 8 files changed, 120 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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;
+    }
 }
--- 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) {
--- 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 extends Op> T lookup(Class<T> 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;
+        }
+    }
 }
--- 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 extends Op> T lookup(Class<T> 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;
+        }
+    }
 }
--- 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++;
             }
         }
--- 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<Node, Node> replacements = new HashMap<Node, Node>();
         replacements.put(graph.start(), duplicate.start());
         duplicate.addDuplicate(graph.getNodes(), replacements);
--- 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());