Mercurial > hg > graal-compiler
changeset 7727:be7b98533b17
Merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Tue, 05 Feb 2013 16:39:45 +0100 |
parents | f629d4a264c6 (diff) fec77d5cd187 (current diff) |
children | 77c86cf33685 |
files | |
diffstat | 18 files changed, 354 insertions(+), 112 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Feb 05 16:39:45 2013 +0100 @@ -2863,6 +2863,12 @@ emitArith(0x85, 0xC0, dst, src); } + public final void testq(Register dst, Address src) { + prefixq(src, dst); + emitByte(0x85); + emitOperandHelper(dst, src); + } + public final void xaddq(Address dst, Register src) { prefixq(dst, src); emitByte(0x0F);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Feb 05 16:39:45 2013 +0100 @@ -229,7 +229,7 @@ } @Override - public void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { + public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { boolean mirrored = emitCompare(left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; switch (left.getKind().getStackKind()) { @@ -248,7 +248,13 @@ } @Override - public Variable emitCMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { + public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info) { + emitIntegerTest(left, right); + append(new BranchOp(negated ? Condition.NE : Condition.EQ, label, info)); + } + + @Override + public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { boolean mirrored = emitCompare(left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; @@ -263,11 +269,29 @@ case Double: append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); break; - + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); } return result; } + @Override + public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { + emitIntegerTest(left, right); + Variable result = newVariable(trueValue.getKind()); + append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); + return result; + } + + private void emitIntegerTest(Value a, Value b) { + assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long; + if (LIRValueUtil.isVariable(b)) { + append(new AMD64TestOp(load(b), loadNonConst(a))); + } else { + append(new AMD64TestOp(load(a), loadNonConst(b))); + } + } + /** * This method emits the compare instruction, and may reorder the operands. It returns true if * it did so.
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Tue Feb 05 16:39:45 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.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Feb 05 16:39:45 2013 +0100 @@ -30,6 +30,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -184,8 +185,8 @@ public void testInstanceOf() { ReturnNode returnNode = testEscapeAnalysis("testInstanceOfSnippet", null, false); ValueNode result = returnNode.result(); - Assert.assertTrue(result instanceof MaterializeNode); - Assert.assertEquals(Constant.TRUE, ((MaterializeNode) result).condition().asConstant()); + Assert.assertTrue(result instanceof ConditionalNode); + Assert.assertEquals(Constant.TRUE, ((ConditionalNode) result).condition().asConstant()); } public boolean testInstanceOfSnippet() {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Feb 05 16:39:45 2013 +0100 @@ -612,6 +612,8 @@ emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, info); } else if (node instanceof ConstantNode) { emitConstantBranch(((ConstantNode) node).asConstant().asBoolean(), trueSuccessor, falseSuccessor, info); + } else if (node instanceof IntegerTestNode) { + emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor, info); } else { throw GraalInternalError.unimplemented(node.toString()); } @@ -619,23 +621,34 @@ private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) { if (falseSuccessor != null) { - emitBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor, info); + emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor, info); if (trueSuccessor != null) { emitJump(trueSuccessor, null); } } else { - emitBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, info); + emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, info); } } public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRFrameState info) { if (falseSuccessorBlock != null) { - emitBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info); + emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info); if (trueSuccessorBlock != null) { emitJump(trueSuccessorBlock, null); } } else { - emitBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessorBlock, info); + emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessorBlock, info); + } + } + + public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRFrameState info) { + if (falseSuccessorBlock != null) { + emitIntegerTestBranch(operand(test.x()), operand(test.y()), true, falseSuccessorBlock, info); + if (trueSuccessorBlock != null) { + emitJump(trueSuccessorBlock, null); + } + } else { + emitIntegerTestBranch(operand(test.x()), operand(test.y()), false, trueSuccessorBlock, info); } } @@ -655,33 +668,31 @@ public Variable emitConditional(BooleanNode node, Value trueValue, Value falseValue) { if (node instanceof IsNullNode) { - return emitNullCheckConditional((IsNullNode) node, trueValue, falseValue); + IsNullNode isNullNode = (IsNullNode) node; + return emitConditionalMove(operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue); } else if (node instanceof CompareNode) { - return emitCompareConditional((CompareNode) node, trueValue, falseValue); + CompareNode compare = (CompareNode) node; + return emitConditionalMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); } else if (node instanceof ConstantNode) { - return emitConstantConditional(((ConstantNode) node).asConstant().asBoolean(), trueValue, falseValue); + ConstantNode constantNode = (ConstantNode) node; + return emitMove(constantNode.asConstant().asBoolean() ? trueValue : falseValue); + } else if (node instanceof IntegerTestNode) { + IntegerTestNode test = (IntegerTestNode) node; + return emitIntegerTestMove(operand(test.x()), operand(test.y()), trueValue, falseValue); } else { throw GraalInternalError.unimplemented(node.toString()); } } - private Variable emitNullCheckConditional(IsNullNode node, Value trueValue, Value falseValue) { - return emitCMove(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue); - } - - private Variable emitConstantConditional(boolean value, Value trueValue, Value falseValue) { - return emitMove(value ? trueValue : falseValue); - } - - private Variable emitCompareConditional(CompareNode compare, Value trueValue, Value falseValue) { - return emitCMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); - } - public abstract void emitJump(LabelRef label, LIRFrameState info); - public abstract void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info); + public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info); + + public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info); - public abstract Variable emitCMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); + public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); + + public abstract Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue); @Override public void emitInvoke(Invoke x) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSubstitutions.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSubstitutions.java Tue Feb 05 16:39:45 2013 +0100 @@ -27,7 +27,7 @@ import java.lang.reflect.*; -import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.snippets.*; import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; import com.oracle.graal.word.*; @@ -113,6 +113,6 @@ @MethodSubstitution(isStatic = false) public static boolean isInstance(final Class<?> thisObj, Object obj) { - return !thisObj.isPrimitive() && MaterializeNode.isInstance(thisObj, obj); + return !thisObj.isPrimitive() && ConditionalNode.materializeIsInstance(thisObj, obj); } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Feb 05 16:39:45 2013 +0100 @@ -708,7 +708,8 @@ if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; InstanceOfNode instanceOfNode = new InstanceOfNode((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); - frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode)))); + ConditionalNode conditional = currentGraph.unique(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph))); + frameState.ipush(append(conditional)); } else { BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode()); DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java Tue Feb 05 16:39:45 2013 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011, 2012, 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.lir.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; + +//@formatter:off +public class AMD64TestOp extends AMD64LIRInstruction { + + @Use({REG}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + + public AMD64TestOp(Value x, Value y) { + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + emit(tasm, masm, x, y); + } + + @Override + protected void verify() { + super.verify(); + assert (x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : x + " " + y; + } + + public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value x, Value y) { + if (isRegister(y)) { + switch (x.getKind()) { + case Int: masm.testl(asIntReg(x), asIntReg(y)); break; + case Long: masm.testq(asLongReg(x), asLongReg(y)); break; + default: throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (x.getKind()) { + case Int: masm.testl(asIntReg(x), tasm.asIntConst(y)); break; + case Long: masm.testq(asLongReg(x), tasm.asIntConst(y)); break; + default: throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (x.getKind()) { + case Int: masm.testl(asIntReg(x), tasm.asIntAddr(y)); break; + case Long: masm.testq(asLongReg(x), tasm.asLongAddr(y)); break; + default: throw GraalInternalError.shouldNotReachHere(); + } + } + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Feb 05 16:39:45 2013 +0100 @@ -191,7 +191,7 @@ return false; } if (trueValue.isConstant() && falseValue.isConstant()) { - MaterializeNode materialize = MaterializeNode.create(condition(), trueValue, falseValue); + ConditionalNode materialize = graph().unique(new ConditionalNode(condition(), trueValue, falseValue)); ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize); removeEmptyIf(tool); return true;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java Tue Feb 05 15:27:40 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009, 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; - -import static com.oracle.graal.nodes.calc.CompareNode.*; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; - -public final class MaterializeNode extends ConditionalNode { - - private MaterializeNode(Condition condition, ValueNode x, ValueNode y) { - this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph())); - } - - private MaterializeNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { - super(condition, trueValue, falseValue); - } - - private MaterializeNode(ValueNode type, ValueNode object) { - super(type.graph().add(new InstanceOfDynamicNode(type, object)), ConstantNode.forInt(1, type.graph()), ConstantNode.forInt(0, type.graph())); - } - - public static MaterializeNode create(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { - Graph graph = condition.graph(); - MaterializeNode result = new MaterializeNode(condition, trueValue, falseValue); - return graph.unique(result); - - } - - public static MaterializeNode create(BooleanNode condition) { - return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph())); - } - - @NodeIntrinsic - public static native boolean materialize(@ConstantNodeParameter Condition condition, int x, int y); - - @NodeIntrinsic - public static native boolean materialize(@ConstantNodeParameter Condition condition, long x, long y); - - @NodeIntrinsic - public static native boolean isInstance(Class mirror, Object object); -}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Tue Feb 05 16:39:45 2013 +0100 @@ -22,15 +22,18 @@ */ package com.oracle.graal.nodes.calc; +import static com.oracle.graal.nodes.calc.CompareNode.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; /** * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note * that these nodes are not built directly from the bytecode but are introduced by canonicalization. */ -public class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable, Negatable { +public final class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable, Negatable { @Input private BooleanNode condition; @@ -44,6 +47,11 @@ this.condition = condition; } + @Override + public boolean inferStamp() { + return updateStamp(x().stamp().meet(y().stamp())); + } + public ValueNode trueValue() { return x(); } @@ -91,4 +99,21 @@ ((StructuredGraph) graph()).replaceFloating(this, replacement); return replacement; } + + private ConditionalNode(Condition condition, ValueNode x, ValueNode y) { + this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph())); + } + + private ConditionalNode(ValueNode type, ValueNode object) { + this(type.graph().add(new InstanceOfDynamicNode(type, object)), ConstantNode.forInt(1, type.graph()), ConstantNode.forInt(0, type.graph())); + } + + @NodeIntrinsic + public static native boolean materializeCondition(@ConstantNodeParameter Condition condition, int x, int y); + + @NodeIntrinsic + public static native boolean materializeCondition(@ConstantNodeParameter Condition condition, long x, long y); + + @NodeIntrinsic + public static native boolean materializeIsInstance(Class mirror, Object object); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Tue Feb 05 16:39:45 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 16:39:45 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; + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Tue Feb 05 16:39:45 2013 +0100 @@ -61,8 +61,8 @@ lessComp = graph.unique(new IntegerLessThanNode(x(), y())); } - MaterializeNode equalValue = MaterializeNode.create(equalComp, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph)); - MaterializeNode value = MaterializeNode.create(lessComp, ConstantNode.forInt(-1, graph), equalValue); + ConditionalNode equalValue = graph.unique(new ConditionalNode(equalComp, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph))); + ConditionalNode value = graph.unique(new ConditionalNode(lessComp, ConstantNode.forInt(-1, graph), equalValue)); graph.replaceFloating(this, value); }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Feb 05 16:39:45 2013 +0100 @@ -496,8 +496,8 @@ for (PhiNode phi : endNode.merge().phis()) { int index = endNode.merge().phiPredecessorIndex(endNode); ValueNode value = phi.valueAt(index); - if (value instanceof MaterializeNode) { - MaterializeNode materialize = (MaterializeNode) value; + if (value instanceof ConditionalNode) { + ConditionalNode materialize = (ConditionalNode) value; BooleanNode compare = materialize.condition(); ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue());
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java Tue Feb 05 16:39:45 2013 +0100 @@ -172,7 +172,7 @@ // Can simply use the phi result if the same materialized values are expected. return result; } else { - return MaterializeNode.create(asCondition(trueValue), t, f); + return t.graph().unique(new ConditionalNode(asCondition(trueValue), t, f)); } } }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSubstitutions.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSubstitutions.java Tue Feb 05 16:39:45 2013 +0100 @@ -22,7 +22,7 @@ */ package com.oracle.graal.snippets; -import static com.oracle.graal.nodes.MaterializeNode.*; +import static com.oracle.graal.nodes.calc.ConditionalNode.*; import static com.oracle.graal.nodes.calc.Condition.*; import com.oracle.graal.api.code.*; @@ -38,12 +38,12 @@ @MethodSubstitution public static boolean aboveThan(int a, int b) { - return materialize(BT, b, a); + return materializeCondition(BT, b, a); } @MethodSubstitution public static boolean aboveOrEqual(int a, int b) { - return !materialize(BT, a, b); + return !materializeCondition(BT, a, b); } /** @@ -51,7 +51,7 @@ */ @MethodSubstitution public static boolean belowThan(int a, int b) { - return materialize(BT, a, b); + return materializeCondition(BT, a, b); } /** @@ -59,7 +59,7 @@ */ @MethodSubstitution public static boolean belowOrEqual(int a, int b) { - return !materialize(BT, b, a); + return !materializeCondition(BT, b, a); } /** @@ -67,7 +67,7 @@ */ @MethodSubstitution public static boolean aboveThan(long a, long b) { - return materialize(BT, b, a); + return materializeCondition(BT, b, a); } /** @@ -75,7 +75,7 @@ */ @MethodSubstitution public static boolean aboveOrEqual(long a, long b) { - return !materialize(BT, a, b); + return !materializeCondition(BT, a, b); } /** @@ -83,7 +83,7 @@ */ @MethodSubstitution public static boolean belowThan(long a, long b) { - return materialize(BT, a, b); + return materializeCondition(BT, a, b); } /** @@ -91,7 +91,7 @@ */ @MethodSubstitution public static boolean belowOrEqual(long a, long b) { - return !materialize(BT, b, a); + return !materializeCondition(BT, b, a); } /**
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Tue Feb 05 15:27:40 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Tue Feb 05 16:39:45 2013 +0100 @@ -248,7 +248,7 @@ } else { comparison = new IntegerLessThanNode(a, b); } - MaterializeNode materialize = MaterializeNode.create(graph.unique(comparison)); + ConditionalNode materialize = graph.unique(new ConditionalNode(graph.unique(comparison), ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph))); ValueNode op; if (condition.canonicalNegate()) {