# HG changeset patch # User Lukas Stadler # Date 1360076001 -3600 # Node ID f629d4a264c67d464309b7159649c9855f942d73 # Parent 301cff1a99d12d16d573069fffeffc09eb018087 new IntegerTestNode, unit tests for IntegerTestNode canonicalization diff -r 301cff1a99d1 -r f629d4a264c6 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java --- 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; + } + } + } diff -r 301cff1a99d1 -r f629d4a264c6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- 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); } } diff -r 301cff1a99d1 -r f629d4a264c6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- /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; + } +}