changeset 7726:f629d4a264c6

new IntegerTestNode, unit tests for IntegerTestNode canonicalization
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 05 Feb 2013 15:53:21 +0100
parents 301cff1a99d1
children be7b98533b17
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java
diffstat 3 files changed, 164 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Tue Feb 05 15:52:41 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Tue Feb 05 15:53:21 2013 +0100
@@ -22,14 +22,29 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static org.junit.Assert.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.phases.common.*;
 
 public class CompareCanonicalizerTest extends GraalCompilerTest {
 
+    private StructuredGraph getCanonicalizedGraph(String name) {
+        StructuredGraph graph = parse(name);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        return graph;
+    }
+
+    private static ValueNode getResult(StructuredGraph graph) {
+        assertTrue(graph.start().next() instanceof ReturnNode);
+        ReturnNode ret = (ReturnNode) graph.start().next();
+        return ret.result();
+    }
+
     @Test
     public void testCanonicalComparison() {
         StructuredGraph referenceGraph = parse("referenceCanonicalComparison");
@@ -40,8 +55,7 @@
         Assumptions assumptions = new Assumptions(false);
         new CanonicalizerPhase(null, runtime(), assumptions).apply(referenceGraph);
         for (int i = 1; i < 4; i++) {
-            StructuredGraph graph = parse("canonicalCompare" + i);
-            new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
+            StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
             assertEquals(referenceGraph, graph);
         }
     }
@@ -77,4 +91,78 @@
             return 1;
         }
     }
+
+    @Test
+    public void testIntegerTest() {
+        for (int i = 1; i <= 4; i++) {
+            StructuredGraph graph = getCanonicalizedGraph("integerTest" + i);
+
+            ValueNode result = getResult(graph);
+            assertTrue(result instanceof ConditionalNode);
+            ConditionalNode mat = (ConditionalNode) result;
+            assertTrue(mat.condition() instanceof IntegerTestNode);
+            IntegerTestNode test = (IntegerTestNode) mat.condition();
+            LocalNode local0 = graph.getLocal(0);
+            LocalNode local1 = graph.getLocal(1);
+            assertTrue((test.x() == local0 && test.y() == local1) || (test.x() == local1 && test.y() == local0));
+        }
+    }
+
+    public static boolean integerTest1(int x, int y) {
+        return (x & y) == 0;
+    }
+
+    public static boolean integerTest2(long x, long y) {
+        return 0 == (x & y);
+    }
+
+    public static boolean integerTest3(long x, long y) {
+        int c = 5;
+        return (c - 5) == (x & y);
+    }
+
+    public static boolean integerTest4(int x, int y) {
+        int c = 10;
+        return (x & y) == (10 - c);
+    }
+
+    @Test
+    public void testIntegerTestCanonicalization() {
+        ValueNode result = getResult(getCanonicalizedGraph("integerTestCanonicalization1"));
+        assertTrue(result.isConstant() && result.asConstant().asLong() == 1);
+        result = getResult(getCanonicalizedGraph("integerTestCanonicalization2"));
+        assertTrue(result.isConstant() && result.asConstant().asLong() == 1);
+        result = getResult(getCanonicalizedGraph("integerTestCanonicalization3"));
+        assertTrue(result instanceof ConditionalNode);
+    }
+
+    public static int integerTestCanonicalization1(boolean b) {
+        int x = b ? 128 : 256;
+        if ((x & 8) == 0) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int integerTestCanonicalization2(boolean b) {
+        int x = b ? 128 : 256;
+        int y = b ? 32 : 64;
+        if ((x & y) == 0) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int integerTestCanonicalization3(boolean b) {
+        int x = b ? 128 : 64;
+        int y = b ? 32 : 64;
+        if ((x & y) == 0) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Tue Feb 05 15:52:41 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Tue Feb 05 15:53:21 2013 +0100
@@ -74,6 +74,12 @@
         } else if (x().integerStamp().alwaysDistinct(y().integerStamp())) {
             return ConstantNode.forBoolean(false, graph());
         }
+
+        if (x() instanceof AndNode && y().isConstant() && y().asConstant().asLong() == 0) {
+            return graph().unique(new IntegerTestNode(((AndNode) x()).x(), ((AndNode) x()).y()));
+        } else if (y() instanceof AndNode && x().isConstant() && x().asConstant().asLong() == 0) {
+            return graph().unique(new IntegerTestNode(((AndNode) y()).x(), ((AndNode) y()).y()));
+        }
         return super.canonical(tool);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Tue Feb 05 15:53:21 2013 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class IntegerTestNode extends BooleanNode implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode x;
+    @Input private ValueNode y;
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public ValueNode y() {
+        return y;
+    }
+
+    /**
+     * Constructs a new Test instruction.
+     * 
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public IntegerTestNode(ValueNode x, ValueNode y) {
+        super(StampFactory.condition());
+        assert (x == null && y == null) || x.kind() == y.kind();
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+    }
+
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            return ConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph());
+        }
+        if ((x().integerStamp().mask() & y().integerStamp().mask()) == 0) {
+            return ConstantNode.forBoolean(true, graph());
+        }
+        return this;
+    }
+}