changeset 15348:1c347436d596

added UnaryOpLogicNode base class, renamed BinaryLogicNode
author Lukas Stadler <lukas.stadler@oracle.com>
date Thu, 24 Apr 2014 10:44:12 +0200
parents 78882562556b
children 7766f486f5d6
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java
diffstat 7 files changed, 191 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryLogicNode.java	Thu Apr 24 08:38:00 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-
-public abstract class BinaryLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable {
-
-    @Input private ValueNode x;
-    @Input private ValueNode y;
-
-    public ValueNode x() {
-        return x;
-    }
-
-    public ValueNode y() {
-        return y;
-    }
-
-    protected void setX(ValueNode x) {
-        updateUsages(this.x, x);
-        this.x = x;
-    }
-
-    protected void setY(ValueNode y) {
-        updateUsages(this.y, y);
-        this.y = y;
-    }
-
-    public BinaryLogicNode(ValueNode x, ValueNode y) {
-        assert x != null && y != null && x.getKind() == y.getKind();
-        this.x = x;
-        this.y = y;
-    }
-
-    @Override
-    public boolean verify() {
-        assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp());
-        return super.verify();
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool gen) {
-    }
-
-    @Override
-    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
-        return false;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+
+public abstract class BinaryOpLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable {
+
+    @Input private ValueNode x;
+    @Input private ValueNode y;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public ValueNode y() {
+        return y;
+    }
+
+    protected void setX(ValueNode x) {
+        updateUsages(this.x, x);
+        this.x = x;
+    }
+
+    protected void setY(ValueNode y) {
+        updateUsages(this.y, y);
+        this.y = y;
+    }
+
+    public BinaryOpLogicNode(ValueNode x, ValueNode y) {
+        assert x != null && y != null && x.getKind() == y.getKind();
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp());
+        return super.verify();
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool gen) {
+    }
+
+    @Override
+    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.api.meta.ProfilingInfo.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+
+public abstract class UnaryOpLogicNode extends LogicNode implements LIRLowerable, MemoryArithmeticLIRLowerable {
+
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    protected void setX(ValueNode object) {
+        updateUsages(this.object, object);
+        this.object = object;
+    }
+
+    public UnaryOpLogicNode(ValueNode object) {
+        assert object != null;
+        this.object = object;
+    }
+
+    public abstract TriState evaluate(ValueNode forObject);
+
+    @Override
+    public void generate(NodeLIRBuilderTool gen) {
+    }
+
+    @Override
+    public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Thu Apr 24 08:38:00 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -35,7 +35,7 @@
  * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed
  * into variants that do not materialize the value (CompareIf, CompareGuard...)
  */
-public abstract class CompareNode extends BinaryLogicNode implements Canonicalizable {
+public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable {
 
     /**
      * Constructs a new Compare instruction.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Thu Apr 24 08:38:00 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -32,7 +32,7 @@
  * expression "(x &amp; y) == 0", meaning that it will return true if (and only if) no bit is set in
  * both x and y.
  */
-public class IntegerTestNode extends BinaryLogicNode implements Canonicalizable {
+public class IntegerTestNode extends BinaryOpLogicNode implements Canonicalizable {
 
     /**
      * Constructs a new Test instruction.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Thu Apr 24 08:38:00 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -33,21 +34,15 @@
 /**
  * An IsNullNode will be true if the supplied value is null, and false if it is non-null.
  */
-public final class IsNullNode extends LogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable {
-
-    @Input private ValueNode object;
-
-    public ValueNode object() {
-        return object;
-    }
+public final class IsNullNode extends UnaryOpLogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable {
 
     /**
      * Constructs a new IsNullNode instruction.
-     * 
+     *
      * @param object the instruction producing the object to check against null
      */
     public IsNullNode(ValueNode object) {
-        this.object = object;
+        super(object);
     }
 
     @Override
@@ -64,20 +59,31 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        Constant constant = object().asConstant();
-        if (constant != null) {
-            assert constant.getKind() == Kind.Object;
-            return LogicConstantNode.forBoolean(constant.isNull(), graph());
-        }
-        if (StampTool.isObjectNonNull(object.stamp())) {
-            return LogicConstantNode.contradiction(graph());
+        switch (evaluate(object())) {
+            case FALSE:
+                return LogicConstantNode.contradiction(graph());
+            case TRUE:
+                return LogicConstantNode.tautology(graph());
         }
         return this;
     }
 
     @Override
+    public TriState evaluate(ValueNode forObject) {
+        Constant constant = forObject.asConstant();
+        if (constant != null) {
+            assert constant.getKind() == Kind.Object;
+            return TriState.get(constant.isNull());
+        }
+        if (StampTool.isObjectNonNull(forObject.stamp())) {
+            return TriState.FALSE;
+        }
+        return TriState.UNKNOWN;
+    }
+
+    @Override
     public void virtualize(VirtualizerTool tool) {
-        if (tool.getObjectState(object) != null) {
+        if (tool.getObjectState(object()) != null) {
             tool.replaceWithValue(LogicConstantNode.contradiction(graph()));
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Thu Apr 24 08:38:00 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Thu Apr 24 10:44:12 2014 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -33,21 +34,20 @@
 /**
  * The {@code InstanceOfNode} represents an instanceof test.
  */
-public final class InstanceOfNode extends LogicNode implements Canonicalizable, Lowerable, Virtualizable {
+public final class InstanceOfNode extends UnaryOpLogicNode implements Canonicalizable, Lowerable, Virtualizable {
 
-    @Input private ValueNode object;
     private final ResolvedJavaType type;
     private JavaTypeProfile profile;
 
     /**
      * Constructs a new InstanceOfNode.
-     * 
+     *
      * @param type the target type of the instanceof check
      * @param object the object being tested by the instanceof
      */
     public InstanceOfNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) {
+        super(object);
         this.type = type;
-        this.object = object;
         this.profile = profile;
         assert type != null;
     }
@@ -59,13 +59,39 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        Stamp stamp = object().stamp();
+        switch (evaluate(object())) {
+            case FALSE:
+                return LogicConstantNode.contradiction(graph());
+            case TRUE:
+                return LogicConstantNode.tautology(graph());
+            case UNKNOWN:
+                Stamp stamp = object().stamp();
+                if (stamp instanceof ObjectStamp) {
+                    ObjectStamp objectStamp = (ObjectStamp) stamp;
+                    ResolvedJavaType stampType = objectStamp.type();
+                    if (stampType != null && type().isAssignableFrom(stampType)) {
+                        if (!objectStamp.nonNull()) {
+                            // the instanceof matches if the object is non-null, so return true
+                            // depending on the null-ness.
+                            IsNullNode isNull = graph().unique(new IsNullNode(object()));
+                            return graph().unique(new LogicNegationNode(isNull));
+                        }
+                    }
+                }
+                return this;
+        }
+        return this;
+    }
+
+    @Override
+    public TriState evaluate(ValueNode forObject) {
+        Stamp stamp = forObject.stamp();
         if (!(stamp instanceof ObjectStamp)) {
-            return this;
+            return TriState.UNKNOWN;
         }
         ObjectStamp objectStamp = (ObjectStamp) stamp;
         if (objectStamp.alwaysNull()) {
-            return LogicConstantNode.contradiction(graph());
+            return TriState.FALSE;
         }
 
         ResolvedJavaType stampType = objectStamp.type();
@@ -74,34 +100,25 @@
             if (subType) {
                 if (objectStamp.nonNull()) {
                     // the instanceOf matches, so return true
-                    return LogicConstantNode.tautology(graph());
-                } else {
-                    // the instanceof matches if the object is non-null, so return true depending on
-                    // the null-ness.
-                    IsNullNode isNull = graph().unique(new IsNullNode(object()));
-                    return graph().unique(new LogicNegationNode(isNull));
+                    return TriState.TRUE;
                 }
             } else {
                 if (objectStamp.isExactType()) {
                     // since this type check failed for an exact type we know that it can never
                     // succeed at run time. we also don't care about null values, since they will
                     // also make the check fail.
-                    return LogicConstantNode.contradiction(graph());
+                    return TriState.FALSE;
                 } else {
                     boolean superType = stampType.isAssignableFrom(type());
                     if (!superType && !stampType.isInterface() && !type().isInterface()) {
-                        return LogicConstantNode.contradiction(graph());
+                        return TriState.FALSE;
                     }
                     // since the subtype comparison was only performed on a declared type we don't
                     // really know if it might be true at run time...
                 }
             }
         }
-        return this;
-    }
-
-    public ValueNode object() {
-        return object;
+        return TriState.UNKNOWN;
     }
 
     /**
@@ -121,7 +138,7 @@
 
     @Override
     public void virtualize(VirtualizerTool tool) {
-        State state = tool.getObjectState(object);
+        State state = tool.getObjectState(object());
         if (state != null) {
             tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph()));
         }