changeset 11815:43bc62c78f77

attempt to canonicalize array length access when lowering array load|store operations
author Doug Simon <doug.simon@oracle.com>
date Thu, 26 Sep 2013 22:45:25 +0200
parents 22d47c2c74e9
children 8db5e8c4f542
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java
diffstat 3 files changed, 31 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Thu Sep 26 16:46:27 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Thu Sep 26 22:45:25 2013 +0200
@@ -447,7 +447,7 @@
     @Test
     public void testLoop4() {
         SchedulePhase schedule = getFinalSchedule("testLoop4Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL);
-        assertReadWithinStartBlock(schedule, true);
+        assertReadWithinStartBlock(schedule, false);
         assertReadWithinReturnBlock(schedule, false);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Sep 26 16:46:27 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Sep 26 22:45:25 2013 +0200
@@ -49,6 +49,7 @@
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
+import static com.oracle.graal.nodes.java.ArrayLengthNode.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 import static com.oracle.graal.replacements.Log.*;
@@ -994,10 +995,15 @@
     private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph g = n.graph();
         ValueNode array = n.array();
-        Stamp stamp = StampFactory.positiveInt();
-        ReadNode arrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false));
-        g.addBeforeFixed(n, arrayLength);
-        tool.createNullCheckGuard(arrayLength, array);
+        ValueNode arrayLength = readArrayLength(array, tool.getRuntime());
+        if (arrayLength == null) {
+            Stamp stamp = StampFactory.positiveInt();
+            ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false));
+            g.addBeforeFixed(n, readArrayLength);
+            tool.createNullCheckGuard(readArrayLength, array);
+            arrayLength = readArrayLength;
+        }
+
         return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Thu Sep 26 16:46:27 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Thu Sep 26 22:45:25 2013 +0200
@@ -45,23 +45,36 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (array() instanceof ArrayLengthProvider) {
-            ValueNode length = ((ArrayLengthProvider) array()).length();
+        ValueNode length = readArrayLength(array(), tool.runtime());
+        if (length != null) {
+            return length;
+        }
+        return this;
+    }
+
+    /**
+     * Gets the length of an array if possible.
+     * 
+     * @param array an array
+     * @return a node representing the length of {@code array} or null if it is not available
+     */
+    public static ValueNode readArrayLength(ValueNode array, MetaAccessProvider runtime) {
+        if (array instanceof ArrayLengthProvider) {
+            ValueNode length = ((ArrayLengthProvider) array).length();
             if (length != null) {
                 return length;
             }
         }
-        MetaAccessProvider runtime = tool.runtime();
-        if (runtime != null && array().isConstant() && !array().isNullConstant()) {
-            Constant constantValue = array().asConstant();
+        if (runtime != null && array.isConstant() && !array.isNullConstant()) {
+            Constant constantValue = array.asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
                 Integer constantLength = runtime.lookupArrayLength(constantValue);
                 if (constantLength != null) {
-                    return ConstantNode.forInt(constantLength, graph());
+                    return ConstantNode.forInt(constantLength, array.graph());
                 }
             }
         }
-        return this;
+        return null;
     }
 
     @Override