changeset 14932:8ce9a950fbe2

allow memory arithmetic to swallow UnsafeCastNode
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 01 Apr 2014 15:42:19 -0700
parents d45e8c306349
children 0a7fce0ac01b
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java
diffstat 3 files changed, 48 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Tue Apr 01 15:41:28 2014 -0700
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java	Tue Apr 01 15:42:19 2014 -0700
@@ -82,7 +82,7 @@
 
     protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) {
         ValueNode other = x;
-        if (other == access) {
+        if (uncast(other) == access) {
             if (commutative) {
                 other = y;
             } else {
@@ -194,7 +194,7 @@
             case Long:
                 return emitBinaryMemory(LAND, true, x, y, access);
             case Short: {
-                ValueNode other = x == access ? y : x;
+                ValueNode other = selectOtherInput(x, y, access);
                 Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null;
                 if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) {
                     // Convert to unsigned load
@@ -207,7 +207,7 @@
                 if (OptFoldMemory.getValue()) {
                     return null;
                 }
-                ValueNode other = x == access ? y : x;
+                ValueNode other = selectOtherInput(x, y, access);
                 Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null;
                 if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) {
                     // Convert to unsigned load
@@ -398,10 +398,12 @@
     }
 
     private boolean emitIntegerTestBranchMemory(ValueNode left, ValueNode right, Access access, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
-        assert left == access || right == access;
-        ValueNode other = left == access ? right : left;
+        ValueNode other = selectOtherInput(left, right, access);
         Kind kind = access.nullCheckLocation().getValueKind();
         if (other.isConstant()) {
+            if (kind != kind.getStackKind()) {
+                return false;
+            }
             Constant constant = other.asConstant();
             if (kind == Kind.Long && !NumUtil.isInt(constant.asLong())) {
                 // Only imm32 as long
@@ -418,10 +420,25 @@
         return true;
     }
 
+    /**
+     * @return the input which is not equal to access, accounting for possible UnsafeCastNodes.
+     */
+    protected ValueNode selectOtherInput(ValueNode left, ValueNode right, Access access) {
+        assert uncast(left) == access || uncast(right) == access;
+        return uncast(left) == access ? right : left;
+    }
+
+    protected ValueNode uncast(ValueNode value) {
+        if (value instanceof UnsafeCastNode) {
+            UnsafeCastNode cast = (UnsafeCastNode) value;
+            return cast.getOriginalValue();
+        }
+        return value;
+    }
+
     protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel,
                     double trueLabelProbability) {
-        assert left == access || right == access;
-        ValueNode other = left == access ? right : left;
+        ValueNode other = selectOtherInput(left, right, access);
         Kind kind = access.nullCheckLocation().getValueKind();
         boolean mirrored = false;
 
@@ -447,7 +464,7 @@
             }
             ensureEvaluated(other);
             gen.getLIRGenerator().emitCompareMemoryConOp(kind, makeAddress(access), constant, getState(access));
-            mirrored = right == access;
+            mirrored = uncast(right) == access;
         } else {
             if (kind != kind.getStackKind()) {
                 // Register compares only work for stack kinds
@@ -461,7 +478,7 @@
 
             evaluateDeferred();
             gen.getLIRGenerator().emitCompareRegMemoryOp(kind, gen.operand(other), makeAddress(access), getState(access));
-            mirrored = left == access;
+            mirrored = uncast(left) == access;
         }
 
         Condition finalCondition = mirrored ? cond.mirror() : cond;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Tue Apr 01 15:41:28 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Tue Apr 01 15:42:19 2014 -0700
@@ -273,9 +273,15 @@
                 // This is all bit hacky since it's happening on the linearized schedule. This needs
                 // to be revisited at some point.
 
+                // Uncast the memory operation.
+                Node use = access.usages().first();
+                if (use instanceof UnsafeCastNode && use.usages().count() == 1) {
+                    use = use.usages().first();
+                }
+
                 // Find a memory lowerable usage of this operation
-                if (access.usages().first() instanceof MemoryArithmeticLIRLowerable) {
-                    ValueNode operation = (ValueNode) access.usages().first();
+                if (use instanceof MemoryArithmeticLIRLowerable) {
+                    ValueNode operation = (ValueNode) use;
                     if (!nodes.contains(operation)) {
                         Debug.log("node %1s in different block from %1s", access, operation);
                         MemoryFoldFailedDifferentBlock.increment();
@@ -316,11 +322,12 @@
                     int opIndex = nodes.indexOf(operation);
                     int current = i + 1;
                     ArrayList<ValueNode> deferred = null;
-                    while (current < opIndex) {
+                    for (; current < opIndex; current++) {
                         ScheduledNode node = nodes.get(current);
                         if (node != firstOperation) {
                             if (node instanceof LocationNode || node instanceof VirtualObjectNode) {
                                 // nothing to do
+                                continue;
                             } else if (node instanceof ConstantNode) {
                                 if (deferred == null) {
                                     deferred = new ArrayList<>(2);
@@ -330,13 +337,18 @@
                                 // basically works around unfriendly scheduling of values which
                                 // are defined in a block but not used there.
                                 deferred.add((ValueNode) node);
-                            } else {
-                                Debug.log("unexpected node %1s", node);
-                                // Unexpected inline node
-                                break;
+                                continue;
+                            } else if (node instanceof UnsafeCastNode) {
+                                UnsafeCastNode cast = (UnsafeCastNode) node;
+                                if (cast.getOriginalValue() == access) {
+                                    continue;
+                                }
                             }
+
+                            // Unexpected inline node
+                            // Debug.log("unexpected node %1s", node);
+                            break;
                         }
-                        current++;
                     }
 
                     if (current == opIndex) {
@@ -369,7 +381,7 @@
                     } else {
                         MemoryFoldFailedNonAdjacent.increment();
                     }
-                } else {
+                } else if (!(use instanceof Access) && !(use instanceof PhiNode) && use.usages().count() == 1) {
                     // memory usage which isn't considered lowerable. Mostly these are
                     // uninteresting but it might be worth looking at to ensure that interesting
                     // nodes are being properly handled.
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Tue Apr 01 15:41:28 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java	Tue Apr 01 15:42:19 2014 -0700
@@ -84,9 +84,8 @@
     @Override
     protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel,
                     double trueLabelProbability) {
-        assert left == access || right == access;
         if (HotSpotGraalRuntime.runtime().getConfig().useCompressedOops) {
-            ValueNode other = left == access ? right : left;
+            ValueNode other = selectOtherInput(left, right, access);
             Kind kind = access.nullCheckLocation().getValueKind();
 
             if (other.isConstant() && kind == Kind.Object && access.isCompressible()) {