changeset 14714:b602356a9cfc

additional canonicalizers for accesses and value nodes (improves number of implicit null checks)
author Lukas Stadler <lukas.stadler@oracle.com>
date Thu, 20 Mar 2014 17:15:36 +0100
parents c8fb80093621
children 03704aa6e71b
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java
diffstat 5 files changed, 53 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Fri Mar 21 11:51:14 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Thu Mar 20 17:15:36 2014 +0100
@@ -43,6 +43,11 @@
         return object;
     }
 
+    protected void setObject(ValueNode x) {
+        updateUsages(object, x);
+        object = x;
+    }
+
     public LocationNode location() {
         return (LocationNode) location;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Fri Mar 21 11:51:14 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Thu Mar 20 17:15:36 2014 +0100
@@ -67,6 +67,9 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
+        if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
+            return graph().unique(new FloatingReadNode(((PiNode) object()).getOriginalValue(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+        }
         return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible());
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Mar 21 11:51:14 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Mar 20 17:15:36 2014 +0100
@@ -60,6 +60,9 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
+        if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
+            return graph().add(new ReadNode(((PiNode) object()).getOriginalValue(), location(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+        }
         return canonicalizeRead(this, location(), object(), tool, isCompressible());
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Fri Mar 21 11:51:14 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Thu Mar 20 17:15:36 2014 +0100
@@ -22,16 +22,17 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
 
 /**
  * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
  */
-public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode {
+public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, GuardingNode {
 
     @Input private ValueNode anchored;
 
@@ -50,19 +51,40 @@
     }
 
     @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) {
-            // Found entry that needs this anchor.
-            return this;
+    public void simplify(SimplifierTool tool) {
+        while (next() instanceof ValueAnchorNode) {
+            ValueAnchorNode nextAnchor = (ValueAnchorNode) next();
+            if (nextAnchor.anchored == anchored || nextAnchor.anchored == null) {
+                // two anchors for the same anchored -> coalesce
+                // nothing anchored on the next anchor -> coalesce
+                nextAnchor.replaceAtUsages(this);
+                GraphUtil.removeFixedWithUnusedInputs(nextAnchor);
+            } else {
+                break;
+            }
+        }
+        if (usages().isEmpty() && next() instanceof FixedAccessNode) {
+            FixedAccessNode next = (FixedAccessNode) next();
+            if (next.getGuard() == anchored) {
+                GraphUtil.removeFixedWithUnusedInputs(this);
+                return;
+            } else if (next.getGuard() == null && anchored instanceof GuardNode && ((GuardNode) anchored).condition() instanceof IsNullNode) {
+                // coalesce null check guards into subsequent read/write
+                next.setGuard((GuardingNode) anchored);
+                tool.addToWorkList(next());
+                return;
+            }
         }
 
-        if (usages().isNotEmpty()) {
-            // A not uses this anchor => anchor is necessary.
-            return this;
+        if (anchored != null && (anchored.isConstant() || anchored instanceof FixedNode)) {
+            // anchoring fixed nodes and constants is useless
+            removeAnchoredNode();
         }
 
-        // Anchor is not necessary any more => remove.
-        return null;
+        if (anchored == null && usages().isEmpty()) {
+            // anchor is not necessary any more => remove.
+            GraphUtil.removeFixedWithUnusedInputs(this);
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Fri Mar 21 11:51:14 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Thu Mar 20 17:15:36 2014 +0100
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.LocationNode.Location;
 import com.oracle.graal.nodes.spi.*;
@@ -33,7 +34,7 @@
 /**
  * Writes a given {@linkplain #value() value} a {@linkplain FixedAccessNode memory location}.
  */
-public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Virtualizable {
+public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Simplifiable, Virtualizable {
 
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
@@ -102,6 +103,13 @@
         gen.emitStore(location().getValueKind(), address, v, this);
     }
 
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
+            setObject(((PiNode) object()).getOriginalValue());
+        }
+    }
+
     @NodeIntrinsic
     public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType, @ConstantNodeParameter boolean compressible);