# HG changeset patch # User Doug Simon # Date 1403710465 -7200 # Node ID e34bb128f22758cadecd55b18178527ac462e5ba # Parent a47528fb2ea09eebc24628d988ad0a8f36b71177# Parent cc4b4fd5c484513f74f72acfeb19085636761cc4 Merge. diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Wed Jun 25 17:34:25 2014 +0200 @@ -64,8 +64,8 @@ FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node; if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) { FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode; - if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && !hasOperand(otherDivRem)) { - Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), state((DeoptimizingNode) valueNode)); + if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) { + Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode)); if (divRem instanceof IntegerDivNode) { setResult(divRem, results[0]); setResult(otherDivRem, results[1]); @@ -136,7 +136,7 @@ // emitCompareBranchMemory expects the memory on the right, so mirror the condition if // that's not true. It might be mirrored again the actual compare is emitted but that's // ok. - Condition finalCondition = uncast(compare.x()) == access ? cond.mirror() : cond; + Condition finalCondition = uncast(compare.getX()) == access ? cond.mirror() : cond; return new ComplexMatchResult() { public Value evaluate(NodeLIRBuilder builder) { LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor()); @@ -364,8 +364,8 @@ @MatchRule("(Or (LeftShift=lshift value Constant) (UnsignedRightShift=rshift value Constant))") public ComplexMatchResult rotateLeftConstant(LeftShiftNode lshift, UnsignedRightShiftNode rshift) { - if ((lshift.getShiftAmountMask() & (lshift.y().asConstant().asInt() + rshift.y().asConstant().asInt())) == 0) { - return builder -> getLIRGeneratorTool().emitRol(operand(lshift.x()), operand(lshift.y())); + if ((lshift.getShiftAmountMask() & (lshift.getY().asConstant().asInt() + rshift.getY().asConstant().asInt())) == 0) { + return builder -> getLIRGeneratorTool().emitRol(operand(lshift.getX()), operand(lshift.getY())); } return null; } diff -r a47528fb2ea0 -r e34bb128f227 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 Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Wed Jun 25 17:34:25 2014 +0200 @@ -103,7 +103,7 @@ IntegerTestNode test = (IntegerTestNode) conditional.condition(); ParameterNode param0 = graph.getParameter(0); ParameterNode param1 = graph.getParameter(1); - assertTrue((test.x() == param0 && test.y() == param1) || (test.x() == param1 && test.y() == param0)); + assertTrue((test.getX() == param0 && test.getY() == param1) || (test.getX() == param1 && test.getY() == param0)); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Jun 25 17:34:25 2014 +0200 @@ -25,10 +25,9 @@ import org.junit.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.loop.phases.*; -import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; @@ -279,7 +278,7 @@ @SuppressWarnings("unused") public static void testNewNodeSnippet() { - new IntegerAddNode(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null); + new ValueAnchorNode(null); } /** diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Jun 25 17:34:25 2014 +0200 @@ -408,17 +408,17 @@ } private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { - PlatformKind kind = gen.getLIRKind(node.object().stamp()).getPlatformKind(); - gen.emitCompareBranch(kind, operand(node.object()), kind.getDefaultValue(), Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability); + PlatformKind kind = gen.getLIRKind(node.getValue().stamp()).getPlatformKind(); + gen.emitCompareBranch(kind, operand(node.getValue()), kind.getDefaultValue(), Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability); } public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { - PlatformKind kind = gen.getLIRKind(compare.x().stamp()).getPlatformKind(); - gen.emitCompareBranch(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability); + PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind(); + gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability); } public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { - gen.emitIntegerTestBranch(operand(test.x()), operand(test.y()), trueSuccessor, falseSuccessor, trueSuccessorProbability); + gen.emitIntegerTestBranch(operand(test.getX()), operand(test.getY()), trueSuccessor, falseSuccessor, trueSuccessorProbability); } public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) { @@ -436,17 +436,17 @@ public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) { if (node instanceof IsNullNode) { IsNullNode isNullNode = (IsNullNode) node; - PlatformKind kind = gen.getLIRKind(isNullNode.object().stamp()).getPlatformKind(); - return gen.emitConditionalMove(kind, operand(isNullNode.object()), kind.getDefaultValue(), Condition.EQ, false, trueValue, falseValue); + PlatformKind kind = gen.getLIRKind(isNullNode.getValue().stamp()).getPlatformKind(); + return gen.emitConditionalMove(kind, operand(isNullNode.getValue()), kind.getDefaultValue(), Condition.EQ, false, trueValue, falseValue); } else if (node instanceof CompareNode) { CompareNode compare = (CompareNode) node; - PlatformKind kind = gen.getLIRKind(compare.x().stamp()).getPlatformKind(); - return gen.emitConditionalMove(kind, operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); + PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind(); + return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); } else if (node instanceof LogicConstantNode) { return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue); } else if (node instanceof IntegerTestNode) { IntegerTestNode test = (IntegerTestNode) node; - return gen.emitIntegerTestMove(operand(test.x()), operand(test.y()), trueValue, falseValue); + return gen.emitIntegerTestMove(operand(test.getX()), operand(test.getY()), trueValue, falseValue); } else { throw GraalInternalError.unimplemented(node.toString()); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Jun 25 17:34:25 2014 +0200 @@ -28,6 +28,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.GraphEvent.NodeEvent; import com.oracle.graal.graph.Node.ValueNumberable; +import com.oracle.graal.graph.NodeClass.NodeClassIterator; +import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.graph.iterators.*; /** @@ -279,6 +281,22 @@ return add(node); } + public T addOrUniqueWithInputs(T node) { + NodeClassIterator iterator = node.inputs().iterator(); + while (iterator.hasNext()) { + Position pos = iterator.nextPosition(); + Node input = pos.get(node); + if (input != null && !input.isAlive()) { + assert !input.isDeleted(); + pos.initialize(node, addOrUniqueWithInputs(input)); + } + } + if (node.getNodeClass().valueNumberable()) { + return uniqueHelper(node, true); + } + return add(node); + } + private T addHelper(T node) { node.initialize(this); return node; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Jun 25 17:34:25 2014 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.CanonicalizeMethod; /** * Metadata for every {@link Node} type. The metadata includes: @@ -102,7 +103,7 @@ /** * Determines if this node type implements {@link Canonicalizable}. */ - private final boolean isCanonicalizable; + private final CanonicalizeMethod canonicalizeMethod; /** * Determines if this node type implements {@link Simplifiable}. @@ -116,7 +117,18 @@ public NodeClass(Class clazz, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); - this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); + if (Canonicalizable.Unary.class.isAssignableFrom(clazz)) { + assert !Canonicalizable.Binary.class.isAssignableFrom(clazz) && !Canonicalizable.class.isAssignableFrom(clazz) : clazz; + this.canonicalizeMethod = CanonicalizeMethod.UNARY; + } else if (Canonicalizable.Binary.class.isAssignableFrom(clazz)) { + assert !Canonicalizable.class.isAssignableFrom(clazz) : clazz; + this.canonicalizeMethod = CanonicalizeMethod.BINARY; + } else if (Canonicalizable.class.isAssignableFrom(clazz)) { + this.canonicalizeMethod = CanonicalizeMethod.BASE; + } else { + this.canonicalizeMethod = null; + } + this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); FieldScanner scanner = new FieldScanner(calcOffset); @@ -249,8 +261,8 @@ /** * Determines if this node type implements {@link Canonicalizable}. */ - public boolean isCanonicalizable() { - return isCanonicalizable; + public CanonicalizeMethod getCanonicalizeMethod() { + return canonicalizeMethod; } /** @@ -377,6 +389,10 @@ node.getNodeClass().set(node, this, value); } + void initialize(Node node, Node value) { + node.getNodeClass().initializePosition(node, this, value); + } + public boolean isValidFor(Node node, Node from) { return node.getNodeClass().isValid(this, from.getNodeClass()); } @@ -1066,6 +1082,20 @@ } } + public void initializePosition(Node node, Position pos, Node x) { + long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()]; + if (pos.getSubIndex() == NOT_ITERABLE) { + assert x == null || fieldTypes.get((pos.isInput() ? inputOffsets : successorOffsets)[pos.getIndex()]).isAssignableFrom(x.getClass()) : this + ".set(node, pos, " + x + ")"; + putNode(node, offset, x); + } else { + NodeList list = getNodeList(node, offset); + while (list.size() <= pos.getSubIndex()) { + list.add(null); + } + list.initialize(pos.getSubIndex(), x); + } + } + public NodeClassIterable getInputIterable(final Node node) { assert getClazz().isInstance(node); return new NodeClassIterable() { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Jun 25 17:34:25 2014 +0200 @@ -154,6 +154,12 @@ return oldValue; } + void initialize(int index, T node) { + incModCount(); + assert index < size(); + nodes[index] = node; + } + void copy(NodeList other) { incModCount(); nodes = Arrays.copyOf(other.nodes, other.size); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,5 +26,25 @@ public interface Canonicalizable { + public enum CanonicalizeMethod { + BASE, + UNARY, + BINARY + } + Node canonical(CanonicalizerTool tool); + + public interface Unary { + T canonical(CanonicalizerTool tool, T forValue); + + T getValue(); + } + + public interface Binary { + T canonical(CanonicalizerTool tool, T forX, T forY); + + T getX(); + + T getY(); + } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Jun 25 17:34:25 2014 +0200 @@ -72,10 +72,10 @@ Value value = gen.load(operand(valueNode)); AMD64AddressValue address = makeCompressedAddress(compress, location); Condition cond = compare.condition(); - if (access == filterCompression(compare.x())) { + if (access == filterCompression(compare.getX())) { cond = cond.mirror(); } else { - assert access == filterCompression(compare.y()); + assert access == filterCompression(compare.getY()); } LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor()); @@ -253,7 +253,7 @@ @MatchRule("(If (FloatLessThan=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") public ComplexMatchResult ifCompareCompressedMemory(IfNode root, CompareNode compare, CompressionNode compress, ValueNode value, ConstantLocationNode location, Access access) { if (canFormCompressedMemory(compress, location)) { - PlatformKind cmpKind = gen.getLIRKind(compare.x().stamp()).getPlatformKind(); + PlatformKind cmpKind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind(); if (cmpKind instanceof Kind) { Kind kind = (Kind) cmpKind; return builder -> { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Wed Jun 25 17:34:25 2014 +0200 @@ -28,7 +28,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; /** * Extends {@link LIRFrameState} to handle {@link HotSpotMonitorValue}s correctly. @@ -40,19 +39,6 @@ } @Override - protected Value processValue(ValueProcedure proc, Value value) { - if (value instanceof HotSpotMonitorValue) { - HotSpotMonitorValue monitor = (HotSpotMonitorValue) value; - if (processed(monitor.getOwner())) { - monitor.setOwner(proc.doValue(monitor.getOwner(), OperandMode.ALIVE, STATE_FLAGS)); - } - return value; - } else { - return super.processValue(proc, value); - } - } - - @Override protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { if (value instanceof HotSpotMonitorValue) { HotSpotMonitorValue monitor = (HotSpotMonitorValue) value; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Jun 25 17:34:25 2014 +0200 @@ -386,7 +386,7 @@ ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE)); ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE)); - IntegerAddNode add = graph.unique(new IntegerAddNode(StampFactory.forKind(Kind.Long), read, counter.getIncrement())); + IntegerAddNode add = graph.unique(new IntegerAddNode(read, counter.getIncrement())); WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE)); graph.addBeforeFixed(counter, thread); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; @@ -32,10 +31,10 @@ /** * {@link MacroNode Macro node} for {@link Class#cast(Object)}. - * + * * @see ClassSubstitutions#cast(Class, Object) */ -public class ClassCastNode extends MacroNode implements Canonicalizable { +public class ClassCastNode extends MacroNode implements Canonicalizable.Binary { public ClassCastNode(Invoke invoke) { super(invoke); @@ -49,16 +48,21 @@ return arguments.get(1); } + public ValueNode getX() { + return getJavaClass(); + } + + public ValueNode getY() { + return getObject(); + } + @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode javaClass = getJavaClass(); - if (javaClass.isConstant()) { - ValueNode object = getObject(); - Class c = (Class) HotSpotObjectConstant.asObject(javaClass.asConstant()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forJavaClass, ValueNode forObject) { + if (forJavaClass.isConstant()) { + Class c = (Class) HotSpotObjectConstant.asObject(forJavaClass.asConstant()); if (c != null && !c.isPrimitive()) { HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c); - CheckCastNode checkcast = graph().add(new CheckCastNode(type, object, null, false)); - return checkcast; + return new CheckCastNode(type, forObject, null, false); } } return this; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -40,7 +40,7 @@ * Compress or uncompress an oop or metaspace pointer. */ @NodeInfo(nameTemplate = "{p#op/s}") -public final class CompressionNode extends ConvertNode implements LIRLowerable, Canonicalizable { +public final class CompressionNode extends ConvertNode implements LIRLowerable { private enum CompressionOp { Compress, @@ -151,11 +151,11 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - return ConstantNode.forConstant(stamp(), evalConst(getValue().asConstant()), tool.getMetaAccess(), graph()); - } else if (getValue() instanceof CompressionNode) { - CompressionNode other = (CompressionNode) getValue(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + return ConstantNode.forConstant(stamp(), evalConst(forValue.asConstant()), tool.getMetaAccess()); + } else if (forValue instanceof CompressionNode) { + CompressionNode other = (CompressionNode) forValue; if (op != other.op && encoding.equals(other.encoding)) { return other.getValue(); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jun 25 17:34:25 2014 +0200 @@ -223,7 +223,7 @@ protected Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) { if (replacer.instanceOf instanceof InstanceOfNode) { InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf; - ValueNode object = instanceOf.object(); + ValueNode object = instanceOf.getValue(); TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue()); final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type(); ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), instanceOf.graph()); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -461,52 +461,52 @@ @Override protected ValueNode genIntegerAdd(Kind kind, ValueNode x, ValueNode y) { - return new IntegerAddNode(StampFactory.forKind(kind), x, y); + return new IntegerAddNode(x, y); } @Override protected ValueNode genIntegerSub(Kind kind, ValueNode x, ValueNode y) { - return new IntegerSubNode(StampFactory.forKind(kind), x, y); + return new IntegerSubNode(x, y); } @Override protected ValueNode genIntegerMul(Kind kind, ValueNode x, ValueNode y) { - return new IntegerMulNode(StampFactory.forKind(kind), x, y); + return new IntegerMulNode(x, y); } @Override protected ValueNode genFloatAdd(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) { - return new FloatAddNode(StampFactory.forKind(kind), x, y, isStrictFP); + return new FloatAddNode(x, y, isStrictFP); } @Override protected ValueNode genFloatSub(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) { - return new FloatSubNode(StampFactory.forKind(kind), x, y, isStrictFP); + return new FloatSubNode(x, y, isStrictFP); } @Override protected ValueNode genFloatMul(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) { - return new FloatMulNode(StampFactory.forKind(kind), x, y, isStrictFP); + return new FloatMulNode(x, y, isStrictFP); } @Override protected ValueNode genFloatDiv(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) { - return new FloatDivNode(StampFactory.forKind(kind), x, y, isStrictFP); + return new FloatDivNode(x, y, isStrictFP); } @Override protected ValueNode genFloatRem(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) { - return new FloatRemNode(StampFactory.forKind(kind), x, y, isStrictFP); + return new FloatRemNode(x, y, isStrictFP); } @Override protected ValueNode genIntegerDiv(Kind kind, ValueNode x, ValueNode y) { - return new IntegerDivNode(StampFactory.forKind(kind), x, y); + return new IntegerDivNode(x, y); } @Override protected ValueNode genIntegerRem(Kind kind, ValueNode x, ValueNode y) { - return new IntegerRemNode(StampFactory.forKind(kind), x, y); + return new IntegerRemNode(x, y); } @Override @@ -516,32 +516,32 @@ @Override protected ValueNode genLeftShift(Kind kind, ValueNode x, ValueNode y) { - return new LeftShiftNode(StampFactory.forKind(kind), x, y); + return new LeftShiftNode(x, y); } @Override protected ValueNode genRightShift(Kind kind, ValueNode x, ValueNode y) { - return new RightShiftNode(StampFactory.forKind(kind), x, y); + return new RightShiftNode(x, y); } @Override protected ValueNode genUnsignedRightShift(Kind kind, ValueNode x, ValueNode y) { - return new UnsignedRightShiftNode(StampFactory.forKind(kind), x, y); + return new UnsignedRightShiftNode(x, y); } @Override protected ValueNode genAnd(Kind kind, ValueNode x, ValueNode y) { - return new AndNode(StampFactory.forKind(kind), x, y); + return new AndNode(x, y); } @Override protected ValueNode genOr(Kind kind, ValueNode x, ValueNode y) { - return new OrNode(StampFactory.forKind(kind), x, y); + return new OrNode(x, y); } @Override protected ValueNode genXor(Kind kind, ValueNode x, ValueNode y) { - return new XorNode(StampFactory.forKind(kind), x, y); + return new XorNode(x, y); } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Jun 25 17:34:25 2014 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; /** * Base class to represent values that need to be stored in more than one register. @@ -55,10 +54,6 @@ valueClass = CompositeValueClass.get(getClass()); } - public final void forEachComponent(OperandMode mode, ValueProcedure proc) { - valueClass.forEachComponent(this, mode, proc); - } - public final void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { valueClass.forEachComponent(inst, this, mode, proc); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Jun 25 17:34:25 2014 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; /** * Lazily associated metadata for every {@link CompositeValue} type. The metadata includes: @@ -140,10 +139,6 @@ return str.toString(); } - public final void forEachComponent(CompositeValue obj, OperandMode mode, ValueProcedure proc) { - forEach(obj, directComponentCount, componentOffsets, mode, componentFlags, proc); - } - public final void forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, InstructionValueProcedure proc) { forEach(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jun 25 17:34:25 2014 +0200 @@ -31,7 +31,6 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; /** * This class represents garbage collection and deoptimization information attached to a LIR @@ -60,22 +59,6 @@ } /** - * Iterates the frame state and calls the {@link ValueProcedure} for every variable. - * - * @param proc The procedure called for variables. - */ - public void forEachState(ValueProcedure proc) { - for (BytecodeFrame cur = topFrame; cur != null; cur = cur.caller()) { - processValues(cur.values, proc); - } - if (virtualObjects != null) { - for (VirtualObject obj : virtualObjects) { - processValues(obj.getValues(), proc); - } - } - } - - /** * Iterates the frame state and calls the {@link InstructionValueProcedure} for every variable. * * @param proc The procedure called for variables. @@ -97,20 +80,6 @@ */ protected static final EnumSet STATE_FLAGS = EnumSet.of(OperandFlag.REG, OperandFlag.STACK); - protected void processValues(Value[] values, ValueProcedure proc) { - for (int i = 0; i < values.length; i++) { - Value value = values[i]; - values[i] = processValue(proc, value); - } - } - - protected Value processValue(ValueProcedure proc, Value value) { - if (processed(value)) { - return proc.doValue(value, OperandMode.ALIVE, STATE_FLAGS); - } - return value; - } - protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) { for (int i = 0; i < values.length; i++) { Value value = values[i]; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Jun 25 17:34:25 2014 +0200 @@ -46,36 +46,6 @@ * methods. Clients of the class must only call the doValue method that takes additional * parameters. */ - public abstract static class ValueProcedure { - - /** - * Iterator method to be overwritten. This version of the iterator does not take additional - * parameters to keep the signature short. - * - * @param value The value that is iterated. - * @return The new value to replace the value that was passed in. - */ - protected Value doValue(Value value) { - throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten"); - } - - /** - * Iterator method to be overwritten. This version of the iterator gets additional - * parameters about the processed value. - * - * @param value The value that is iterated. - * @param mode The operand mode for the value. - * @param flags A set of flags for the value. - * @return The new value to replace the value that was passed in. - */ - public Value doValue(Value value, OperandMode mode, EnumSet flags) { - return doValue(value); - } - } - - /** - * Similar to {@link ValueProcedure} but with an {@link LIRInstruction} parameter. - */ public abstract static class InstructionValueProcedure { /** @@ -105,6 +75,46 @@ } } + /** + * Similar to {@link InstructionValueProcedure} but without an {@link LIRInstruction} parameter. + */ + public abstract static class ValueProcedure extends InstructionValueProcedure { + + /** + * Iterator method to be overwritten. This version of the iterator does not take additional + * parameters to keep the signature short. + * + * @param value The value that is iterated. + * @return The new value to replace the value that was passed in. + */ + protected Value doValue(Value value) { + throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten"); + } + + /** + * Iterator method to be overwritten. This version of the iterator gets additional + * parameters about the processed value. + * + * @param value The value that is iterated. + * @param mode The operand mode for the value. + * @param flags A set of flags for the value. + * @return The new value to replace the value that was passed in. + */ + protected Value doValue(Value value, OperandMode mode, EnumSet flags) { + return doValue(value); + } + + @Override + final protected Value doValue(LIRInstruction instruction, Value value) { + throw GraalInternalError.shouldNotReachHere("This doValue() methods should never be called"); + } + + @Override + final public Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) { + return doValue(value, mode, flags); + } + } + public abstract static class StateProcedure { protected abstract void doState(LIRFrameState state); @@ -287,26 +297,6 @@ return false; } - public final void forEachInput(ValueProcedure proc) { - instructionClass.forEachUse(this, proc); - } - - public final void forEachAlive(ValueProcedure proc) { - instructionClass.forEachAlive(this, proc); - } - - public final void forEachTemp(ValueProcedure proc) { - instructionClass.forEachTemp(this, proc); - } - - public final void forEachOutput(ValueProcedure proc) { - instructionClass.forEachDef(this, proc); - } - - public final void forEachState(ValueProcedure proc) { - instructionClass.forEachState(this, proc); - } - public final void forEachInput(InstructionValueProcedure proc) { instructionClass.forEachUse(this, proc); } @@ -346,7 +336,7 @@ * clients can stop the iteration once a suitable hint has been found. * @return The non-null value returned by the procedure, or null. */ - public Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) { + public Value forEachRegisterHint(Value value, OperandMode mode, InstructionValueProcedure proc) { return instructionClass.forEachRegisterHint(this, mode, proc); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Jun 25 17:34:25 2014 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.StateProcedure; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; public class LIRInstructionClass extends LIRIntrospection { @@ -263,22 +262,6 @@ return false; } - public final void forEachUse(LIRInstruction obj, ValueProcedure proc) { - forEach(obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc); - } - - public final void forEachAlive(LIRInstruction obj, ValueProcedure proc) { - forEach(obj, directAliveCount, aliveOffsets, OperandMode.ALIVE, aliveFlags, proc); - } - - public final void forEachTemp(LIRInstruction obj, ValueProcedure proc) { - forEach(obj, directTempCount, tempOffsets, OperandMode.TEMP, tempFlags, proc); - } - - public final void forEachDef(LIRInstruction obj, ValueProcedure proc) { - forEach(obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc); - } - public final void forEachUse(LIRInstruction obj, InstructionValueProcedure proc) { forEach(obj, obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc); } @@ -295,15 +278,6 @@ forEach(obj, obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc); } - public final void forEachState(LIRInstruction obj, ValueProcedure proc) { - for (int i = 0; i < stateOffsets.length; i++) { - LIRFrameState state = getState(obj, stateOffsets[i]); - if (state != null) { - state.forEachState(proc); - } - } - } - public final void forEachState(LIRInstruction obj, InstructionValueProcedure proc) { for (int i = 0; i < stateOffsets.length; i++) { LIRFrameState state = getState(obj, stateOffsets[i]); @@ -322,7 +296,7 @@ } } - public final Value forEachRegisterHint(LIRInstruction obj, OperandMode mode, ValueProcedure proc) { + public final Value forEachRegisterHint(LIRInstruction obj, OperandMode mode, InstructionValueProcedure proc) { int hintDirectCount = 0; long[] hintOffsets = null; if (mode == OperandMode.USE) { @@ -338,7 +312,7 @@ for (int i = 0; i < hintOffsets.length; i++) { if (i < hintDirectCount) { Value hintValue = getValue(obj, hintOffsets[i]); - Value result = proc.doValue(hintValue, null, null); + Value result = proc.doValue(obj, hintValue, null, null); if (result != null) { return result; } @@ -346,7 +320,7 @@ Value[] hintValues = getValueArray(obj, hintOffsets[i]); for (int j = 0; j < hintValues.length; j++) { Value hintValue = hintValues[j]; - Value result = proc.doValue(hintValue, null, null); + Value result = proc.doValue(obj, hintValue, null, null); if (result != null) { return result; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Jun 25 17:34:25 2014 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; abstract class LIRIntrospection extends FieldIntrospection { @@ -120,33 +119,6 @@ } } - protected static void forEach(Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, ValueProcedure proc) { - for (int i = 0; i < offsets.length; i++) { - assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]); - - if (i < directCount) { - Value value = getValue(obj, offsets[i]); - if (value instanceof CompositeValue) { - CompositeValue composite = (CompositeValue) value; - composite.forEachComponent(mode, proc); - } else { - setValue(obj, offsets[i], proc.doValue(value, mode, flags[i])); - } - } else { - Value[] values = getValueArray(obj, offsets[i]); - for (int j = 0; j < values.length; j++) { - Value value = values[j]; - if (value instanceof CompositeValue) { - CompositeValue composite = (CompositeValue) value; - composite.forEachComponent(mode, proc); - } else { - values[j] = proc.doValue(value, mode, flags[i]); - } - } - } - } - } - protected static void forEach(LIRInstruction inst, Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, InstructionValueProcedure proc) { for (int i = 0; i < offsets.length; i++) { assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Wed Jun 25 17:34:25 2014 +0200 @@ -62,7 +62,7 @@ range = IntegerArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph)); } } - IntegerDivNode div = graph.add(new IntegerDivNode(iv.valueNode().stamp().unrestricted(), range, iv.strideNode())); + IntegerDivNode div = graph.add(new IntegerDivNode(range, iv.strideNode())); graph.addBeforeFixed(loop.entryPoint(), div); ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph); if (assumePositive) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Wed Jun 25 17:34:25 2014 +0200 @@ -72,7 +72,7 @@ @Override public long constantStride() { - if (value instanceof IntegerSubNode && base.valueNode() == value.y()) { + if (value instanceof IntegerSubNode && base.valueNode() == value.getY()) { return -base.constantStride(); } return base.constantStride(); @@ -85,7 +85,7 @@ @Override public ValueNode strideNode() { - if (value instanceof IntegerSubNode && base.valueNode() == value.y()) { + if (value instanceof IntegerSubNode && base.valueNode() == value.getY()) { return graph().unique(new NegateNode(base.strideNode())); } return base.strideNode(); @@ -116,10 +116,10 @@ return b + o; } if (value instanceof IntegerSubNode) { - if (base.valueNode() == value.x()) { + if (base.valueNode() == value.getX()) { return b - o; } else { - assert base.valueNode() == value.y(); + assert base.valueNode() == value.getY(); return o - b; } } @@ -131,10 +131,10 @@ return IntegerArithmeticNode.add(graph(), b, o); } if (value instanceof IntegerSubNode) { - if (base.valueNode() == value.x()) { + if (base.valueNode() == value.getX()) { return IntegerArithmeticNode.sub(graph(), b, o); } else { - assert base.valueNode() == value.y(); + assert base.valueNode() == value.getY(); return IntegerArithmeticNode.sub(graph(), o, b); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Wed Jun 25 17:34:25 2014 +0200 @@ -95,10 +95,10 @@ private ValueNode addSub(ValueNode op, ValueNode base) { if (op instanceof IntegerAddNode || op instanceof IntegerSubNode) { IntegerArithmeticNode aritOp = (IntegerArithmeticNode) op; - if (aritOp.x() == base && loop.isOutsideLoop(aritOp.y())) { - return aritOp.y(); - } else if (aritOp.y() == base && loop.isOutsideLoop(aritOp.x())) { - return aritOp.x(); + if (aritOp.getX() == base && loop.isOutsideLoop(aritOp.getY())) { + return aritOp.getY(); + } else if (aritOp.getY() == base && loop.isOutsideLoop(aritOp.getX())) { + return aritOp.getX(); } } return null; @@ -107,16 +107,16 @@ private ValueNode mul(ValueNode op, ValueNode base) { if (op instanceof IntegerMulNode) { IntegerMulNode mul = (IntegerMulNode) op; - if (mul.x() == base && loop.isOutsideLoop(mul.y())) { - return mul.y(); - } else if (mul.y() == base && loop.isOutsideLoop(mul.x())) { - return mul.x(); + if (mul.getX() == base && loop.isOutsideLoop(mul.getY())) { + return mul.getY(); + } else if (mul.getY() == base && loop.isOutsideLoop(mul.getX())) { + return mul.getX(); } } if (op instanceof LeftShiftNode) { LeftShiftNode shift = (LeftShiftNode) op; - if (shift.x() == base && shift.y().isConstant()) { - return ConstantNode.forInt(1 << shift.y().asConstant().asInt(), base.graph()); + if (shift.getX() == base && shift.getY().isConstant()) { + return ConstantNode.forInt(1 << shift.getY().asConstant().asInt(), base.graph()); } } return null; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Wed Jun 25 17:34:25 2014 +0200 @@ -141,11 +141,15 @@ if (!BinaryNode.canTryReassociate(binary)) { continue; } - BinaryNode result = BinaryNode.reassociate(binary, invariant); + BinaryNode result = BinaryNode.reassociate(binary, invariant, binary.getX(), binary.getY()); if (result != binary) { if (Debug.isLogEnabled()) { Debug.log("%s : Reassociated %s into %s", MetaUtil.format("%H::%n", graph.method()), binary, result); } + if (!result.isAlive()) { + assert !result.isDeleted(); + result = graph.addOrUniqueWithInputs(result); + } graph.replaceFloating(binary, result); } } @@ -177,17 +181,17 @@ Condition condition = null; InductionVariable iv = null; ValueNode limit = null; - if (isOutsideLoop(lessThan.x())) { - iv = getInductionVariables().get(lessThan.y()); + if (isOutsideLoop(lessThan.getX())) { + iv = getInductionVariables().get(lessThan.getY()); if (iv != null) { condition = lessThan.condition().mirror(); - limit = lessThan.x(); + limit = lessThan.getX(); } - } else if (isOutsideLoop(lessThan.y())) { - iv = getInductionVariables().get(lessThan.x()); + } else if (isOutsideLoop(lessThan.getY())) { + iv = getInductionVariables().get(lessThan.getX()); if (iv != null) { condition = lessThan.condition(); - limit = lessThan.y(); + limit = lessThan.getY(); } } if (condition == null) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -78,7 +78,7 @@ public void simplify(SimplifierTool tool) { while (condition instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition; - setCondition(negation.getInput()); + setCondition(negation.getValue()); negated = !negated; } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,22 +22,19 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; -public abstract class BinaryOpLogicNode extends LogicNode implements LIRLowerable, Canonicalizable { +public abstract class BinaryOpLogicNode extends LogicNode implements LIRLowerable, Canonicalizable.Binary { @Input private ValueNode x; @Input private ValueNode y; - public ValueNode x() { + public ValueNode getX() { return x; } - public ValueNode y() { + public ValueNode getY() { return y; } @@ -57,8 +54,6 @@ this.y = y; } - public abstract TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY); - @Override public boolean verify() { assertTrue(x.stamp().isCompatible(y.stamp()), "stamps not compatible: %s, %s", x.stamp(), y.stamp()); @@ -66,17 +61,6 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - switch (evaluate(tool.getConstantReflection(), x(), y())) { - case FALSE: - return LogicConstantNode.contradiction(graph()); - case TRUE: - return LogicConstantNode.tautology(graph()); - } - return this; - } - - @Override public void generate(NodeLIRBuilderTool gen) { } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -70,7 +70,7 @@ public Node canonical(CanonicalizerTool tool) { if (condition instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition; - setCondition(negation.getInput()); + setCondition(negation.getValue()); negated = !negated; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -114,10 +114,25 @@ } } + public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess) { + if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) { + return forInt(constant.asInt()); + } + if (constant.getKind() == Kind.Object) { + return new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)); + } else { + return createPrimitive(constant); + } + } + public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) { return graph.unique(new ConstantNode(constant, stamp.constant(constant, metaAccess))); } + public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess) { + return new ConstantNode(constant, stamp.constant(constant, metaAccess)); + } + /** * Returns a node for a Java primitive. */ @@ -127,6 +142,14 @@ } /** + * Returns a node for a Java primitive. + */ + public static ConstantNode forPrimitive(Constant constant) { + assert constant.getKind() != Kind.Object; + return forConstant(constant, null); + } + + /** * Returns a node for a primitive of a given type. */ public static ConstantNode forPrimitive(Stamp stamp, Constant constant, StructuredGraph graph) { @@ -141,6 +164,20 @@ } /** + * Returns a node for a primitive of a given type. + */ + public static ConstantNode forPrimitive(Stamp stamp, Constant constant) { + if (stamp instanceof IntegerStamp) { + assert constant.getKind().isNumericInteger() && stamp.getStackKind() == constant.getKind().getStackKind(); + IntegerStamp istamp = (IntegerStamp) stamp; + return forIntegerBits(istamp.getBits(), constant); + } else { + assert constant.getKind().isNumericFloat() && stamp.getStackKind() == constant.getKind(); + return forConstant(constant, null); + } + } + + /** * Returns a node for a double constant. * * @param d the double value for which to create the instruction @@ -151,6 +188,16 @@ } /** + * Returns a node for a double constant. + * + * @param d the double value for which to create the instruction + * @return a node for a double constant + */ + public static ConstantNode forDouble(double d) { + return createPrimitive(Constant.forDouble(d)); + } + + /** * Returns a node for a float constant. * * @param f the float value for which to create the instruction @@ -161,6 +208,16 @@ } /** + * Returns a node for a float constant. + * + * @param f the float value for which to create the instruction + * @return a node for a float constant + */ + public static ConstantNode forFloat(float f) { + return createPrimitive(Constant.forFloat(f)); + } + + /** * Returns a node for an long constant. * * @param i the long value for which to create the instruction @@ -171,6 +228,16 @@ } /** + * Returns a node for an long constant. + * + * @param i the long value for which to create the instruction + * @return a node for an long constant + */ + public static ConstantNode forLong(long i) { + return createPrimitive(Constant.forLong(i)); + } + + /** * Returns a node for an integer constant. * * @param i the integer value for which to create the instruction @@ -181,6 +248,16 @@ } /** + * Returns a node for an integer constant. + * + * @param i the integer value for which to create the instruction + * @return a node for an integer constant + */ + public static ConstantNode forInt(int i) { + return createPrimitive(Constant.forInt(i)); + } + + /** * Returns a node for a boolean constant. * * @param i the boolean value for which to create the instruction @@ -191,6 +268,16 @@ } /** + * Returns a node for a boolean constant. + * + * @param i the boolean value for which to create the instruction + * @return a node representing the boolean + */ + public static ConstantNode forBoolean(boolean i) { + return createPrimitive(Constant.forInt(i ? 1 : 0)); + } + + /** * Returns a node for a byte constant. * * @param i the byte value for which to create the instruction @@ -238,6 +325,20 @@ return forIntegerBits(bits, Constant.forPrimitiveInt(bits, value), graph); } + private static ConstantNode forIntegerBits(int bits, Constant constant) { + long value = constant.asLong(); + long bounds = SignExtendNode.signExtend(value, bits); + return new ConstantNode(constant, StampFactory.forInteger(bits, bounds, bounds)); + } + + /** + * Returns a node for a constant integer that's not directly representable as Java primitive + * (e.g. short). + */ + public static ConstantNode forIntegerBits(int bits, long value) { + return forIntegerBits(bits, Constant.forPrimitiveInt(bits, value)); + } + /** * Returns a node for a constant integer that's compatible to a given stamp. */ @@ -250,6 +351,18 @@ } } + /** + * Returns a node for a constant integer that's compatible to a given stamp. + */ + public static ConstantNode forIntegerStamp(Stamp stamp, long value) { + if (stamp instanceof IntegerStamp) { + IntegerStamp intStamp = (IntegerStamp) stamp; + return forIntegerBits(intStamp.getBits(), value); + } else { + return forIntegerKind(stamp.getStackKind(), value); + } + } + public static ConstantNode forIntegerKind(Kind kind, long value, StructuredGraph graph) { switch (kind) { case Byte: @@ -263,6 +376,19 @@ } } + public static ConstantNode forIntegerKind(Kind kind, long value) { + switch (kind) { + case Byte: + case Short: + case Int: + return createPrimitive(Constant.forInt((int) value)); + case Long: + return createPrimitive(Constant.forLong(value)); + default: + throw GraalInternalError.shouldNotReachHere("unknown kind " + kind); + } + } + public static ConstantNode forFloatingKind(Kind kind, double value, StructuredGraph graph) { switch (kind) { case Float: @@ -274,6 +400,17 @@ } } + public static ConstantNode forFloatingKind(Kind kind, double value) { + switch (kind) { + case Float: + return ConstantNode.forFloat((float) value); + case Double: + return ConstantNode.forDouble(value); + default: + throw GraalInternalError.shouldNotReachHere("unknown kind " + kind); + } + } + /** * Returns a node for a constant double that's compatible to a given stamp. */ @@ -281,6 +418,13 @@ return forFloatingKind(stamp.getStackKind(), value, graph); } + /** + * Returns a node for a constant double that's compatible to a given stamp. + */ + public static ConstantNode forFloatingStamp(Stamp stamp, double value) { + return forFloatingKind(stamp.getStackKind(), value); + } + public static ConstantNode defaultForKind(Kind kind, StructuredGraph graph) { switch (kind) { case Boolean: diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -103,7 +103,7 @@ public Node canonical(CanonicalizerTool tool) { if (condition() instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition(); - return graph().unique(new GuardNode(negation.getInput(), getAnchor(), reason, action, !negated, speculation)); + return graph().unique(new GuardNode(negation.getValue(), getAnchor(), reason, action, !negated, speculation)); } else if (condition() instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition(); if (c.getValue() != negated) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -147,7 +147,7 @@ setTrueSuccessor(null); setFalseSuccessor(null); LogicNegationNode negation = (LogicNegationNode) condition(); - IfNode newIfNode = graph().add(new IfNode(negation.getInput(), falseSucc, trueSucc, 1 - trueSuccessorProbability)); + IfNode newIfNode = graph().add(new IfNode(negation.getValue(), falseSucc, trueSucc, 1 - trueSuccessorProbability)); predecessor().replaceFirstSuccessor(this, newIfNode); GraphUtil.killWithUnusedFloatingInputs(this); return; @@ -259,7 +259,7 @@ assert trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty(); if (condition() instanceof IntegerLessThanNode) { IntegerLessThanNode lessThan = (IntegerLessThanNode) condition(); - Constant y = lessThan.y().stamp().asConstant(); + Constant y = lessThan.getY().stamp().asConstant(); if (y != null && y.asLong() == 0 && falseSuccessor().next() instanceof IfNode) { IfNode ifNode2 = (IfNode) falseSuccessor().next(); if (ifNode2.condition() instanceof IntegerLessThanNode) { @@ -271,24 +271,24 @@ * Convert x >= 0 && x < positive which is represented as !(x < 0) && x < * into an unsigned compare. */ - if (lessThan2.x() == lessThan.x() && lessThan2.y().stamp() instanceof IntegerStamp && ((IntegerStamp) lessThan2.y().stamp()).isPositive() && + if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp() instanceof IntegerStamp && ((IntegerStamp) lessThan2.getY().stamp()).isPositive() && sameDestination(trueSuccessor(), ifNode2.falseSuccessor)) { - below = graph().unique(new IntegerBelowThanNode(lessThan2.x(), lessThan2.y())); + below = graph().unique(new IntegerBelowThanNode(lessThan2.getX(), lessThan2.getY())); // swap direction BeginNode tmp = falseSucc; falseSucc = trueSucc; trueSucc = tmp; - } else if (lessThan2.y() == lessThan.x() && sameDestination(trueSuccessor(), ifNode2.trueSuccessor)) { + } else if (lessThan2.getY() == lessThan.getX() && sameDestination(trueSuccessor(), ifNode2.trueSuccessor)) { /* * Convert x >= 0 && x <= positive which is represented as !(x < 0) && * !( > x), into x <| positive + 1. This can only be done for * constants since there isn't a IntegerBelowEqualThanNode but that doesn't * appear to be interesting. */ - Constant positive = lessThan2.x().asConstant(); + Constant positive = lessThan2.getX().asConstant(); if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getKind().getMaxValue()) { ConstantNode newLimit = ConstantNode.forIntegerKind(positive.getKind(), positive.asLong() + 1, graph()); - below = graph().unique(new IntegerBelowThanNode(lessThan.x(), newLimit)); + below = graph().unique(new IntegerBelowThanNode(lessThan.getX(), newLimit)); } } if (below != null) { @@ -355,7 +355,7 @@ InstanceOfNode instanceOfA = (InstanceOfNode) a; if (b instanceof IsNullNode) { IsNullNode isNullNode = (IsNullNode) b; - if (isNullNode.object() == instanceOfA.object()) { + if (isNullNode.getValue() == instanceOfA.getValue()) { if (instanceOfA.profile() != null && instanceOfA.profile().getNullSeen() != TriState.FALSE) { instanceOfA.setProfile(new JavaTypeProfile(TriState.FALSE, instanceOfA.profile().getNotRecordedProbability(), instanceOfA.profile().getTypes())); } @@ -364,7 +364,7 @@ } } else if (b instanceof InstanceOfNode) { InstanceOfNode instanceOfB = (InstanceOfNode) b; - if (instanceOfA.object() == instanceOfB.object() && !instanceOfA.type().isInterface() && !instanceOfB.type().isInterface() && + if (instanceOfA.getValue() == instanceOfB.getValue() && !instanceOfA.type().isInterface() && !instanceOfB.type().isInterface() && !instanceOfA.type().isAssignableFrom(instanceOfB.type()) && !instanceOfB.type().isAssignableFrom(instanceOfA.type())) { // Two instanceof on the same value with mutually exclusive types. JavaTypeProfile profileA = instanceOfA.profile(); @@ -425,9 +425,9 @@ } Condition comparableCondition = null; Condition conditionB = compareB.condition(); - if (compareB.x() == compareA.x() && compareB.y() == compareA.y()) { + if (compareB.getX() == compareA.getX() && compareB.getY() == compareA.getY()) { comparableCondition = conditionB; - } else if (compareB.x() == compareA.y() && compareB.y() == compareA.x()) { + } else if (compareB.getX() == compareA.getY() && compareB.getY() == compareA.getX()) { comparableCondition = conditionB.mirror(); } @@ -440,13 +440,13 @@ } } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) { boolean canSwap = false; - if ((compareA.x() == compareB.x() && valuesDistinct(constantReflection, compareA.y(), compareB.y()))) { + if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) { canSwap = true; - } else if ((compareA.x() == compareB.y() && valuesDistinct(constantReflection, compareA.y(), compareB.x()))) { + } else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) { canSwap = true; - } else if ((compareA.y() == compareB.x() && valuesDistinct(constantReflection, compareA.x(), compareB.y()))) { + } else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) { canSwap = true; - } else if ((compareA.y() == compareB.y() && valuesDistinct(constantReflection, compareA.x(), compareB.x()))) { + } else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) { canSwap = true; } @@ -645,7 +645,7 @@ return false; } Node singleUsage = mergeUsages.first(); - if (!(singleUsage instanceof ValuePhiNode) || (singleUsage != compare.x() && singleUsage != compare.y())) { + if (!(singleUsage instanceof ValuePhiNode) || (singleUsage != compare.getX() && singleUsage != compare.getY())) { return false; } @@ -664,8 +664,8 @@ List mergePredecessors = merge.cfgPredecessors().snapshot(); assert phi.valueCount() == merge.forwardEndCount(); - Constant[] xs = constantValues(compare.x(), merge, false); - Constant[] ys = constantValues(compare.y(), merge, false); + Constant[] xs = constantValues(compare.getX(), merge, false); + Constant[] ys = constantValues(compare.getY(), merge, false); if (xs == null || ys == null) { return false; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -40,7 +40,7 @@ /** * Returns a node for a boolean constant. - * + * * @param v the boolean value for which to create the instruction * @param graph * @return a node representing the boolean @@ -50,6 +50,16 @@ } /** + * Returns a node for a boolean constant. + * + * @param v the boolean value for which to create the instruction + * @return a node representing the boolean + */ + public static LogicConstantNode forBoolean(boolean v) { + return new LogicConstantNode(v); + } + + /** * Gets a constant for {@code true}. */ public static LogicConstantNode tautology(Graph graph) { @@ -63,6 +73,20 @@ return forBoolean(false, graph); } + /** + * Gets a constant for {@code true}. + */ + public static LogicConstantNode tautology() { + return forBoolean(true); + } + + /** + * Gets a constant for {@code false}. + */ + public static LogicConstantNode contradiction() { + return forBoolean(false); + } + public boolean getValue() { return value; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -28,22 +28,22 @@ /** * Logic node that negates its argument. */ -public class LogicNegationNode extends LogicNode implements Canonicalizable { +public class LogicNegationNode extends LogicNode implements Canonicalizable.Unary { - @Input(InputType.Condition) private LogicNode input; + @Input(InputType.Condition) private LogicNode value; - public LogicNegationNode(LogicNode input) { - this.input = input; + public LogicNegationNode(LogicNode value) { + this.value = value; } - public LogicNode getInput() { - return input; + public LogicNode getValue() { + return value; } @Override - public Node canonical(CanonicalizerTool tool) { - if (input instanceof LogicNegationNode) { - return ((LogicNegationNode) input).getInput(); + public LogicNode canonical(CanonicalizerTool tool, LogicNode forValue) { + if (forValue instanceof LogicNegationNode) { + return ((LogicNegationNode) forValue).getValue(); } else { return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -243,10 +243,10 @@ long increment = NO_INCREMENT; if (input != null && input instanceof IntegerAddNode) { IntegerAddNode add = (IntegerAddNode) input; - if (add.x() == phi && add.y().isConstant()) { - increment = add.y().asConstant().asLong(); - } else if (add.y() == phi && add.x().isConstant()) { - increment = add.x().asConstant().asLong(); + if (add.getX() == phi && add.getY().isConstant()) { + increment = add.getY().asConstant().asLong(); + } else if (add.getY() == phi && add.getX().isConstant()) { + increment = add.getX().asConstant().asLong(); } } else if (input == phi) { increment = 0; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; -public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable { +public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable.Binary { @Input(InputType.Condition) private LogicNode x; @Input(InputType.Condition) private LogicNode y; @@ -65,36 +65,40 @@ return shortCircuitProbability; } - protected ShortCircuitOrNode canonicalizeNegation() { - LogicNode xCond = x; + protected ShortCircuitOrNode canonicalizeNegation(LogicNode forX, LogicNode forY) { + LogicNode xCond = forX; boolean xNeg = xNegated; while (xCond instanceof LogicNegationNode) { - xCond = ((LogicNegationNode) xCond).getInput(); + xCond = ((LogicNegationNode) xCond).getValue(); xNeg = !xNeg; } - LogicNode yCond = y; + LogicNode yCond = forY; boolean yNeg = yNegated; while (yCond instanceof LogicNegationNode) { - yCond = ((LogicNegationNode) yCond).getInput(); + yCond = ((LogicNegationNode) yCond).getValue(); yNeg = !yNeg; } - if (xCond != x || yCond != y) { - return graph().unique(new ShortCircuitOrNode(xCond, xNeg, yCond, yNeg, shortCircuitProbability)); + if (xCond != forX || yCond != forY) { + return new ShortCircuitOrNode(xCond, xNeg, yCond, yNeg, shortCircuitProbability); } else { - return null; + return this; } } @Override public Node canonical(CanonicalizerTool tool) { - ShortCircuitOrNode ret = canonicalizeNegation(); - if (ret != null) { + return canonical(tool, getX(), getY()); + } + + public LogicNode canonical(CanonicalizerTool tool, LogicNode forX, LogicNode forY) { + ShortCircuitOrNode ret = canonicalizeNegation(forX, forY); + if (ret != this) { return ret; } - if (getX() == getY()) { + if (forX == forY) { // @formatter:off // a || a = a // a || !a = true @@ -104,40 +108,40 @@ if (isXNegated()) { if (isYNegated()) { // !a || !a = !a - return graph().unique(new LogicNegationNode(getX())); + return new LogicNegationNode(forX); } else { // !a || a = true - return LogicConstantNode.tautology(graph()); + return LogicConstantNode.tautology(); } } else { if (isYNegated()) { // a || !a = true - return LogicConstantNode.tautology(graph()); + return LogicConstantNode.tautology(); } else { // a || a = a - return getX(); + return forX; } } } - if (getX() instanceof LogicConstantNode) { - if (((LogicConstantNode) getX()).getValue() ^ isXNegated()) { - return LogicConstantNode.tautology(graph()); + if (forX instanceof LogicConstantNode) { + if (((LogicConstantNode) forX).getValue() ^ isXNegated()) { + return LogicConstantNode.tautology(); } else { if (isYNegated()) { - return graph().unique(new LogicNegationNode(getY())); + return new LogicNegationNode(forY); } else { - return getY(); + return forY; } } } - if (getY() instanceof LogicConstantNode) { - if (((LogicConstantNode) getY()).getValue() ^ isYNegated()) { - return LogicConstantNode.tautology(graph()); + if (forY instanceof LogicConstantNode) { + if (((LogicConstantNode) forY).getValue() ^ isYNegated()) { + return LogicConstantNode.tautology(); } else { if (isXNegated()) { - return graph().unique(new LogicNegationNode(getX())); + return new LogicNegationNode(forX); } else { - return getX(); + return forX; } } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -35,7 +35,7 @@ /** * A node that attaches a type profile to a proxied input node. */ -public final class TypeProfileProxyNode extends UnaryNode implements Canonicalizable, IterableNodeType, ValueProxy { +public final class TypeProfileProxyNode extends UnaryNode implements IterableNodeType, ValueProxy { private final JavaTypeProfile profile; private transient ResolvedJavaType lastCheckedType; @@ -71,12 +71,12 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (StampTool.isExactType(getValue())) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (StampTool.isExactType(forValue)) { // The profile is useless - we know the type! - return getValue(); - } else if (getValue() instanceof TypeProfileProxyNode) { - TypeProfileProxyNode other = (TypeProfileProxyNode) getValue(); + return forValue; + } else if (forValue instanceof TypeProfileProxyNode) { + TypeProfileProxyNode other = (TypeProfileProxyNode) forValue; JavaTypeProfile otherProfile = other.getProfile(); if (otherProfile == lastCheckedProfile) { // We have already incorporated the knowledge about this profile => abort. @@ -87,33 +87,33 @@ if (newProfile.equals(otherProfile)) { // We are useless - just use the other proxy node. Debug.log("Canonicalize with other proxy node."); - return getValue(); + return forValue; } if (newProfile != this.profile) { Debug.log("Improved profile via other profile."); - return TypeProfileProxyNode.create(getValue(), newProfile); + return new TypeProfileProxyNode(forValue, newProfile); } - } else if (StampTool.typeOrNull(getValue()) != null) { - ResolvedJavaType type = StampTool.typeOrNull(getValue()); + } else if (StampTool.typeOrNull(forValue) != null) { + ResolvedJavaType type = StampTool.typeOrNull(forValue); ResolvedJavaType uniqueConcrete = type.findUniqueConcreteSubtype(); if (uniqueConcrete != null) { // Profile is useless => remove. Debug.log("Profile useless, there is enough static type information available."); - return getValue(); + return forValue; } if (Objects.equals(type, lastCheckedType)) { // We have already incorporate the knowledge about this type => abort. return this; } lastCheckedType = type; - JavaTypeProfile newProfile = this.profile.restrict(type, StampTool.isObjectNonNull(getValue())); + JavaTypeProfile newProfile = this.profile.restrict(type, StampTool.isObjectNonNull(forValue)); if (newProfile != this.profile) { Debug.log("Improved profile via static type information."); if (newProfile.getTypes().length == 0) { // Only null profiling is not beneficial enough to keep the node around. - return getValue(); + return forValue; } - return TypeProfileProxyNode.create(getValue(), newProfile); + return new TypeProfileProxyNode(forValue, newProfile); } } return this; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnaryOpLogicNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,29 +22,22 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; -public abstract class UnaryOpLogicNode extends LogicNode implements LIRLowerable { +public abstract class UnaryOpLogicNode extends LogicNode implements LIRLowerable, Canonicalizable.Unary { - @Input private ValueNode object; + @Input private ValueNode value; - public ValueNode object() { - return object; + public ValueNode getValue() { + return value; } - protected void setX(ValueNode object) { - updateUsages(this.object, object); - this.object = object; + public UnaryOpLogicNode(ValueNode value) { + assert value != null; + this.value = value; } - public UnaryOpLogicNode(ValueNode object) { - assert object != null; - this.object = object; - } - - public abstract TriState evaluate(ValueNode forObject); - @Override public void generate(NodeLIRBuilderTool gen) { } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -34,7 +34,7 @@ @NodeInfo(nameTemplate = "ValuePhi({i#values})") public class ValuePhiNode extends PhiNode implements Simplifiable { - @Input final NodeInputList values = new NodeInputList<>(this); + @Input final NodeInputList values; /** * Create a value phi with the specified stamp. @@ -45,6 +45,20 @@ public ValuePhiNode(Stamp stamp, MergeNode merge) { super(stamp, merge); assert stamp != StampFactory.forVoid(); + values = new NodeInputList<>(this); + } + + /** + * Create a value phi with the specified stamp and the given values. + * + * @param stamp the stamp of the value + * @param merge the merge that the new phi belongs to + * @param values the initial values of the phi + */ + public ValuePhiNode(Stamp stamp, MergeNode merge, ValueNode[] values) { + super(stamp, merge); + assert stamp != StampFactory.forVoid(); + this.values = new NodeInputList<>(this, values); } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -30,17 +30,19 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "&") -public final class AndNode extends BitLogicNode implements Canonicalizable, NarrowableArithmeticNode { +public final class AndNode extends BitLogicNode implements NarrowableArithmeticNode { - public AndNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public AndNode(ValueNode x, ValueNode y) { + super(StampTool.and(x.stamp(), y.stamp()), x, y); + assert x.stamp().isCompatible(y.stamp()); } @Override public boolean inferStamp() { - return updateStamp(StampTool.and(x().stamp(), y().stamp())); + return updateStamp(StampTool.and(getX().stamp(), getY().stamp())); } @Override @@ -50,46 +52,45 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return x(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return forX; } - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new AndNode(stamp(), y(), x())); + if (forX.isConstant() && !forY.isConstant()) { + return new AndNode(forY, forX); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long rawY = y().asConstant().asLong(); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long rawY = forY.asConstant().asLong(); long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp())); if ((rawY & mask) == mask) { - return x(); + return forX; } if ((rawY & mask) == 0) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + return ConstantNode.forIntegerStamp(stamp(), 0); } - if (x() instanceof SignExtendNode) { - SignExtendNode ext = (SignExtendNode) x(); + if (forX instanceof SignExtendNode) { + SignExtendNode ext = (SignExtendNode) forX; if (rawY == ((1L << ext.getInputBits()) - 1)) { - ValueNode result = graph().unique(new ZeroExtendNode(ext.getValue(), ext.getResultBits())); - return result; + return new ZeroExtendNode(ext.getValue(), ext.getResultBits()); } } - if (x().stamp() instanceof IntegerStamp) { - IntegerStamp xStamp = (IntegerStamp) x().stamp(); + if (forX.stamp() instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) forX.stamp(); if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) { // No bits are set which are outside the mask, so the mask will have no effect. - return x(); + return forX; } } - return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitAnd(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitAnd(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -25,21 +25,22 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; /** * The {@code BinaryNode} class is the base of arithmetic and logic operations with two inputs. */ -public abstract class BinaryNode extends FloatingNode { +public abstract class BinaryNode extends FloatingNode implements Canonicalizable.Binary { @Input private ValueNode x; @Input private ValueNode y; - public ValueNode x() { + public ValueNode getX() { return x; } - public ValueNode y() { + public ValueNode getY() { return y; } @@ -63,9 +64,9 @@ public ValueNode getValue(BinaryNode binary) { switch (this) { case x: - return binary.x(); + return binary.getX(); case y: - return binary.y(); + return binary.getY(); default: throw GraalInternalError.shouldNotReachHere(); } @@ -74,9 +75,9 @@ public ValueNode getOtherValue(BinaryNode binary) { switch (this) { case x: - return binary.y(); + return binary.getY(); case y: - return binary.x(); + return binary.getX(); default: throw GraalInternalError.shouldNotReachHere(); } @@ -89,7 +90,7 @@ if (stamp instanceof IntegerStamp) { return IntegerArithmeticNode.add(graph, x, y); } else if (stamp instanceof FloatStamp) { - return graph.unique(new FloatAddNode(stamp, x, y, false)); + return graph.unique(new FloatAddNode(x, y, false)); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -101,7 +102,7 @@ if (stamp instanceof IntegerStamp) { return IntegerArithmeticNode.sub(graph, x, y); } else if (stamp instanceof FloatStamp) { - return graph.unique(new FloatSubNode(stamp, x, y, false)); + return graph.unique(new FloatSubNode(x, y, false)); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -113,7 +114,7 @@ if (stamp instanceof IntegerStamp) { return IntegerArithmeticNode.mul(graph, x, y); } else if (stamp instanceof FloatStamp) { - return graph.unique(new FloatMulNode(stamp, x, y, false)); + return graph.unique(new FloatMulNode(x, y, false)); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -124,8 +125,8 @@ } public static ReassociateMatch findReassociate(BinaryNode binary, NodePredicate criterion) { - boolean resultX = criterion.apply(binary.x()); - boolean resultY = criterion.apply(binary.y()); + boolean resultX = criterion.apply(binary.getX()); + boolean resultY = criterion.apply(binary.getY()); if (resultX && !resultY) { return ReassociateMatch.x; } @@ -157,8 +158,11 @@ *

* This method accepts only {@linkplain #canTryReassociate(BinaryNode) reassociable} operations * such as +, -, *, &, | and ^ + * + * @param forY + * @param forX */ - public static BinaryNode reassociate(BinaryNode node, NodePredicate criterion) { + public static BinaryNode reassociate(BinaryNode node, NodePredicate criterion, ValueNode forX, ValueNode forY) { assert canTryReassociate(node); ReassociateMatch match1 = findReassociate(node, criterion); if (match1 == null) { @@ -203,29 +207,28 @@ ValueNode a = match2.getOtherValue(other); if (node instanceof IntegerAddNode || node instanceof IntegerSubNode) { BinaryNode associated; - StructuredGraph graph = node.graph(); if (invertM1) { - associated = IntegerArithmeticNode.sub(graph, m2, m1); + associated = IntegerArithmeticNode.sub(m2, m1); } else if (invertM2) { - associated = IntegerArithmeticNode.sub(graph, m1, m2); + associated = IntegerArithmeticNode.sub(m1, m2); } else { - associated = IntegerArithmeticNode.add(graph, m1, m2); + associated = IntegerArithmeticNode.add(m1, m2); } if (invertA) { - return IntegerArithmeticNode.sub(graph, associated, a); + return IntegerArithmeticNode.sub(associated, a); } if (aSub) { - return IntegerArithmeticNode.sub(graph, a, associated); + return IntegerArithmeticNode.sub(a, associated); } - return IntegerArithmeticNode.add(graph, a, associated); + return IntegerArithmeticNode.add(a, associated); } else if (node instanceof IntegerMulNode) { - return IntegerArithmeticNode.mul(node.graph(), a, IntegerAddNode.mul(node.graph(), m1, m2)); + return IntegerArithmeticNode.mul(a, IntegerAddNode.mul(m1, m2)); } else if (node instanceof AndNode) { - return BitLogicNode.and(node.graph(), a, BitLogicNode.and(node.graph(), m1, m2)); + return BitLogicNode.and(a, BitLogicNode.and(m1, m2)); } else if (node instanceof OrNode) { - return BitLogicNode.or(node.graph(), a, BitLogicNode.or(node.graph(), m1, m2)); + return BitLogicNode.or(a, BitLogicNode.or(m1, m2)); } else if (node instanceof XorNode) { - return BitLogicNode.xor(node.graph(), a, BitLogicNode.xor(node.graph(), m1, m2)); + return BitLogicNode.xor(a, BitLogicNode.xor(m1, m2)); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -25,7 +25,6 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * The {@code LogicNode} class definition. @@ -34,7 +33,7 @@ /** * Constructs a new logic operation node. - * + * * @param x the first input into this node * @param y the second input into this node */ @@ -44,17 +43,26 @@ } public static BitLogicNode and(StructuredGraph graph, ValueNode v1, ValueNode v2) { - assert v1.stamp().isCompatible(v2.stamp()); - return graph.unique(new AndNode(StampTool.and(v1.stamp(), v2.stamp()), v1, v2)); + return graph.unique(new AndNode(v1, v2)); + } + + public static BitLogicNode and(ValueNode v1, ValueNode v2) { + return new AndNode(v1, v2); } public static BitLogicNode or(StructuredGraph graph, ValueNode v1, ValueNode v2) { - assert v1.stamp().isCompatible(v2.stamp()); - return graph.unique(new OrNode(StampTool.or(v1.stamp(), v2.stamp()), v1, v2)); + return graph.unique(new OrNode(v1, v2)); + } + + public static BitLogicNode or(ValueNode v1, ValueNode v2) { + return new OrNode(v1, v2); } public static BitLogicNode xor(StructuredGraph graph, ValueNode v1, ValueNode v2) { - assert v1.stamp().isCompatible(v2.stamp()); - return graph.unique(new XorNode(StampTool.xor(v1.stamp(), v2.stamp()), v1, v2)); + return graph.unique(new XorNode(v1, v2)); + } + + public static BitLogicNode xor(ValueNode v1, ValueNode v2) { + return new XorNode(v1, v2); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,10 +23,8 @@ 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.*; import com.oracle.graal.compiler.common.calc.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; @@ -62,7 +60,7 @@ */ public abstract boolean unorderedIsTrue(); - private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { + private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { Constant trueConstant = conditionalNode.trueValue().asConstant(); Constant falseConstant = conditionalNode.falseValue().asConstant(); @@ -71,14 +69,14 @@ boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue()); if (trueResult == falseResult) { - return LogicConstantNode.forBoolean(trueResult, graph()); + return LogicConstantNode.forBoolean(trueResult); } else { if (trueResult) { assert falseResult == false; return conditionalNode.condition(); } else { assert falseResult == true; - return graph().unique(new LogicNegationNode(conditionalNode.condition())); + return new LogicNegationNode(conditionalNode.condition()); } } @@ -86,46 +84,37 @@ return this; } - protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { throw new GraalInternalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored); } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (forX.isConstant() && forY.isConstant()) { - return TriState.get(condition().foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue())); + return LogicConstantNode.forBoolean(condition().foldCondition(forX.asConstant(), forY.asConstant(), tool.getConstantReflection(), unorderedIsTrue())); } - return TriState.UNKNOWN; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - Node result = super.canonical(tool); - if (result != this) { - return result; - } - if (x().isConstant()) { - if ((result = canonicalizeSymmetricConstant(tool, x().asConstant(), y(), true)) != this) { + ValueNode result; + if (forX.isConstant()) { + if ((result = canonicalizeSymmetricConstant(tool, forX.asConstant(), forY, true)) != this) { return result; } - } else if (y().isConstant()) { - if ((result = canonicalizeSymmetricConstant(tool, y().asConstant(), x(), false)) != this) { + } else if (forY.isConstant()) { + if ((result = canonicalizeSymmetricConstant(tool, forY.asConstant(), forX, false)) != this) { return result; } - } else if (x() instanceof ConvertNode && y() instanceof ConvertNode) { - ConvertNode convertX = (ConvertNode) x(); - ConvertNode convertY = (ConvertNode) y(); + } else if (forX instanceof ConvertNode && forY instanceof ConvertNode) { + ConvertNode convertX = (ConvertNode) forX; + ConvertNode convertY = (ConvertNode) forY; if (convertX.preservesOrder(condition()) && convertY.preservesOrder(condition()) && convertX.getValue().stamp().isCompatible(convertY.getValue().stamp())) { - return graph().unique(duplicateModified(convertX.getValue(), convertY.getValue())); + return duplicateModified(convertX.getValue(), convertY.getValue()); } - } return this; } protected abstract CompareNode duplicateModified(ValueNode newX, ValueNode newY); - protected Node canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { + protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { if (nonConstant instanceof ConditionalNode) { return optimizeConditional(constant, (ConditionalNode) nonConstant, tool.getConstantReflection(), mirrored ? condition().mirror() : condition()); } else if (nonConstant instanceof NormalizeCompareNode) { @@ -135,9 +124,9 @@ ConstantNode newConstant = canonicalConvertConstant(tool, convert, constant); if (newConstant != null) { if (mirrored) { - return graph().unique(duplicateModified(newConstant, convert.getValue())); + return duplicateModified(newConstant, convert.getValue()); } else { - return graph().unique(duplicateModified(convert.getValue(), newConstant)); + return duplicateModified(convert.getValue(), newConstant); } } } @@ -148,13 +137,17 @@ if (convert.preservesOrder(condition())) { Constant reverseConverted = convert.reverse(constant); if (convert.convert(reverseConverted).equals(constant)) { - return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, tool.getMetaAccess(), convert.graph()); + return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, tool.getMetaAccess()); } } return null; } public static CompareNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) { + return graph.unique(createCompareNode(condition, x, y)); + } + + public static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) { assert x.getKind() == y.getKind(); assert condition.isCanonical() : "condition is not canonical: " + condition; assert !x.getKind().isNumericFloat(); @@ -176,6 +169,6 @@ comparison = new IntegerBelowThanNode(x, y); } - return graph.unique(comparison); + return comparison; } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -76,17 +76,17 @@ public ValueNode canonical(CanonicalizerTool tool) { if (condition instanceof LogicNegationNode) { LogicNegationNode negated = (LogicNegationNode) condition; - return graph().unique(new ConditionalNode(negated.getInput(), falseValue(), trueValue())); + return graph().unique(new ConditionalNode(negated.getValue(), falseValue(), trueValue())); } // this optimizes the case where a value that can only be 0 or 1 is materialized to 0 or 1 if (trueValue().isConstant() && falseValue().isConstant() && condition instanceof IntegerEqualsNode) { IntegerEqualsNode equals = (IntegerEqualsNode) condition; - if (equals.y().isConstant() && equals.y().asConstant().equals(Constant.INT_0) && equals.x().stamp() instanceof IntegerStamp) { - IntegerStamp equalsXStamp = (IntegerStamp) equals.x().stamp(); + if (equals.getY().isConstant() && equals.getY().asConstant().equals(Constant.INT_0) && equals.getX().stamp() instanceof IntegerStamp) { + IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp(); if (equalsXStamp.upMask() == 1) { if (trueValue().asConstant().equals(Constant.INT_0) && falseValue().asConstant().equals(Constant.INT_1)) { - return IntegerConvertNode.convertUnsigned(equals.x(), stamp()); + return IntegerConvertNode.convertUnsigned(equals.getX(), stamp()); } } } @@ -102,7 +102,7 @@ if (condition instanceof CompareNode && ((CompareNode) condition).condition() == Condition.EQ) { // optimize the pattern (x == y) ? x : y CompareNode compare = (CompareNode) condition; - if ((compare.x() == trueValue() && compare.y() == falseValue()) || (compare.x() == falseValue() && compare.y() == trueValue())) { + if ((compare.getX() == trueValue() && compare.getY() == falseValue()) || (compare.getX() == falseValue() && compare.getY() == trueValue())) { return falseValue(); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,24 +23,25 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode { +public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode implements Canonicalizable.Binary { @Input private ValueNode x; @Input private ValueNode y; - public ValueNode x() { - return x; - } - - public ValueNode y() { - return y; - } - public FixedBinaryNode(Stamp stamp, ValueNode x, ValueNode y) { super(stamp); this.x = x; this.y = y; } + + public ValueNode getX() { + return x; + } + + public ValueNode getY() { + return y; + } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -31,10 +30,10 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "+") -public final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable { +public final class FloatAddNode extends FloatArithmeticNode { - public FloatAddNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) { - super(stamp, x, y, isStrictFP); + public FloatAddNode(ValueNode x, ValueNode y, boolean isStrictFP) { + super(x.stamp().unrestricted(), x, y, isStrictFP); } public Constant evalConst(Constant... inputs) { @@ -49,12 +48,12 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new FloatAddNode(stamp(), y(), x(), isStrictFP())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new FloatAddNode(forY, forX, isStrictFP()); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + if (forX.isConstant()) { + return ConstantNode.forConstant(evalConst(forX.asConstant(), forY.asConstant()), null); } // Constant 0.0 can't be eliminated since it can affect the sign of the result. return this; @@ -62,9 +61,9 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value op1 = builder.operand(x()); - Value op2 = builder.operand(y()); - if (!y().isConstant() && !livesLonger(this, y(), builder)) { + Value op1 = builder.operand(getX()); + Value op2 = builder.operand(getY()); + if (!getY().isConstant() && !livesLonger(this, getY(), builder)) { Value op = op1; op1 = op2; op2 = op; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -36,7 +35,7 @@ * A {@code FloatConvert} converts between integers and floating point numbers according to Java * semantics. */ -public class FloatConvertNode extends ConvertNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable { +public class FloatConvertNode extends ConvertNode implements Lowerable, ArithmeticLIRLowerable { private final FloatConvert op; @@ -147,11 +146,11 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - return ConstantNode.forPrimitive(evalConst(getValue().asConstant()), graph()); - } else if (getValue() instanceof FloatConvertNode) { - FloatConvertNode other = (FloatConvertNode) getValue(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + return ConstantNode.forConstant(evalConst(forValue.asConstant()), null); + } else if (forValue instanceof FloatConvertNode) { + FloatConvertNode other = (FloatConvertNode) forValue; if (other.isLossless() && other.op == this.op.reverse()) { return other.getValue(); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -31,10 +30,10 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "/") -public final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable { +public final class FloatDivNode extends FloatArithmeticNode { - public FloatDivNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) { - super(stamp, x, y, isStrictFP); + public FloatDivNode(ValueNode x, ValueNode y, boolean isStrictFP) { + super(x.stamp().unrestricted(), x, y, isStrictFP); } public Constant evalConst(Constant... inputs) { @@ -49,15 +48,15 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitDiv(builder.operand(x()), builder.operand(y()), null)); + builder.setResult(this, gen.emitDiv(builder.operand(getX()), builder.operand(getY()), null)); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,12 +22,11 @@ */ package com.oracle.graal.nodes.calc; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @@ -57,17 +56,21 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = super.canonical(tool, forX, forY); + if (result != this) { + return result; + } if (forX.stamp() instanceof FloatStamp && forY.stamp() instanceof FloatStamp) { FloatStamp xStamp = (FloatStamp) forX.stamp(); FloatStamp yStamp = (FloatStamp) forY.stamp(); if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && xStamp.isNonNaN() && yStamp.isNonNaN()) { - return TriState.TRUE; + return LogicConstantNode.tautology(); } else if (xStamp.alwaysDistinct(yStamp)) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } } - return super.evaluate(constantReflection, forX, forY); + return this; } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,12 +22,11 @@ */ 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.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @@ -62,11 +61,15 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = super.canonical(tool, forX, forY); + if (result != this) { + return result; + } if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY) && !unorderedIsTrue()) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } - return super.evaluate(constantReflection, forX, forY); + return this; } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -31,10 +30,10 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "*") -public final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable { +public final class FloatMulNode extends FloatArithmeticNode { - public FloatMulNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) { - super(stamp, x, y, isStrictFP); + public FloatMulNode(ValueNode x, ValueNode y, boolean isStrictFP) { + super(x.stamp().unrestricted(), x, y, isStrictFP); } public Constant evalConst(Constant... inputs) { @@ -49,21 +48,21 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new FloatMulNode(stamp(), y(), x(), isStrictFP())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new FloatMulNode(forY, forX, isStrictFP()); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value op1 = builder.operand(x()); - Value op2 = builder.operand(y()); - if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) { + Value op1 = builder.operand(getX()); + Value op2 = builder.operand(getY()); + if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) { Value op = op1; op1 = op2; op2 = op; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -31,10 +30,10 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "%") -public class FloatRemNode extends FloatArithmeticNode implements Canonicalizable, Lowerable { +public class FloatRemNode extends FloatArithmeticNode implements Lowerable { - public FloatRemNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) { - super(stamp, x, y, isStrictFP); + public FloatRemNode(ValueNode x, ValueNode y, boolean isStrictFP) { + super(x.stamp().unrestricted(), x, y, isStrictFP); } public Constant evalConst(Constant... inputs) { @@ -49,9 +48,9 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(getX().asConstant(), getY().asConstant())); } return this; } @@ -63,6 +62,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitRem(builder.operand(x()), builder.operand(y()), null)); + builder.setResult(this, gen.emitRem(builder.operand(getX()), builder.operand(getY()), null)); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,18 +23,18 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "-") -public final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable { +public final class FloatSubNode extends FloatArithmeticNode { - public FloatSubNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) { - super(stamp, x, y, isStrictFP); + public FloatSubNode(ValueNode x, ValueNode y, boolean isStrictFP) { + super(x.stamp().unrestricted(), x, y, isStrictFP); } public Constant evalConst(Constant... inputs) { @@ -49,12 +49,12 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return ConstantNode.forFloatingStamp(stamp(), 0.0f, graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return ConstantNode.forFloatingStamp(stamp(), 0.0f); } - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } // Constant 0.0 can't be eliminated since it can affect the sign of the result. return this; @@ -62,6 +62,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,15 +32,15 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "+") -public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode { +public class IntegerAddNode extends IntegerArithmeticNode implements NarrowableArithmeticNode { - public IntegerAddNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public IntegerAddNode(ValueNode x, ValueNode y) { + super(StampTool.add(x.stamp(), y.stamp()), x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.add(x().stamp(), y().stamp())); + return updateStamp(StampTool.add(getX().stamp(), getY().stamp())); } @Override @@ -50,51 +50,51 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerAddNode(stamp(), y(), x())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new IntegerAddNode(forY, forX); } - if (x() instanceof IntegerSubNode) { - IntegerSubNode sub = (IntegerSubNode) x(); - if (sub.y() == y()) { + if (forX instanceof IntegerSubNode) { + IntegerSubNode sub = (IntegerSubNode) forX; + if (sub.getY() == forY) { // (a - b) + b - return sub.x(); + return sub.getX(); } } - if (y() instanceof IntegerSubNode) { - IntegerSubNode sub = (IntegerSubNode) y(); - if (sub.y() == x()) { + if (forY instanceof IntegerSubNode) { + IntegerSubNode sub = (IntegerSubNode) forY; + if (sub.getY() == forX) { // b + (a - b) - return sub.x(); + return sub.getX(); } } - if (x().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 0) { - return x(); + return forX; } // canonicalize expressions like "(a + 1) + 2" - BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); if (reassociated != this) { return reassociated; } } - if (x() instanceof NegateNode) { - return IntegerArithmeticNode.sub(graph(), y(), ((NegateNode) x()).getValue()); - } else if (y() instanceof NegateNode) { - return IntegerArithmeticNode.sub(graph(), x(), ((NegateNode) y()).getValue()); + if (forX instanceof NegateNode) { + return IntegerArithmeticNode.sub(forY, ((NegateNode) forX).getValue()); + } else if (forY instanceof NegateNode) { + return IntegerArithmeticNode.sub(forX, ((NegateNode) forY).getValue()); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value op1 = builder.operand(x()); - assert op1 != null : x() + ", this=" + this; - Value op2 = builder.operand(y()); - if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) { + Value op1 = builder.operand(getX()); + assert op1 != null : getX() + ", this=" + this; + Value op2 = builder.operand(getY()); + if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) { Value op = op1; op1 = op2; op2 = op; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,7 +25,6 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; public abstract class IntegerArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { @@ -35,15 +34,26 @@ } public static IntegerAddNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) { - return graph.unique(new IntegerAddNode(StampTool.add(v1.stamp(), v2.stamp()), v1, v2)); + return graph.unique(new IntegerAddNode(v1, v2)); + } + + public static IntegerAddNode add(ValueNode v1, ValueNode v2) { + return new IntegerAddNode(v1, v2); } public static IntegerMulNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) { - assert v1.stamp().isCompatible(v2.stamp()); - return graph.unique(new IntegerMulNode(v1.stamp().unrestricted(), v1, v2)); + return graph.unique(new IntegerMulNode(v1, v2)); + } + + public static IntegerMulNode mul(ValueNode v1, ValueNode v2) { + return new IntegerMulNode(v1, v2); } public static IntegerSubNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) { - return graph.unique(new IntegerSubNode(StampTool.sub(v1.stamp(), v2.stamp()), v1, v2)); + return graph.unique(new IntegerSubNode(v1, v2)); + } + + public static IntegerSubNode sub(ValueNode v1, ValueNode v2) { + return new IntegerSubNode(v1, v2); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,8 +22,6 @@ */ package com.oracle.graal.nodes.calc; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -57,32 +55,27 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = super.canonical(tool, forX, forY); + if (result != this) { + return result; + } if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } else if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) { IntegerStamp xStamp = (IntegerStamp) forX.stamp(); IntegerStamp yStamp = (IntegerStamp) forY.stamp(); if (yStamp.isPositive()) { if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { - return TriState.TRUE; + return LogicConstantNode.tautology(); } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } } } - return super.evaluate(constantReflection, forX, forY); - } - - @Override - public Node canonical(CanonicalizerTool tool) { - Node result = super.canonical(tool); - if (result != this) { - return result; - } - if (x().isConstant() && x().asConstant().asLong() == 0) { + if (forX.isConstant() && forX.asConstant().asLong() == 0) { // 0 |<| y is the same as 0 != y - return graph().unique(new LogicNegationNode(CompareNode.createCompareNode(graph(), Condition.EQ, x(), y()))); + return new LogicNegationNode(CompareNode.createCompareNode(Condition.EQ, forX, forY)); } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,16 +22,14 @@ */ package com.oracle.graal.nodes.calc; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; /** * An {@code IntegerConvert} converts an integer to an integer of different width. */ -public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable, Canonicalizable { +public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable { private final int resultBits; @@ -60,18 +58,16 @@ } } - protected ValueNode canonicalConvert() { - if (getValue().stamp() instanceof IntegerStamp) { - int inputBits = ((IntegerStamp) getValue().stamp()).getBits(); + protected ValueNode canonicalConvert(ValueNode value) { + if (value.stamp() instanceof IntegerStamp) { + int inputBits = ((IntegerStamp) value.stamp()).getBits(); if (inputBits == resultBits) { - return getValue(); - } else if (getValue().isConstant()) { - Constant ret = evalConst(getValue().asConstant()); - return ConstantNode.forIntegerBits(resultBits, ret.asLong(), graph()); + return value; + } else if (value.isConstant()) { + return ConstantNode.forIntegerBits(resultBits, evalConst(value.asConstant()).asLong()); } } - - return null; + return this; } public static ValueNode convert(ValueNode input, Stamp stamp) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,62 +31,61 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "/") -public class IntegerDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { +public class IntegerDivNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public IntegerDivNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public IntegerDivNode(ValueNode x, ValueNode y) { + super(x.stamp().unrestricted(), x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.div(x().stamp(), y().stamp())); + return updateStamp(StampTool.div(getX().stamp(), getY().stamp())); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - long y = y().asConstant().asLong(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + long y = forY.asConstant().asLong(); if (y == 0) { return this; // this will trap, can not canonicalize } - return ConstantNode.forIntegerStamp(stamp(), x().asConstant().asLong() / y, graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + return ConstantNode.forIntegerStamp(stamp(), forX.asConstant().asLong() / y); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1) { - return x(); + return forX; } if (c == -1) { - return graph().unique(new NegateNode(x())); + return new NegateNode(forX); } long abs = Math.abs(c); - if (CodeUtil.isPowerOf2(abs) && x().stamp() instanceof IntegerStamp) { - Stamp unrestricted = stamp().unrestricted(); - ValueNode dividend = x(); - IntegerStamp stampX = (IntegerStamp) x().stamp(); + if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) { + ValueNode dividend = forX; + IntegerStamp stampX = (IntegerStamp) forX.stamp(); int log2 = CodeUtil.log2(abs); // no rounding if dividend is positive or if its low bits are always 0 if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) { int bits = PrimitiveStamp.getBits(stamp()); - RightShiftNode sign = graph().unique(new RightShiftNode(unrestricted, x(), ConstantNode.forInt(bits - 1, graph()))); - UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(unrestricted, sign, ConstantNode.forInt(bits - log2, graph()))); - dividend = IntegerArithmeticNode.add(graph(), dividend, round); + RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1)); + UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2)); + dividend = IntegerArithmeticNode.add(dividend, round); } - RightShiftNode shift = graph().unique(new RightShiftNode(unrestricted, dividend, ConstantNode.forInt(log2, graph()))); + RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2)); if (c < 0) { - return graph().unique(new NegateNode(shift)); + return new NegateNode(shift); } return shift; } } // Convert the expression ((a - a % b) / b) into (a / b). - if (x() instanceof IntegerSubNode) { - IntegerSubNode integerSubNode = (IntegerSubNode) x(); - if (integerSubNode.y() instanceof IntegerRemNode) { - IntegerRemNode integerRemNode = (IntegerRemNode) integerSubNode.y(); - if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.x() == integerRemNode.x() && - this.y() == integerRemNode.y()) { - return graph().add(new IntegerDivNode(stamp(), integerSubNode.x(), this.y())); + if (forX instanceof IntegerSubNode) { + IntegerSubNode integerSubNode = (IntegerSubNode) forX; + if (integerSubNode.getY() instanceof IntegerRemNode) { + IntegerRemNode integerRemNode = (IntegerRemNode) integerSubNode.getY(); + if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.getX() == integerRemNode.getX() && + forY == integerRemNode.getY()) { + return new IntegerDivNode(integerSubNode.getX(), forY); } } } @@ -108,11 +107,11 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override public boolean canDeoptimize() { - return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); + return !(getY().stamp() instanceof IntegerStamp) || ((IntegerStamp) getY().stamp()).contains(0); } } diff -r a47528fb2ea0 -r e34bb128f227 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 Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ 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.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -58,15 +57,15 @@ } @Override - protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { if (constant.getKind() == Kind.Int && constant.asInt() == 0) { - ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); - ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y(); + ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); + ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); - if (normalizeNode.x().getKind() == Kind.Double || normalizeNode.x().getKind() == Kind.Float) { - return graph().unique(new FloatEqualsNode(a, b)); + if (normalizeNode.getX().getKind() == Kind.Double || normalizeNode.getX().getKind() == Kind.Float) { + return new FloatEqualsNode(a, b); } else { - return graph().unique(new IntegerEqualsNode(a, b)); + return new IntegerEqualsNode(a, b); } } return this; @@ -83,56 +82,56 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { - return TriState.TRUE; + return LogicConstantNode.tautology(); } else if (forX.stamp().alwaysDistinct(forY.stamp())) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } - return super.evaluate(constantReflection, forX, forY); + return super.canonical(tool, forX, forY); } @Override - protected Node canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { + protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { if (constant.asLong() == 0) { if (nonConstant instanceof AndNode) { AndNode andNode = (AndNode) nonConstant; - return graph().unique(new IntegerTestNode(andNode.x(), andNode.y())); + return new IntegerTestNode(andNode.getX(), andNode.getY()); } else if (nonConstant instanceof ShiftNode) { if (nonConstant instanceof LeftShiftNode) { LeftShiftNode shift = (LeftShiftNode) nonConstant; - if (shift.y().isConstant()) { + if (shift.getY().isConstant()) { int mask = shift.getShiftAmountMask(); - int amount = shift.y().asConstant().asInt() & mask; - if (shift.x().getKind() == Kind.Int) { - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 >>> amount, graph()))); + int amount = shift.getY().asConstant().asInt() & mask; + if (shift.getX().getKind() == Kind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 >>> amount)); } else { - assert shift.x().getKind() == Kind.Long; - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L >>> amount, graph()))); + assert shift.getX().getKind() == Kind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L >>> amount)); } } } else if (nonConstant instanceof RightShiftNode) { RightShiftNode shift = (RightShiftNode) nonConstant; - if (shift.y().isConstant() && ((IntegerStamp) shift.x().stamp()).isPositive()) { + if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp()).isPositive()) { int mask = shift.getShiftAmountMask(); - int amount = shift.y().asConstant().asInt() & mask; - if (shift.x().getKind() == Kind.Int) { - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph()))); + int amount = shift.getY().asConstant().asInt() & mask; + if (shift.getX().getKind() == Kind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); } else { - assert shift.x().getKind() == Kind.Long; - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph()))); + assert shift.getX().getKind() == Kind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); } } } else if (nonConstant instanceof UnsignedRightShiftNode) { UnsignedRightShiftNode shift = (UnsignedRightShiftNode) nonConstant; - if (shift.y().isConstant()) { + if (shift.getY().isConstant()) { int mask = shift.getShiftAmountMask(); - int amount = shift.y().asConstant().asInt() & mask; - if (shift.x().getKind() == Kind.Int) { - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph()))); + int amount = shift.getY().asConstant().asInt() & mask; + if (shift.getX().getKind() == Kind.Int) { + return new IntegerTestNode(shift.getX(), ConstantNode.forInt(-1 << amount)); } else { - assert shift.x().getKind() == Kind.Long; - return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph()))); + assert shift.getX().getKind() == Kind.Long; + return new IntegerTestNode(shift.getX(), ConstantNode.forLong(-1L << amount)); } } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -58,46 +57,41 @@ } @Override - protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { assert condition() == Condition.LT; if (constant.getKind() == Kind.Int && constant.asInt() == 0) { - ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); - ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y(); + ValueNode a = mirrored ? normalizeNode.getY() : normalizeNode.getX(); + ValueNode b = mirrored ? normalizeNode.getX() : normalizeNode.getY(); - if (normalizeNode.x().getKind() == Kind.Double || normalizeNode.x().getKind() == Kind.Float) { - return graph().unique(new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess)); + if (normalizeNode.getX().getKind() == Kind.Double || normalizeNode.getX().getKind() == Kind.Float) { + return new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess); } else { - return graph().unique(new IntegerLessThanNode(a, b)); + return new IntegerLessThanNode(a, b); } } return this; } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = super.canonical(tool, forX, forY); + if (result != this) { + return result; + } if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } else if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) { IntegerStamp xStamp = (IntegerStamp) forX.stamp(); IntegerStamp yStamp = (IntegerStamp) forY.stamp(); if (xStamp.upperBound() < yStamp.lowerBound()) { - return TriState.TRUE; + return LogicConstantNode.tautology(); } else if (xStamp.lowerBound() >= yStamp.upperBound()) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } } - return super.evaluate(constantReflection, forX, forY); - } - - @Override - public Node canonical(CanonicalizerTool tool) { - Node result = super.canonical(tool); - if (result != this) { - return result; - } - if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { - if (IntegerStamp.sameSign((IntegerStamp) x().stamp(), (IntegerStamp) y().stamp())) { - return graph().unique(new IntegerBelowThanNode(x(), y())); + if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) { + if (IntegerStamp.sameSign((IntegerStamp) forX.stamp(), (IntegerStamp) forY.stamp())) { + return new IntegerBelowThanNode(forX, forY); } } return this; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,10 +32,11 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "*") -public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode { +public class IntegerMulNode extends IntegerArithmeticNode implements NarrowableArithmeticNode { - public IntegerMulNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public IntegerMulNode(ValueNode x, ValueNode y) { + super(x.stamp().unrestricted(), x, y); + assert x.stamp().isCompatible(y.stamp()); } @Override @@ -45,40 +46,40 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerMulNode(stamp(), y(), x())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new IntegerMulNode(forY, forX); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1) { - return x(); + return forX; } if (c == 0) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + return ConstantNode.forIntegerStamp(stamp(), 0); } long abs = Math.abs(c); if (abs > 0 && CodeUtil.isPowerOf2(abs)) { - LeftShiftNode shift = graph().unique(new LeftShiftNode(stamp().unrestricted(), x(), ConstantNode.forInt(CodeUtil.log2(abs), graph()))); + LeftShiftNode shift = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(abs))); if (c < 0) { - return graph().unique(new NegateNode(shift)); + return new NegateNode(shift); } else { return shift; } } // canonicalize expressions like "(a * 1) * 2" - return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value op1 = builder.operand(x()); - Value op2 = builder.operand(y()); - if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) { + Value op1 = builder.operand(getX()); + Value op2 = builder.operand(getY()); + if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) { Value op = op1; op1 = op2; op2 = op; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,31 +31,31 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "%") -public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { +public class IntegerRemNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - public IntegerRemNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public IntegerRemNode(ValueNode x, ValueNode y) { + super(x.stamp().unrestricted(), x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.rem(x().stamp(), y().stamp())); + return updateStamp(StampTool.rem(getX().stamp(), getY().stamp())); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - long y = y().asConstant().asLong(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + long y = forY.asConstant().asLong(); if (y == 0) { return this; // this will trap, can not canonicalize } - return ConstantNode.forIntegerStamp(stamp(), x().asConstant().asLong() % y, graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + return ConstantNode.forIntegerStamp(stamp(), forX.asConstant().asLong() % y); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1 || c == -1) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); - } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { - return graph().unique(new AndNode(stamp(), x(), ConstantNode.forIntegerStamp(stamp(), c - 1, graph()))); + return ConstantNode.forIntegerStamp(stamp(), 0); + } else if (c > 0 && CodeUtil.isPowerOf2(c) && forX.stamp() instanceof IntegerStamp && ((IntegerStamp) forX.stamp()).isPositive()) { + return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), c - 1)); } } return this; @@ -68,11 +68,11 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override public boolean canDeoptimize() { - return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); + return !(getY().stamp() instanceof IntegerStamp) || ((IntegerStamp) getY().stamp()).contains(0); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -30,17 +30,18 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "-") -public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode { +public class IntegerSubNode extends IntegerArithmeticNode implements NarrowableArithmeticNode { - public IntegerSubNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public IntegerSubNode(ValueNode x, ValueNode y) { + super(StampTool.sub(x.stamp(), y.stamp()), x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.sub(x().stamp(), y().stamp())); + return updateStamp(StampTool.sub(getX().stamp(), getY().stamp())); } @Override @@ -50,75 +51,75 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return ConstantNode.forIntegerStamp(stamp(), 0); } - if (x() instanceof IntegerAddNode) { - IntegerAddNode x = (IntegerAddNode) x(); - if (x.y() == y()) { + if (forX instanceof IntegerAddNode) { + IntegerAddNode x = (IntegerAddNode) forX; + if (x.getY() == forY) { // (a + b) - b - return x.x(); + return x.getX(); } - if (x.x() == y()) { + if (x.getX() == forY) { // (a + b) - a - return x.y(); + return x.getY(); } - } else if (x() instanceof IntegerSubNode) { - IntegerSubNode x = (IntegerSubNode) x(); - if (x.x() == y()) { + } else if (forX instanceof IntegerSubNode) { + IntegerSubNode x = (IntegerSubNode) forX; + if (x.getX() == forY) { // (a - b) - a - return graph().unique(new NegateNode(x.y())); + return new NegateNode(x.getY()); } } - if (y() instanceof IntegerAddNode) { - IntegerAddNode y = (IntegerAddNode) y(); - if (y.x() == x()) { + if (forY instanceof IntegerAddNode) { + IntegerAddNode y = (IntegerAddNode) forY; + if (y.getX() == forX) { // a - (a + b) - return graph().unique(new NegateNode(y.y())); + return new NegateNode(y.getY()); } - if (y.y() == x()) { + if (y.getY() == forX) { // b - (a + b) - return graph().unique(new NegateNode(y.x())); + return new NegateNode(y.getX()); } - } else if (y() instanceof IntegerSubNode) { - IntegerSubNode y = (IntegerSubNode) y(); - if (y.x() == x()) { + } else if (forY instanceof IntegerSubNode) { + IntegerSubNode y = (IntegerSubNode) forY; + if (y.getX() == forX) { // a - (a - b) - return y.y(); + return y.getY(); } } - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 0) { - return x(); + return forX; } - BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); if (reassociated != this) { return reassociated; } - if (c < 0 || ((IntegerStamp) StampFactory.forKind(y().getKind())).contains(-c)) { + if (c < 0 || ((IntegerStamp) StampFactory.forKind(forY.getKind())).contains(-c)) { // Adding a negative is more friendly to the backend since adds are // commutative, so prefer add when it fits. - return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forIntegerStamp(stamp(), -c, graph())); + return IntegerArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp(), -c)); } - } else if (x().isConstant()) { - long c = x().asConstant().asLong(); + } else if (forX.isConstant()) { + long c = forX.asConstant().asLong(); if (c == 0) { - return graph().unique(new NegateNode(y())); + return new NegateNode(forY); } - return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } - if (y() instanceof NegateNode) { - return IntegerArithmeticNode.add(graph(), x(), ((NegateNode) y()).getValue()); + if (forY instanceof NegateNode) { + return IntegerArithmeticNode.add(forX, ((NegateNode) forY).getValue()); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,9 +22,8 @@ */ 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.spi.*; import com.oracle.graal.nodes.*; /** @@ -45,19 +44,19 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (forX.isConstant() && forY.isConstant()) { - return TriState.get((forX.asConstant().asLong() & forY.asConstant().asLong()) == 0); + return LogicConstantNode.forBoolean((forX.asConstant().asLong() & forY.asConstant().asLong()) == 0); } - if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { + if (getX().stamp() instanceof IntegerStamp && getY().stamp() instanceof IntegerStamp) { IntegerStamp xStamp = (IntegerStamp) forX.stamp(); IntegerStamp yStamp = (IntegerStamp) forY.stamp(); if ((xStamp.upMask() & yStamp.upMask()) == 0) { - return TriState.TRUE; + return LogicConstantNode.tautology(); } else if ((xStamp.downMask() & yStamp.downMask()) != 0) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } } - return TriState.UNKNOWN; + return this; } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,9 +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.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,7 +32,7 @@ /** * An IsNullNode will be true if the supplied value is null, and false if it is non-null. */ -public final class IsNullNode extends UnaryOpLogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable { +public final class IsNullNode extends UnaryOpLogicNode implements LIRLowerable, Virtualizable, PiPushable { /** * Constructs a new IsNullNode instruction. @@ -52,38 +50,27 @@ @Override public boolean verify() { - assertTrue(object() != null, "is null input must not be null"); - assertTrue(object().stamp() instanceof AbstractObjectStamp, "is null input must be an object"); + assertTrue(getValue() != null, "is null input must not be null"); + assertTrue(getValue().stamp() instanceof AbstractObjectStamp, "is null input must be an object"); return super.verify(); } @Override - public Node canonical(CanonicalizerTool tool) { - switch (evaluate(object())) { - case FALSE: - return LogicConstantNode.contradiction(graph()); - case TRUE: - return LogicConstantNode.tautology(graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + Constant constant = forValue.asConstant(); + if (constant != null) { + assert constant.getKind() == Kind.Object; + return LogicConstantNode.forBoolean(constant.isNull()); + } + if (StampTool.isObjectNonNull(forValue.stamp())) { + return LogicConstantNode.contradiction(); } 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(getValue()) != null) { tool.replaceWithValue(LogicConstantNode.contradiction(graph())); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -32,15 +31,15 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "<<") -public final class LeftShiftNode extends ShiftNode implements Canonicalizable { +public final class LeftShiftNode extends ShiftNode { - public LeftShiftNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public LeftShiftNode(ValueNode x, ValueNode y) { + super(x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.leftShift(x().stamp(), y().stamp())); + return updateStamp(StampTool.leftShift(getX().stamp(), getY().stamp())); } @Override @@ -55,39 +54,39 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - int amount = y().asConstant().asInt(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + int amount = forY.asConstant().asInt(); int originalAmout = amount; int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { - return x(); + return forX; } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; + if (forX instanceof ShiftNode) { + ShiftNode other = (ShiftNode) forX; + if (other.getY().isConstant()) { + int otherAmount = other.getY().asConstant().asInt() & mask; if (other instanceof LeftShiftNode) { int total = amount + otherAmount; if (total != (total & mask)) { - return ConstantNode.forIntegerKind(getKind(), 0, graph()); + return ConstantNode.forIntegerKind(getKind(), 0); } - return graph().unique(new LeftShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph()))); + return new LeftShiftNode(other.getX(), ConstantNode.forInt(total)); } else if ((other instanceof RightShiftNode || other instanceof UnsignedRightShiftNode) && otherAmount == amount) { if (getKind() == Kind.Long) { - return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forLong(-1L << amount, graph()))); + return new AndNode(other.getX(), ConstantNode.forLong(-1L << amount)); } else { assert getKind() == Kind.Int; - return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forInt(-1 << amount, graph()))); + return new AndNode(other.getX(), ConstantNode.forInt(-1 << amount)); } } } } if (originalAmout != amount) { - return graph().unique(new LeftShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph()))); + return new LeftShiftNode(forX, ConstantNode.forInt(amount)); } } return this; @@ -95,6 +94,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitShl(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitShl(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -62,20 +61,20 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode ret = canonicalConvert(); - if (ret != null) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode ret = canonicalConvert(forValue); + if (ret != this) { return ret; } - if (getValue() instanceof NarrowNode) { + if (forValue instanceof NarrowNode) { // zzzzzzzz yyyyxxxx -(narrow)-> yyyyxxxx -(narrow)-> xxxx // ==> zzzzzzzz yyyyxxxx -(narrow)-> xxxx - NarrowNode other = (NarrowNode) getValue(); - return graph().unique(new NarrowNode(other.getValue(), getResultBits())); - } else if (getValue() instanceof IntegerConvertNode) { + NarrowNode other = (NarrowNode) forValue; + return new NarrowNode(other.getValue(), getResultBits()); + } else if (forValue instanceof IntegerConvertNode) { // SignExtendNode or ZeroExtendNode - IntegerConvertNode other = (IntegerConvertNode) getValue(); + IntegerConvertNode other = (IntegerConvertNode) forValue; if (getResultBits() == other.getInputBits()) { // xxxx -(extend)-> yyyy xxxx -(narrow)-> xxxx // ==> no-op @@ -83,20 +82,19 @@ } else if (getResultBits() < other.getInputBits()) { // yyyyxxxx -(extend)-> zzzzzzzz yyyyxxxx -(narrow)-> xxxx // ==> yyyyxxxx -(narrow)-> xxxx - return graph().unique(new NarrowNode(other.getValue(), getResultBits())); + return new NarrowNode(other.getValue(), getResultBits()); } else { if (other instanceof SignExtendNode) { // sxxx -(sign-extend)-> ssssssss sssssxxx -(narrow)-> sssssxxx // ==> sxxx -(sign-extend)-> sssssxxx - return graph().unique(new SignExtendNode(other.getValue(), getResultBits())); + return new SignExtendNode(other.getValue(), getResultBits()); } else if (other instanceof ZeroExtendNode) { // xxxx -(zero-extend)-> 00000000 00000xxx -(narrow)-> 0000xxxx // ==> xxxx -(zero-extend)-> 0000xxxx - return graph().unique(new ZeroExtendNode(other.getValue(), getResultBits())); + return new ZeroExtendNode(other.getValue(), getResultBits()); } } } - return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -34,7 +33,7 @@ /** * The {@code NegateNode} node negates its operand. */ -public final class NegateNode extends UnaryNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode { +public final class NegateNode extends UnaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode { @Override public boolean inferStamp() { @@ -68,16 +67,16 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - return ConstantNode.forPrimitive(evalConst(getValue().asConstant()), graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + return ConstantNode.forConstant(evalConst(forValue.asConstant()), null); } - if (getValue() instanceof NegateNode) { - return ((NegateNode) getValue()).getValue(); + if (forValue instanceof NegateNode) { + return ((NegateNode) forValue).getValue(); } - if (getValue() instanceof IntegerSubNode) { - IntegerSubNode sub = (IntegerSubNode) getValue(); - return IntegerArithmeticNode.sub(graph(), sub.y(), sub.x()); + if (forValue instanceof IntegerSubNode) { + IntegerSubNode sub = (IntegerSubNode) forValue; + return new IntegerSubNode(sub.getY(), sub.getX()); } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -50,15 +51,21 @@ } @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + // nothing to do + return this; + } + + @Override public void lower(LoweringTool tool) { LogicNode equalComp; LogicNode lessComp; - if (x().stamp() instanceof FloatStamp) { - equalComp = graph().unique(new FloatEqualsNode(x(), y())); - lessComp = graph().unique(new FloatLessThanNode(x(), y(), isUnorderedLess)); + if (getX().stamp() instanceof FloatStamp) { + equalComp = graph().unique(new FloatEqualsNode(getX(), getY())); + lessComp = graph().unique(new FloatLessThanNode(getX(), getY(), isUnorderedLess)); } else { - equalComp = graph().unique(new IntegerEqualsNode(x(), y())); - lessComp = graph().unique(new IntegerLessThanNode(x(), y())); + equalComp = graph().unique(new IntegerEqualsNode(getX(), getY())); + lessComp = graph().unique(new IntegerLessThanNode(getX(), getY())); } ConditionalNode equalValue = graph().unique(new ConditionalNode(equalComp, ConstantNode.forInt(0, graph()), ConstantNode.forInt(1, graph()))); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -34,7 +33,7 @@ /** * Binary negation of long or integer values. */ -public final class NotNode extends UnaryNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode { +public final class NotNode extends UnaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode { @Override public boolean inferStamp() { @@ -57,12 +56,12 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - return ConstantNode.forPrimitive(evalConst(getValue().asConstant()), graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + return ConstantNode.forConstant(evalConst(forValue.asConstant()), null); } - if (getValue() instanceof NotNode) { - return ((NotNode) getValue()).getValue(); + if (forValue instanceof NotNode) { + return ((NotNode) forValue).getValue(); } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -58,26 +57,20 @@ } @Override - public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) { - if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { - return TriState.TRUE; - } else if (forX.stamp().alwaysDistinct(forY.stamp())) { - return TriState.FALSE; - } else { - return super.evaluate(constantReflection, forX, forY); - } - } - - @Override - public Node canonical(CanonicalizerTool tool) { - Node result = super.canonical(tool); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = super.canonical(tool, forX, forY); if (result != this) { return result; } - if (StampTool.isObjectAlwaysNull(x())) { - return graph().unique(new IsNullNode(y())); - } else if (StampTool.isObjectAlwaysNull(y())) { - return graph().unique(new IsNullNode(x())); + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return LogicConstantNode.tautology(); + } else if (forX.stamp().alwaysDistinct(forY.stamp())) { + return LogicConstantNode.contradiction(); + } + if (StampTool.isObjectAlwaysNull(forX)) { + return new IsNullNode(forY); + } else if (StampTool.isObjectAlwaysNull(forY)) { + return new IsNullNode(forX); } return this; } @@ -103,15 +96,15 @@ @Override public void virtualize(VirtualizerTool tool) { - State stateX = tool.getObjectState(x()); - State stateY = tool.getObjectState(y()); + State stateX = tool.getObjectState(getX()); + State stateY = tool.getObjectState(getY()); boolean xVirtual = stateX != null && stateX.getState() == EscapeState.Virtual; boolean yVirtual = stateY != null && stateY.getState() == EscapeState.Virtual; if (xVirtual && !yVirtual) { - virtualizeNonVirtualComparison(stateX, stateY != null ? stateY.getMaterializedValue() : y(), tool); + virtualizeNonVirtualComparison(stateX, stateY != null ? stateY.getMaterializedValue() : getY(), tool); } else if (!xVirtual && yVirtual) { - virtualizeNonVirtualComparison(stateY, stateX != null ? stateX.getMaterializedValue() : x(), tool); + virtualizeNonVirtualComparison(stateY, stateX != null ? stateX.getMaterializedValue() : getX(), tool); } else if (xVirtual && yVirtual) { boolean xIdentity = stateX.getVirtualObject().hasIdentity(); boolean yIdentity = stateY.getVirtualObject().hasIdentity(); @@ -119,7 +112,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */ diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -30,17 +30,19 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "|") -public final class OrNode extends BitLogicNode implements Canonicalizable { +public final class OrNode extends BitLogicNode { - public OrNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public OrNode(ValueNode x, ValueNode y) { + super(StampTool.or(x.stamp(), y.stamp()), x, y); + assert x.stamp().isCompatible(y.stamp()); } @Override public boolean inferStamp() { - return updateStamp(StampTool.or(x().stamp(), y().stamp())); + return updateStamp(StampTool.or(getX().stamp(), getY().stamp())); } @Override @@ -50,31 +52,31 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return x(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return forX; } - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new OrNode(stamp(), y(), x())); + if (forX.isConstant() && !forY.isConstant()) { + return new OrNode(forY, forX); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long rawY = y().asConstant().asLong(); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long rawY = forY.asConstant().asLong(); long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp())); if ((rawY & mask) == mask) { - return ConstantNode.forIntegerStamp(stamp(), mask, graph()); + return ConstantNode.forIntegerStamp(stamp(), mask); } if ((rawY & mask) == 0) { - return x(); + return forX; } - return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitOr(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitOr(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -25,7 +25,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -36,7 +35,7 @@ * of a primitive value to some other incompatible stamp. The new stamp must have the same width as * the old stamp. */ -public class ReinterpretNode extends UnaryNode implements Canonicalizable, ArithmeticLIRLowerable { +public class ReinterpretNode extends UnaryNode implements ArithmeticLIRLowerable { private ReinterpretNode(Kind to, ValueNode value) { this(StampFactory.forKind(to), value); @@ -81,16 +80,16 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - return ConstantNode.forPrimitive(evalConst(getValue().asConstant()), graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + return ConstantNode.forConstant(evalConst(forValue.asConstant()), null); } - if (stamp().isCompatible(getValue().stamp())) { - return getValue(); + if (stamp().isCompatible(forValue.stamp())) { + return forValue; } - if (getValue() instanceof ReinterpretNode) { - ReinterpretNode reinterpret = (ReinterpretNode) getValue(); - return getValue().graph().unique(new ReinterpretNode(stamp(), reinterpret.getValue())); + if (forValue instanceof ReinterpretNode) { + ReinterpretNode reinterpret = (ReinterpretNode) forValue; + return new ReinterpretNode(stamp(), reinterpret.getValue()); } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,10 +31,10 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = ">>") -public final class RightShiftNode extends ShiftNode implements Canonicalizable { +public final class RightShiftNode extends ShiftNode { - public RightShiftNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public RightShiftNode(ValueNode x, ValueNode y) { + super(x, y); } @Override @@ -49,35 +49,35 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { - return graph().unique(new UnsignedRightShiftNode(stamp(), x(), y())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.stamp() instanceof IntegerStamp && ((IntegerStamp) forX.stamp()).isPositive()) { + return new UnsignedRightShiftNode(forX, forY); } - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - int amount = y().asConstant().asInt(); + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + int amount = forY.asConstant().asInt(); int originalAmout = amount; int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { - return x(); + return forX; } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; + if (forX instanceof ShiftNode) { + ShiftNode other = (ShiftNode) forX; + if (other.getY().isConstant()) { + int otherAmount = other.getY().asConstant().asInt() & mask; if (other instanceof RightShiftNode) { int total = amount + otherAmount; if (total != (total & mask)) { - assert other.x().stamp() instanceof IntegerStamp; - IntegerStamp istamp = (IntegerStamp) other.x().stamp(); + assert other.getX().stamp() instanceof IntegerStamp; + IntegerStamp istamp = (IntegerStamp) other.getX().stamp(); if (istamp.isPositive()) { - return ConstantNode.forIntegerKind(getKind(), 0, graph()); + return ConstantNode.forIntegerKind(getKind(), 0); } if (istamp.isStrictlyNegative()) { - return ConstantNode.forIntegerKind(getKind(), -1L, graph()); + return ConstantNode.forIntegerKind(getKind(), -1L); } /* @@ -85,14 +85,14 @@ * full shift for this kind */ assert total >= mask; - return graph().unique(new RightShiftNode(stamp(), other.x(), ConstantNode.forInt(mask, graph()))); + return new RightShiftNode(other.getX(), ConstantNode.forInt(mask)); } - return graph().unique(new RightShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph()))); + return new RightShiftNode(other.getX(), ConstantNode.forInt(total)); } } } if (originalAmout != amount) { - return graph().unique(new RightShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph()))); + return new RightShiftNode(forX, ConstantNode.forInt(amount)); } } return this; @@ -100,6 +100,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitShr(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitShr(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,12 +33,13 @@ /** * Creates a new shift operation. - * + * * @param x the first input value * @param s the second input value */ - public ShiftNode(Stamp stamp, ValueNode x, ValueNode s) { - super(stamp, x, s); + public ShiftNode(ValueNode x, ValueNode s) { + super(x.stamp().unrestricted(), x, s); + assert s.getKind() == Kind.Int; } public int getShiftAmountMask() { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -68,32 +67,32 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode ret = canonicalConvert(); - if (ret != null) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode ret = canonicalConvert(forValue); + if (ret != this) { return ret; } - if (getValue() instanceof SignExtendNode) { + if (forValue instanceof SignExtendNode) { // sxxx -(sign-extend)-> ssss sxxx -(sign-extend)-> ssssssss sssssxxx // ==> sxxx -(sign-extend)-> ssssssss sssssxxx - SignExtendNode other = (SignExtendNode) getValue(); - return graph().unique(new SignExtendNode(other.getValue(), getResultBits())); - } else if (getValue() instanceof ZeroExtendNode) { - ZeroExtendNode other = (ZeroExtendNode) getValue(); + SignExtendNode other = (SignExtendNode) forValue; + return new SignExtendNode(other.getValue(), getResultBits()); + } else if (forValue instanceof ZeroExtendNode) { + ZeroExtendNode other = (ZeroExtendNode) forValue; if (other.getResultBits() > other.getInputBits()) { // sxxx -(zero-extend)-> 0000 sxxx -(sign-extend)-> 00000000 0000sxxx // ==> sxxx -(zero-extend)-> 00000000 0000sxxx - return graph().unique(new ZeroExtendNode(other.getValue(), getResultBits())); + return new ZeroExtendNode(other.getValue(), getResultBits()); } } - if (getValue().stamp() instanceof IntegerStamp) { - IntegerStamp inputStamp = (IntegerStamp) getValue().stamp(); + if (forValue.stamp() instanceof IntegerStamp) { + IntegerStamp inputStamp = (IntegerStamp) forValue.stamp(); if ((inputStamp.upMask() & (1L << (getInputBits() - 1))) == 0L) { // 0xxx -(sign-extend)-> 0000 0xxx // ==> 0xxx -(zero-extend)-> 0000 0xxx - return graph().unique(new ZeroExtendNode(getValue(), getResultBits())); + return new ZeroExtendNode(forValue, getResultBits()); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -23,13 +23,14 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; /** * The {@code UnaryNode} class is the base of arithmetic and bit logic operations with exactly one * input. */ -public abstract class UnaryNode extends FloatingNode { +public abstract class UnaryNode extends FloatingNode implements Canonicalizable.Unary { @Input private ValueNode value; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -31,34 +30,27 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "|/|") -public class UnsignedDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { +public class UnsignedDivNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - /** - * Used by {@code NodeIntrinsic} in {@code UnsignedMathSubstitutions}. - */ - private UnsignedDivNode(Kind kind, ValueNode x, ValueNode y) { - this(StampFactory.forKind(kind), x, y); - } - - public UnsignedDivNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public UnsignedDivNode(ValueNode x, ValueNode y) { + super(x.stamp().unrestricted(), x, y); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - long yConst = y().asConstant().asLong(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + long yConst = forY.asConstant().asLong(); if (yConst == 0) { return this; // this will trap, cannot canonicalize } - return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.divide(x().asConstant().asLong(), yConst), graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.divide(forX.asConstant().asLong(), yConst)); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1) { - return x(); + return forX; } if (CodeUtil.isPowerOf2(c)) { - return graph().unique(new UnsignedRightShiftNode(stamp(), x(), ConstantNode.forInt(CodeUtil.log2(c), graph()))); + return new UnsignedRightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(c))); } } return this; @@ -71,17 +63,17 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitUDiv(gen.operand(x()), gen.operand(y()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().emitUDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override public boolean canDeoptimize() { - return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); + return !(getY().stamp() instanceof IntegerStamp) || ((IntegerStamp) getY().stamp()).contains(0); } @NodeIntrinsic - public static native int unsignedDivide(@ConstantNodeParameter Kind kind, int a, int b); + public static native int unsignedDivide(int a, int b); @NodeIntrinsic - public static native long unsignedDivide(@ConstantNodeParameter Kind kind, long a, long b); + public static native long unsignedDivide(long a, long b); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -31,33 +30,26 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "|%|") -public class UnsignedRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { +public class UnsignedRemNode extends FixedBinaryNode implements Lowerable, LIRLowerable { - /** - * Used by {@code NodeIntrinsic} in {@code UnsignedMathSubstitutions}. - */ - private UnsignedRemNode(Kind kind, ValueNode x, ValueNode y) { - this(StampFactory.forKind(kind), x, y); - } - - public UnsignedRemNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public UnsignedRemNode(ValueNode x, ValueNode y) { + super(x.stamp().unrestricted(), x, y); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - long yConst = y().asConstant().asLong(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + long yConst = forY.asConstant().asLong(); if (yConst == 0) { return this; // this will trap, cannot canonicalize } - return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.remainder(x().asConstant().asLong(), yConst), graph()); - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + return ConstantNode.forIntegerStamp(stamp(), UnsignedMath.remainder(forX.asConstant().asLong(), yConst)); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + return ConstantNode.forIntegerStamp(stamp(), 0); } else if (CodeUtil.isPowerOf2(c)) { - return graph().unique(new AndNode(stamp(), x(), ConstantNode.forIntegerStamp(stamp(), c - 1, graph()))); + return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), c - 1)); } } return this; @@ -70,17 +62,17 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.setResult(this, gen.getLIRGeneratorTool().emitURem(gen.operand(x()), gen.operand(y()), gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().emitURem(gen.operand(getX()), gen.operand(getY()), gen.state(this))); } @Override public boolean canDeoptimize() { - return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); + return !(getY().stamp() instanceof IntegerStamp) || ((IntegerStamp) getY().stamp()).contains(0); } @NodeIntrinsic - public static native int unsignedRemainder(@ConstantNodeParameter Kind kind, int a, int b); + public static native int unsignedRemainder(int a, int b); @NodeIntrinsic - public static native long unsignedRemainder(@ConstantNodeParameter Kind kind, long a, long b); + public static native long unsignedRemainder(long a, long b); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; @@ -32,15 +31,15 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = ">>>") -public final class UnsignedRightShiftNode extends ShiftNode implements Canonicalizable { +public final class UnsignedRightShiftNode extends ShiftNode { - public UnsignedRightShiftNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public UnsignedRightShiftNode(ValueNode x, ValueNode y) { + super(x, y); } @Override public boolean inferStamp() { - return updateStamp(StampTool.unsignedRightShift(x().stamp(), y().stamp())); + return updateStamp(StampTool.unsignedRightShift(getX().stamp(), getY().stamp())); } @Override @@ -55,39 +54,39 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && y().isConstant()) { - return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - int amount = y().asConstant().asInt(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && forY.isConstant()) { + return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + int amount = forY.asConstant().asInt(); int originalAmout = amount; int mask = getShiftAmountMask(); amount &= mask; if (amount == 0) { - return x(); + return forX; } - if (x() instanceof ShiftNode) { - ShiftNode other = (ShiftNode) x(); - if (other.y().isConstant()) { - int otherAmount = other.y().asConstant().asInt() & mask; + if (forX instanceof ShiftNode) { + ShiftNode other = (ShiftNode) forX; + if (other.getY().isConstant()) { + int otherAmount = other.getY().asConstant().asInt() & mask; if (other instanceof UnsignedRightShiftNode) { int total = amount + otherAmount; if (total != (total & mask)) { - return ConstantNode.forIntegerKind(getKind(), 0, graph()); + return ConstantNode.forIntegerKind(getKind(), 0); } - return graph().unique(new UnsignedRightShiftNode(stamp(), other.x(), ConstantNode.forInt(total, graph()))); + return new UnsignedRightShiftNode(other.getX(), ConstantNode.forInt(total)); } else if (other instanceof LeftShiftNode && otherAmount == amount) { if (getKind() == Kind.Long) { - return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forLong(-1L >>> amount, graph()))); + return new AndNode(other.getX(), ConstantNode.forLong(-1L >>> amount)); } else { assert getKind() == Kind.Int; - return graph().unique(new AndNode(stamp(), other.x(), ConstantNode.forInt(-1 >>> amount, graph()))); + return new AndNode(other.getX(), ConstantNode.forInt(-1 >>> amount)); } } } } if (originalAmout != amount) { - return graph().unique(new UnsignedRightShiftNode(stamp(), x(), ConstantNode.forInt(amount, graph()))); + return new UnsignedRightShiftNode(forX, ConstantNode.forInt(amount)); } } return this; @@ -95,6 +94,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitUShr(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitUShr(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -30,17 +30,19 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "^") -public final class XorNode extends BitLogicNode implements Canonicalizable { +public final class XorNode extends BitLogicNode { - public XorNode(Stamp stamp, ValueNode x, ValueNode y) { - super(stamp, x, y); + public XorNode(ValueNode x, ValueNode y) { + super(StampTool.xor(x.stamp(), y.stamp()), x, y); + assert x.stamp().isCompatible(y.stamp()); } @Override public boolean inferStamp() { - return updateStamp(StampTool.xor(x().stamp(), y().stamp())); + return updateStamp(StampTool.xor(getX().stamp(), getY().stamp())); } @Override @@ -50,30 +52,30 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return ConstantNode.forIntegerStamp(stamp(), 0); } - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new XorNode(stamp(), y(), x())); + if (forX.isConstant() && !forY.isConstant()) { + return new XorNode(forY, forX); } - if (x().isConstant()) { - return ConstantNode.forPrimitive(stamp(), evalConst(x().asConstant(), y().asConstant()), graph()); - } else if (y().isConstant()) { - long rawY = y().asConstant().asLong(); + if (forX.isConstant()) { + return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant())); + } else if (forY.isConstant()) { + long rawY = forY.asConstant().asLong(); long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp())); if ((rawY & mask) == 0) { - return x(); + return forX; } else if ((rawY & mask) == mask) { - return graph().unique(new NotNode(x())); + return new NotNode(forX); } - return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); + return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } return this; } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitXor(builder.operand(x()), builder.operand(y()))); + builder.setResult(this, gen.emitXor(builder.operand(getX()), builder.operand(getY()))); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -25,7 +25,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -78,20 +77,20 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - ValueNode ret = canonicalConvert(); - if (ret != null) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode ret = canonicalConvert(forValue); + if (ret != this) { return ret; } - if (getValue() instanceof ZeroExtendNode) { + if (forValue instanceof ZeroExtendNode) { // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx // ==> xxxx -(zero-extend)-> 00000000 0000xxxx - ZeroExtendNode other = (ZeroExtendNode) getValue(); - return graph().unique(new ZeroExtendNode(other.getValue(), getResultBits())); + ZeroExtendNode other = (ZeroExtendNode) forValue; + return new ZeroExtendNode(other.getValue(), getResultBits()); } - if (getValue() instanceof NarrowNode) { - NarrowNode narrow = (NarrowNode) getValue(); + if (forValue instanceof NarrowNode) { + NarrowNode narrow = (NarrowNode) forValue; Stamp inputStamp = narrow.getValue().stamp(); if (inputStamp instanceof IntegerStamp && inputStamp.isCompatible(stamp())) { IntegerStamp istamp = (IntegerStamp) inputStamp; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -39,7 +38,7 @@ * This node represents the boxing of a primitive value. This corresponds to a call to the valueOf * methods in Integer, Long, etc. */ -public class BoxNode extends UnaryNode implements VirtualizableAllocation, Lowerable, Canonicalizable { +public class BoxNode extends UnaryNode implements VirtualizableAllocation, Lowerable { private final Kind boxingKind; @@ -58,14 +57,11 @@ } @Override - public Node canonical(CanonicalizerTool tool) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { /* * Constant values are not canonicalized into their constant boxing objects because this * would mean that the information that they came from a valueOf is lost. */ - if (usages().isEmpty()) { - return null; - } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -35,7 +34,7 @@ * the if node's taken probability. Then the branch probability node will be removed. This node is * intended primarily for snippets, so that they can define their fast and slow paths. */ -public class BranchProbabilityNode extends FloatingNode implements Canonicalizable, Lowerable { +public class BranchProbabilityNode extends FloatingNode implements Simplifiable, Lowerable { public static final double LIKELY_PROBABILITY = 0.6; public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY; @@ -67,7 +66,7 @@ } @Override - public Node canonical(CanonicalizerTool tool) { + public void simplify(SimplifierTool tool) { if (probability.isConstant()) { double probabilityValue = probability.asConstant().asDouble(); if (probabilityValue < 0.0) { @@ -78,9 +77,9 @@ boolean couldSet = false; for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) { if (node.condition() == Condition.EQ) { - ValueNode other = node.x(); - if (node.x() == this) { - other = node.y(); + ValueNode other = node.getX(); + if (node.getX() == this) { + other = node.getY(); } if (other.isConstant()) { double probabilityToSet = probabilityValue; @@ -94,15 +93,15 @@ } } } - if (!couldSet) { - if (isSubstitutionGraph()) { - return this; + if (couldSet) { + replaceAndDelete(condition); + tool.addToWorkList(condition.usages()); + } else { + if (!isSubstitutionGraph()) { + throw new GraalInternalError("Wrong usage of branch probability injection!"); } - throw new GraalInternalError("Wrong usage of branch probability injection!"); } - return condition; } - return this; } private boolean isSubstitutionGraph() { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,7 +25,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,23 +33,23 @@ * Loads an object's {@linkplain Representation#ObjectHub hub}. The object is not null-checked by * this operation. */ -public final class LoadHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, Virtualizable { +public final class LoadHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable.Unary, Virtualizable { - @Input private ValueNode object; + @Input private ValueNode value; - public ValueNode object() { - return object; + public ValueNode getValue() { + return value; } - public LoadHubNode(ValueNode object, Kind kind) { + public LoadHubNode(ValueNode value, Kind kind) { super(getKind(kind), null); - this.object = object; + this.value = value; } - public LoadHubNode(ValueNode object, Kind kind, ValueNode guard) { + public LoadHubNode(ValueNode value, Kind kind, ValueNode guard) { super(getKind(kind), (GuardingNode) guard); - assert object != guard; - this.object = object; + assert value != guard; + this.value = value; } private static Stamp getKind(Kind kind) { @@ -63,10 +62,10 @@ } @Override - public Node canonical(CanonicalizerTool tool) { + public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) { MetaAccessProvider metaAccess = tool.getMetaAccess(); - if (metaAccess != null && object.stamp() instanceof ObjectStamp) { - ObjectStamp stamp = (ObjectStamp) object.stamp(); + if (metaAccess != null && forObject.stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) forObject.stamp(); ResolvedJavaType exactType; if (stamp.isExactType()) { @@ -81,7 +80,7 @@ } if (exactType != null) { - return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), metaAccess, graph()); + return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), metaAccess); } } return this; @@ -89,7 +88,7 @@ @Override public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object); + State state = tool.getObjectState(value); if (state != null) { Constant constantHub = state.getVirtualObject().type().getEncoding(Representation.ObjectHub); tool.replaceWithValue(ConstantNode.forConstant(constantHub, tool.getMetaAccessProvider(), graph())); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -61,7 +61,7 @@ @Override public Node canonical(CanonicalizerTool tool) { if (hub instanceof LoadHubNode) { - ValueNode object = ((LoadHubNode) hub).object(); + ValueNode object = ((LoadHubNode) hub).getValue(); ResolvedJavaType type = StampTool.typeOrNull(object); if (StampTool.isExactType(object)) { return resolveExactMethod(tool, type); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,13 +24,12 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -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.*; -public class UnboxNode extends UnaryNode implements Virtualizable, Lowerable, Canonicalizable { +public class UnboxNode extends UnaryNode implements Virtualizable, Lowerable { private final Kind boxingKind; @@ -61,22 +60,19 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - Constant constant = getValue().asConstant(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + Constant constant = forValue.asConstant(); Constant unboxed = tool.getConstantReflection().unboxPrimitive(constant); if (unboxed != null && unboxed.getKind() == boxingKind) { - return ConstantNode.forConstant(unboxed, tool.getMetaAccess(), graph()); + return ConstantNode.forConstant(unboxed, tool.getMetaAccess()); } - } else if (getValue() instanceof BoxNode) { - BoxNode box = (BoxNode) getValue(); + } else if (forValue instanceof BoxNode) { + BoxNode box = (BoxNode) forValue; if (boxingKind == box.getBoxingKind()) { return box.getValue(); } } - if (usages().isEmpty()) { - return null; - } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; 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.spi.*; @@ -33,7 +32,7 @@ * Implements a type check where the type being checked is loaded at runtime. This is used, for * instance, to implement an object array store check. */ -public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable, Lowerable { +public final class CheckCastDynamicNode extends FixedWithNextNode implements Canonicalizable.Binary, Lowerable { @Input private ValueNode object; @Input private ValueNode hub; @@ -55,6 +54,25 @@ this.forStoreCheck = forStoreCheck; } + public ValueNode object() { + return object; + } + + /** + * Gets the runtime-loaded type being cast to. + */ + public ValueNode hub() { + return hub; + } + + public ValueNode getX() { + return object; + } + + public ValueNode getY() { + return hub; + } + public boolean isForStoreCheck() { return forStoreCheck; } @@ -70,32 +88,19 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - assert object() != null : this; - - if (StampTool.isObjectAlwaysNull(object())) { - return object(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject, ValueNode forHub) { + if (StampTool.isObjectAlwaysNull(forObject)) { + return forObject; } - if (hub.isConstant()) { - ResolvedJavaType t = tool.getConstantReflection().asJavaType(hub.asConstant()); + if (forHub.isConstant()) { + ResolvedJavaType t = tool.getConstantReflection().asJavaType(forHub.asConstant()); if (t != null) { - return graph().add(new CheckCastNode(t, object(), null, forStoreCheck)); + return graph().add(new CheckCastNode(t, forObject, null, forStoreCheck)); } } return this; } - public ValueNode object() { - return object; - } - - /** - * Gets the runtime-loaded type being cast to. - */ - public ValueNode hub() { - return hub; - } - @NodeIntrinsic public static native T checkCastDynamic(Class type, Object object, @ConstantNodeParameter boolean forStoreCheck); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; 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.spi.*; @@ -34,7 +33,7 @@ * known at compile time. This is used, for instance, to intrinsify {@link Class#isInstance(Object)} * . */ -public final class InstanceOfDynamicNode extends LogicNode implements Canonicalizable, Lowerable { +public final class InstanceOfDynamicNode extends LogicNode implements Canonicalizable.Binary, Lowerable { @Input private ValueNode object; @Input private ValueNode mirror; @@ -56,16 +55,14 @@ tool.getLowerer().lower(this, tool); } - @Override - public Node canonical(CanonicalizerTool tool) { - assert object() != null : this; - if (mirror().isConstant()) { - ResolvedJavaType t = tool.getConstantReflection().asJavaType(mirror().asConstant()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject, ValueNode forMirror) { + if (forMirror.isConstant()) { + ResolvedJavaType t = tool.getConstantReflection().asJavaType(forMirror.asConstant()); if (t != null) { if (t.isPrimitive()) { - return LogicConstantNode.contradiction(graph()); + return LogicConstantNode.contradiction(); } else { - return graph().unique(new InstanceOfNode(t, object(), null)); + return new InstanceOfNode(t, forObject, null); } } } @@ -79,4 +76,12 @@ public ValueNode mirror() { return mirror; } + + public ValueNode getX() { + return object; + } + + public ValueNode getY() { + return mirror; + } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,9 +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.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -34,7 +32,7 @@ /** * The {@code InstanceOfNode} represents an instanceof test. */ -public class InstanceOfNode extends UnaryOpLogicNode implements Canonicalizable, Lowerable, Virtualizable { +public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { private final ResolvedJavaType type; private JavaTypeProfile profile; @@ -58,40 +56,14 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - 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(); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + Stamp stamp = forValue.stamp(); if (!(stamp instanceof ObjectStamp)) { - return TriState.UNKNOWN; + return this; } ObjectStamp objectStamp = (ObjectStamp) stamp; if (objectStamp.alwaysNull()) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } ResolvedJavaType stampType = objectStamp.type(); @@ -100,25 +72,32 @@ if (subType) { if (objectStamp.nonNull()) { // the instanceOf matches, so return true - return TriState.TRUE; + return LogicConstantNode.tautology(); } } 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 TriState.FALSE; + return LogicConstantNode.contradiction(); } else { boolean superType = stampType.isAssignableFrom(type()); if (!superType && !stampType.isInterface() && !type().isInterface()) { - return TriState.FALSE; + return LogicConstantNode.contradiction(); } // 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 TriState.UNKNOWN; + 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. + return new LogicNegationNode(new IsNullNode(forValue)); + } + } + return this; } /** @@ -138,7 +117,7 @@ @Override public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object()); + State state = tool.getObjectState(getValue()); if (state != null) { tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -37,7 +37,7 @@ * The {@code LoadFieldNode} represents a read of a static or instance field. */ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, VirtualizableRoot { +public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable.Unary, VirtualizableRoot { /** * Creates a new LoadFieldNode instance. @@ -49,6 +49,10 @@ super(createStamp(field), object, field); } + public ValueNode getValue() { + return object(); + } + private static Stamp createStamp(ResolvedJavaField field) { Kind kind = field.getKind(); if (kind == Kind.Object && field.getType() instanceof ResolvedJavaType) { @@ -60,22 +64,26 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (usages().isEmpty() && !isVolatile() && (isStatic() || StampTool.isObjectNonNull(object().stamp()))) { + return canonical(tool, getValue()); + } + + public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) { + if (usages().isEmpty() && !isVolatile() && (isStatic() || StampTool.isObjectNonNull(forObject.stamp()))) { return null; } MetaAccessProvider metaAccess = tool.getMetaAccess(); if (tool.canonicalizeReads() && metaAccess != null) { - ConstantNode constant = asConstant(metaAccess); + ConstantNode constant = asConstant(metaAccess, forObject); if (constant != null) { return constant; } - PhiNode phi = asPhi(metaAccess); + PhiNode phi = asPhi(metaAccess, forObject); if (phi != null) { return phi; } } - if (!isStatic() && object().isNullConstant()) { - return graph().add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.NullCheckException)); + if (!isStatic() && forObject.isNullConstant()) { + return new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.NullCheckException); } return this; } @@ -83,22 +91,22 @@ /** * Gets a constant value for this load if possible. */ - public ConstantNode asConstant(MetaAccessProvider metaAccess) { + public ConstantNode asConstant(MetaAccessProvider metaAccess, ValueNode forObject) { Constant constant = null; if (isStatic()) { constant = field().readConstantValue(null); - } else if (object().isConstant() && !object().isNullConstant()) { - constant = field().readConstantValue(object().asConstant()); + } else if (forObject.isConstant() && !forObject.isNullConstant()) { + constant = field().readConstantValue(forObject.asConstant()); } if (constant != null) { - return ConstantNode.forConstant(constant, metaAccess, graph()); + return ConstantNode.forConstant(constant, metaAccess); } return null; } - private PhiNode asPhi(MetaAccessProvider metaAccess) { - if (!isStatic() && field.isFinal() && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(isNotA(ConstantNode.class)).isEmpty()) { - PhiNode phi = (PhiNode) object(); + private PhiNode asPhi(MetaAccessProvider metaAccess, ValueNode forObject) { + if (!isStatic() && field.isFinal() && forObject instanceof ValuePhiNode && ((ValuePhiNode) forObject).values().filter(isNotA(ConstantNode.class)).isEmpty()) { + PhiNode phi = (PhiNode) forObject; Constant[] constants = new Constant[phi.valueCount()]; for (int i = 0; i < phi.valueCount(); i++) { Constant constantValue = field().readConstantValue(phi.valueAt(i).asConstant()); @@ -107,11 +115,11 @@ } constants[i] = constantValue; } - PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(stamp(), phi.merge())); + ConstantNode[] constantNodes = new ConstantNode[phi.valueCount()]; for (int i = 0; i < phi.valueCount(); i++) { - newPhi.addInput(ConstantNode.forConstant(constants[i], metaAccess, graph())); + constantNodes[i] = ConstantNode.forConstant(constants[i], metaAccess); } - return newPhi; + return new ValuePhiNode(stamp(), phi.merge(), constantNodes); } return null; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -121,8 +121,8 @@ tool.addToWorkList(blockSuccessor(survivingEdge)); graph().removeSplit(this, blockSuccessor(survivingEdge)); } - if (value() instanceof LoadHubNode && ((LoadHubNode) value()).object().stamp() instanceof ObjectStamp) { - ObjectStamp stamp = (ObjectStamp) ((LoadHubNode) value()).object().stamp(); + if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(); if (stamp.type() != null) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,12 +24,15 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.Graph.NodeChangedListener; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.Binary; +import com.oracle.graal.graph.spi.Canonicalizable.Unary; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.util.*; @@ -229,11 +232,50 @@ return result; } + private static AutoCloseable getCanonicalizeableContractAssertion(Node node) { + boolean needsAssertion = false; + assert (needsAssertion = true) == true; + if (needsAssertion) { + Mark mark = node.graph().getMark(); + return () -> { + assert mark.equals(node.graph().getMark()) : "new node created while canonicalizing " + node.getClass().getSimpleName() + " " + node + ": " + + node.graph().getNewNodes(mark).snapshot(); + }; + } else { + return new AutoCloseable() { + public void close() throws Exception { + // nothing to do + } + }; + } + } + public boolean baseTryCanonicalize(final Node node, NodeClass nodeClass) { - if (nodeClass.isCanonicalizable()) { + if (nodeClass.getCanonicalizeMethod() != null) { METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("CanonicalizeNode", node)) { - Node canonical = node.canonical(tool); + Node canonical; + switch (nodeClass.getCanonicalizeMethod()) { + case BASE: + canonical = node.canonical(tool); + break; + case UNARY: + try (AutoCloseable verify = getCanonicalizeableContractAssertion(node)) { + @SuppressWarnings("unchecked") + Canonicalizable.Unary unary = (Unary) node; + canonical = unary.canonical(tool, unary.getValue()); + } + break; + case BINARY: + try (AutoCloseable verify = getCanonicalizeableContractAssertion(node)) { + @SuppressWarnings("unchecked") + Canonicalizable.Binary binary = (Binary) node; + canonical = binary.canonical(tool, binary.getX(), binary.getY()); + } + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected CanonicalizeMethod"); + } if (performReplacement(node, canonical)) { return true; } @@ -271,14 +313,19 @@ // -------------------------------------------- // X: must not happen (checked with assertions) // @formatter:on - private boolean performReplacement(final Node node, Node canonical) { - if (canonical == node) { + private boolean performReplacement(final Node node, Node newCanonical) { + if (newCanonical == node) { Debug.log("Canonicalizer: work on %1s", node); return false; } else { + Node canonical = newCanonical; Debug.log("Canonicalizer: replacing %1s with %1s", node, canonical); METRIC_CANONICALIZED_NODES.increment(); StructuredGraph graph = (StructuredGraph) node.graph(); + if (canonical != null && !canonical.isAlive()) { + assert !canonical.isDeleted(); + canonical = graph.addOrUniqueWithInputs(canonical); + } if (node instanceof FloatingNode) { if (canonical == null) { // case 1 diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -373,16 +373,16 @@ if (isTrue && condition instanceof InstanceOfNode) { InstanceOfNode instanceOf = (InstanceOfNode) condition; - ValueNode object = instanceOf.object(); + ValueNode object = instanceOf.getValue(); state.addNullness(false, object); state.addType(instanceOf.type(), object); } else if (condition instanceof IsNullNode) { IsNullNode nullCheck = (IsNullNode) condition; - state.addNullness(isTrue, nullCheck.object()); + state.addNullness(isTrue, nullCheck.getValue()); } else if (condition instanceof ObjectEqualsNode) { ObjectEqualsNode equals = (ObjectEqualsNode) condition; - ValueNode x = equals.x(); - ValueNode y = equals.y(); + ValueNode x = equals.getX(); + ValueNode y = equals.getY(); if (isTrue) { if (state.isNull(x) && !state.isNull(y)) { metricObjectEqualsRegistered.increment(); @@ -438,8 +438,8 @@ } } if (type != null) { - state.addNullness(false, loadHub.object()); - state.addType(type, loadHub.object()); + state.addNullness(false, loadHub.getValue()); + state.addType(type, loadHub.getValue()); } } } @@ -452,16 +452,16 @@ return null; } IntegerBelowThanNode below = (IntegerBelowThanNode) guard.condition(); - if (below.x().getKind() == Kind.Int && below.x().isConstant() && !below.y().isConstant()) { - Stamp stamp = StampTool.unsignedCompare(below.x().stamp(), below.y().stamp()); + if (below.getX().getKind() == Kind.Int && below.getX().isConstant() && !below.getY().isConstant()) { + Stamp stamp = StampTool.unsignedCompare(below.getX().stamp(), below.getY().stamp()); if (stamp != null) { - return new GuardedStamp(below.y(), stamp, guard); + return new GuardedStamp(below.getY(), stamp, guard); } } - if (below.y().getKind() == Kind.Int && below.y().isConstant() && !below.x().isConstant()) { - Stamp stamp = StampTool.unsignedCompare(below.x().stamp(), below.y().stamp()); + if (below.getY().getKind() == Kind.Int && below.getY().isConstant() && !below.getX().isConstant()) { + Stamp stamp = StampTool.unsignedCompare(below.getX().stamp(), below.getY().stamp()); if (stamp != null) { - return new GuardedStamp(below.x(), stamp, guard); + return new GuardedStamp(below.getX(), stamp, guard); } } } @@ -522,13 +522,13 @@ GuardNode existingGuard = null; if (guard.condition() instanceof IntegerBelowThanNode) { IntegerBelowThanNode below = (IntegerBelowThanNode) guard.condition(); - IntegerStamp xStamp = (IntegerStamp) below.x().stamp(); - IntegerStamp yStamp = (IntegerStamp) below.y().stamp(); - GuardedStamp cstamp = state.valueConstraints.get(below.x()); + IntegerStamp xStamp = (IntegerStamp) below.getX().stamp(); + IntegerStamp yStamp = (IntegerStamp) below.getY().stamp(); + GuardedStamp cstamp = state.valueConstraints.get(below.getX()); if (cstamp != null) { xStamp = (IntegerStamp) cstamp.getStamp(); } else { - cstamp = state.valueConstraints.get(below.y()); + cstamp = state.valueConstraints.get(below.getY()); if (cstamp != null) { yStamp = (IntegerStamp) cstamp.getStamp(); } @@ -552,10 +552,10 @@ } } else if (guard.condition() instanceof IntegerEqualsNode && guard.negated()) { IntegerEqualsNode equals = (IntegerEqualsNode) guard.condition(); - GuardedStamp cstamp = state.valueConstraints.get(equals.y()); - if (cstamp != null && equals.x().isConstant()) { + GuardedStamp cstamp = state.valueConstraints.get(equals.getY()); + if (cstamp != null && equals.getX().isConstant()) { IntegerStamp stamp = (IntegerStamp) cstamp.getStamp(); - if (!stamp.contains(equals.x().asConstant().asLong())) { + if (!stamp.contains(equals.getX().asConstant().asLong())) { // x != n is true if n is outside the range of the stamp existingGuard = cstamp.getGuard(); Debug.log("existing guard %s %1s proves !%1s", existingGuard, existingGuard.condition(), guard.condition()); @@ -620,7 +620,7 @@ } else { if (condition instanceof InstanceOfNode) { InstanceOfNode instanceOf = (InstanceOfNode) condition; - ValueNode object = instanceOf.object(); + ValueNode object = instanceOf.getValue(); if (state.isNull(object)) { metricInstanceOfRemoved.increment(); return falseValue; @@ -633,7 +633,7 @@ } } else if (condition instanceof IsNullNode) { IsNullNode isNull = (IsNullNode) condition; - ValueNode object = isNull.object(); + ValueNode object = isNull.getValue(); if (state.isNull(object)) { metricNullCheckRemoved.increment(); return trueValue; @@ -643,8 +643,8 @@ } } else if (condition instanceof ObjectEqualsNode) { ObjectEqualsNode equals = (ObjectEqualsNode) condition; - ValueNode x = equals.x(); - ValueNode y = equals.y(); + ValueNode x = equals.getX(); + ValueNode y = equals.getY(); if (state.isNull(x) && state.isNonNull(y) || state.isNonNull(x) && state.isNull(y)) { metricObjectEqualsRemoved.increment(); return falseValue; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -71,11 +71,11 @@ CompareNode compare = (CompareNode) fixedGuard.condition(); List mergePredecessors = merge.cfgPredecessors().snapshot(); - Constant[] xs = IfNode.constantValues(compare.x(), merge, true); + Constant[] xs = IfNode.constantValues(compare.getX(), merge, true); if (xs == null) { continue; } - Constant[] ys = IfNode.constantValues(compare.y(), merge, true); + Constant[] ys = IfNode.constantValues(compare.getY(), merge, true); if (ys == null) { continue; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -117,7 +117,7 @@ private void processGuard(Node node) { GuardNode guard = (GuardNode) node; if (guard.negated() && guard.condition() instanceof IsNullNode && (guard.getSpeculation() == null || guard.getSpeculation().equals(Constant.NULL_OBJECT))) { - ValueNode obj = ((IsNullNode) guard.condition()).object(); + ValueNode obj = ((IsNullNode) guard.condition()).getValue(); nullGuarded.put(obj, guard); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -157,7 +157,7 @@ IsNullNode isNullNode = (IsNullNode) condition; BeginNode nonTrappingContinuation = ifNode.falseSuccessor(); BeginNode trappingContinuation = ifNode.trueSuccessor(); - NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object())); + NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.getValue())); trappingNullCheck.setStateBefore(deopt.stateBefore()); deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java Wed Jun 25 17:34:25 2014 +0200 @@ -45,7 +45,7 @@ private static CastCheckExtractor extractCastCheckInfo(LogicNode x, LogicNode y) { if (x instanceof IsNullNode) { IsNullNode isNull = (IsNullNode) x; - ValueNode subject = isNull.object(); + ValueNode subject = isNull.getValue(); if (isInstanceOfCheckOn(y, subject)) { InstanceOfNode iOf = (InstanceOfNode) y; return new CastCheckExtractor(iOf.type(), subject); @@ -82,6 +82,6 @@ return false; } InstanceOfNode io = (InstanceOfNode) cond; - return io.object() == subject; + return io.getValue() == subject; } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Wed Jun 25 17:34:25 2014 +0200 @@ -27,10 +27,12 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -332,10 +334,32 @@ } FlowUtil.inferStampAndCheck(changed); added.add(changed); - ValueNode canon = (ValueNode) changed.canonical(tool); + + Node canon; + switch (changed.getNodeClass().getCanonicalizeMethod()) { + case BASE: + canon = changed.canonical(tool); + break; + case UNARY: + @SuppressWarnings("unchecked") + Canonicalizable.Unary unary = (Unary) changed; + canon = unary.canonical(tool, unary.getValue()); + break; + case BINARY: + @SuppressWarnings("unchecked") + Canonicalizable.Binary binary = (Binary) changed; + canon = binary.canonical(tool, binary.getX(), binary.getY()); + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected CanonicalizeMethod"); + } + if (canon != null && !canon.isAlive()) { + assert !canon.isDeleted(); + canon = graph.addOrUniqueWithInputs(canon); + } // might be already in `added`, no problem adding it again. - added.add(canon); - rememberSubstitution(f, canon); + added.add((ValueNode) canon); + rememberSubstitution(f, (ValueNode) canon); return canon; } @@ -445,7 +469,7 @@ * */ private LogicNode baseCaseInstanceOfNode(InstanceOfNode instanceOf) { - ValueNode scrutinee = GraphUtil.unproxify(instanceOf.object()); + ValueNode scrutinee = GraphUtil.unproxify(instanceOf.getValue()); if (!FlowUtil.hasLegalObjectStamp(scrutinee)) { return instanceOf; } @@ -470,7 +494,7 @@ * */ private FloatingNode baseCaseIsNullNode(IsNullNode isNu) { - ValueNode object = isNu.object(); + ValueNode object = isNu.getValue(); if (!FlowUtil.hasLegalObjectStamp(object)) { return isNu; } @@ -489,11 +513,11 @@ * otherwise the unmodified argument. */ private LogicNode baseCaseObjectEqualsNode(ObjectEqualsNode equals) { - if (!FlowUtil.hasLegalObjectStamp(equals.x()) || !FlowUtil.hasLegalObjectStamp(equals.y())) { + if (!FlowUtil.hasLegalObjectStamp(equals.getX()) || !FlowUtil.hasLegalObjectStamp(equals.getY())) { return equals; } - ValueNode x = GraphUtil.unproxify(equals.x()); - ValueNode y = GraphUtil.unproxify(equals.y()); + ValueNode x = GraphUtil.unproxify(equals.getX()); + ValueNode y = GraphUtil.unproxify(equals.getY()); if (state.isNull(x) && state.isNonNull(y) || state.isNonNull(x) && state.isNull(y)) { metricObjectEqualsRemoved.increment(); return falseConstant; diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Wed Jun 25 17:34:25 2014 +0200 @@ -234,7 +234,7 @@ return; } // it's unwarranted to assume loadHub.object() to be non-null - state.trackCC(loadHub.object(), type, begin); + state.trackCC(loadHub.getValue(), type, begin); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java Wed Jun 25 17:34:25 2014 +0200 @@ -359,7 +359,7 @@ return false; } IsNullNode isNull = (IsNullNode) cond; - return isNull.object() == subject; + return isNull.getValue() == subject; } /** diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Wed Jun 25 17:34:25 2014 +0200 @@ -647,7 +647,7 @@ } if (condition instanceof LogicNegationNode) { - addFact(!isTrue, ((LogicNegationNode) condition).getInput(), anchor); + addFact(!isTrue, ((LogicNegationNode) condition).getValue(), anchor); } else if (condition instanceof ShortCircuitOrNode) { /* * We can register the conditions being or-ed as long as the anchor is a fixed node, @@ -677,7 +677,7 @@ addFactInstanceOf(isTrue, (InstanceOfNode) condition, anchor); } else if (condition instanceof IsNullNode) { IsNullNode nullCheck = (IsNullNode) condition; - addNullness(isTrue, nullCheck.object(), anchor); + addNullness(isTrue, nullCheck.getValue(), anchor); } else if (condition instanceof ObjectEqualsNode) { addFactObjectEqualsNode(isTrue, (ObjectEqualsNode) condition, anchor); } else { @@ -692,7 +692,7 @@ * */ private void addFactInstanceOf(boolean isTrue, InstanceOfNode instanceOf, GuardingNode anchor) { - ValueNode object = instanceOf.object(); + ValueNode object = instanceOf.getValue(); if (isTrue) { if (knownNotToPassInstanceOf(object, instanceOf.type())) { impossiblePath(); @@ -710,15 +710,15 @@ } private void addFactObjectEqualsNode(boolean isTrue, ObjectEqualsNode equals, GuardingNode anchor) { - if (isDependencyTainted(equals.x(), anchor)) { + if (isDependencyTainted(equals.getX(), anchor)) { return; } - if (isDependencyTainted(equals.y(), anchor)) { + if (isDependencyTainted(equals.getY(), anchor)) { return; } assert anchor instanceof FixedNode; - ValueNode x = GraphUtil.unproxify(equals.x()); - ValueNode y = GraphUtil.unproxify(equals.y()); + ValueNode x = GraphUtil.unproxify(equals.getX()); + ValueNode y = GraphUtil.unproxify(equals.getY()); if (isTrue) { if (isNull(x) && isNonNull(y)) { impossiblePath(); @@ -730,12 +730,12 @@ } if (isNull(x) || isNull(y)) { metricObjectEqualsRegistered.increment(); - addNullness(true, equals.x(), anchor); - addNullness(true, equals.y(), anchor); + addNullness(true, equals.getX(), anchor); + addNullness(true, equals.getY(), anchor); } else if (isNonNull(x) || isNonNull(y)) { metricObjectEqualsRegistered.increment(); - addNullness(false, equals.x(), anchor); - addNullness(false, equals.y(), anchor); + addNullness(false, equals.getX(), anchor); + addNullness(false, equals.getY(), anchor); } Witness wx = typeInfo(x); Witness wy = typeInfo(y); @@ -748,8 +748,8 @@ if (best != null) { assert !best.isInterface(); // type tightening is enough, nullness already taken care of - trackCC(equals.x(), best, anchor); - trackCC(equals.y(), best, anchor); + trackCC(equals.getX(), best, anchor); + trackCC(equals.getY(), best, anchor); } } else if (wx == null) { typeRefinements.put(x, new Witness(wy)); @@ -759,10 +759,10 @@ } else { if (isNull(x) && !isNonNull(y)) { metricObjectEqualsRegistered.increment(); - addNullness(false, equals.y(), anchor); + addNullness(false, equals.getY(), anchor); } else if (!isNonNull(x) && isNull(y)) { metricObjectEqualsRegistered.increment(); - addNullness(false, equals.x(), anchor); + addNullness(false, equals.getX(), anchor); } } } @@ -911,20 +911,20 @@ private Evidence outcomeIsNullNode(boolean isTrue, IsNullNode isNullNode) { if (isTrue) { // grab an anchor attesting nullness - final GuardingNode replacement = nonTrivialNullAnchor(isNullNode.object()); + final GuardingNode replacement = nonTrivialNullAnchor(isNullNode.getValue()); if (replacement != null) { return new Evidence(replacement); } - if (isNonNull(isNullNode.object())) { + if (isNonNull(isNullNode.getValue())) { return Evidence.COUNTEREXAMPLE; } } else { // grab an anchor attesting non-nullness - final Witness w = typeInfo(isNullNode.object()); + final Witness w = typeInfo(isNullNode.getValue()); if (w != null && w.isNonNull()) { return new Evidence(w.guard()); } - if (isNull(isNullNode.object())) { + if (isNull(isNullNode.getValue())) { return Evidence.COUNTEREXAMPLE; } } @@ -936,9 +936,9 @@ * Utility method for {@link #outcome(boolean, com.oracle.graal.nodes.LogicNode)} */ private Evidence outcomeInstanceOfNode(boolean isTrue, InstanceOfNode iOf) { - final Witness w = typeInfo(iOf.object()); + final Witness w = typeInfo(iOf.getValue()); if (isTrue) { - if (isNull(iOf.object())) { + if (isNull(iOf.getValue())) { return Evidence.COUNTEREXAMPLE; } // grab an anchor attesting instanceof @@ -957,7 +957,7 @@ } else { // grab an anchor attesting not-instanceof // (1 of 2) attempt determining nullness - final GuardingNode nullGuard = nonTrivialNullAnchor(iOf.object()); + final GuardingNode nullGuard = nonTrivialNullAnchor(iOf.getValue()); if (nullGuard != null) { return new Evidence(nullGuard); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Wed Jun 25 17:34:25 2014 +0200 @@ -67,8 +67,8 @@ protected boolean verify(StructuredGraph graph, PhaseContext context) { for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { // bail out if we compare an object of type klass with == or != (except null checks) - if (checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) { - throw new VerificationError("Verification of " + klass.getName() + " usage failed: Comparing " + cn.x() + " and " + cn.y() + " in " + graph.method() + + if (checkUsage(cn.getX(), cn.getY(), context.getMetaAccess()) && checkUsage(cn.getY(), cn.getX(), context.getMetaAccess())) { + throw new VerificationError("Verification of " + klass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + graph.method() + " must use .equals() for object equality, not '==' or '!='"); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -50,6 +51,12 @@ throw GraalInternalError.shouldNotReachHere(); } + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + // nothing to do + return this; + } + public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { builder.setResult(this, gen.emitFloatConvert(op, builder.operand(getValue()))); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Wed Jun 25 17:34:25 2014 +0200 @@ -50,7 +50,7 @@ protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) { InstanceOfNode ion = graph.getNodes().filter(InstanceOfNode.class).first(); if (ion != null) { - InstanceOfNode ionNew = graph.unique(new InstanceOfNode(ion.type(), ion.object(), profile)); + InstanceOfNode ionNew = graph.unique(new InstanceOfNode(ion.type(), ion.getValue(), profile)); graph.replaceFloating(ion, ionNew); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Wed Jun 25 17:34:25 2014 +0200 @@ -223,7 +223,7 @@ if (graph.getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) { return; } - ValueNode hub = createReadHub(graph, loadHub.object(), loadHub.getGuard()); + ValueNode hub = createReadHub(graph, loadHub.getValue(), loadHub.getGuard()); graph.replaceFloating(loadHub, hub); } @@ -589,16 +589,16 @@ } if (offset instanceof IntegerAddNode) { IntegerAddNode integerAddNode = (IntegerAddNode) offset; - if (integerAddNode.y() instanceof ConstantNode) { - displacement = integerAddNode.y().asConstant().asLong(); - offset = integerAddNode.x(); + if (integerAddNode.getY() instanceof ConstantNode) { + displacement = integerAddNode.getY().asConstant().asLong(); + offset = integerAddNode.getX(); } } if (offset instanceof LeftShiftNode) { LeftShiftNode leftShiftNode = (LeftShiftNode) offset; - if (leftShiftNode.y() instanceof ConstantNode) { - long shift = leftShiftNode.y().asConstant().asLong(); + if (leftShiftNode.getY() instanceof ConstantNode) { + long shift = leftShiftNode.getY().asConstant().asLong(); if (shift >= 1 && shift <= 3) { if (shift == 1) { indexScaling = 2; @@ -607,7 +607,7 @@ } else { indexScaling = 8; } - offset = leftShiftNode.x(); + offset = leftShiftNode.getX(); } } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 25 17:34:25 2014 +0200 @@ -141,7 +141,7 @@ assert testValue.isConstant(); return LogicConstantNode.forBoolean(result.asConstant().equals(testValue.asConstant()), result.graph()); } - if (condition == null || condition.y() != testValue) { + if (condition == null || condition.getY() != testValue) { // Re-use previously generated condition if the trueValue for the test is the same condition = createCompareNode(result.graph(), Condition.EQ, result, testValue); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.replacements; -import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.replacements.nodes.*; @@ -58,11 +57,11 @@ @MethodSubstitution public static int divideUnsigned(int dividend, int divisor) { - return UnsignedDivNode.unsignedDivide(Kind.Int, dividend, divisor); + return UnsignedDivNode.unsignedDivide(dividend, divisor); } @MethodSubstitution public static int remainderUnsigned(int dividend, int divisor) { - return UnsignedRemNode.unsignedRemainder(Kind.Int, dividend, divisor); + return UnsignedRemNode.unsignedRemainder(dividend, divisor); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.replacements; -import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.replacements.nodes.*; @@ -58,11 +57,11 @@ @MethodSubstitution public static long divideUnsigned(long dividend, long divisor) { - return UnsignedDivNode.unsignedDivide(Kind.Long, dividend, divisor); + return UnsignedDivNode.unsignedDivide(dividend, divisor); } @MethodSubstitution public static long remainderUnsigned(long dividend, long divisor) { - return UnsignedRemNode.unsignedRemainder(Kind.Long, dividend, divisor); + return UnsignedRemNode.unsignedRemainder(dividend, divisor); } } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java Wed Jun 25 17:34:25 2014 +0200 @@ -26,9 +26,7 @@ import static com.oracle.graal.nodes.calc.ConditionalNode.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.calc.*; @@ -101,7 +99,7 @@ */ @MethodSubstitution public static int divide(int a, int b) { - return unsignedDivide(Kind.Int, a, b); + return unsignedDivide(a, b); } /** @@ -109,7 +107,7 @@ */ @MethodSubstitution public static int remainder(int a, int b) { - return unsignedRemainder(Kind.Int, a, b); + return unsignedRemainder(a, b); } /** @@ -117,7 +115,7 @@ */ @MethodSubstitution public static long divide(long a, long b) { - return unsignedDivide(Kind.Long, a, b); + return unsignedDivide(a, b); } /** @@ -125,18 +123,18 @@ */ @MethodSubstitution public static long remainder(long a, long b) { - return unsignedRemainder(Kind.Long, a, b); + return unsignedRemainder(a, b); } @NodeIntrinsic(UnsignedDivNode.class) - private static native int unsignedDivide(@ConstantNodeParameter Kind kind, int a, int b); + private static native int unsignedDivide(int a, int b); @NodeIntrinsic(UnsignedDivNode.class) - private static native long unsignedDivide(@ConstantNodeParameter Kind kind, long a, long b); + private static native long unsignedDivide(long a, long b); @NodeIntrinsic(UnsignedRemNode.class) - private static native int unsignedRemainder(@ConstantNodeParameter Kind kind, int a, int b); + private static native int unsignedRemainder(int a, int b); @NodeIntrinsic(UnsignedRemNode.class) - private static native long unsignedRemainder(@ConstantNodeParameter Kind kind, long a, long b); + private static native long unsignedRemainder(long a, long b); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -24,13 +24,12 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -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.*; -public class BitCountNode extends UnaryNode implements LIRLowerable, Canonicalizable { +public class BitCountNode extends UnaryNode implements LIRLowerable { public BitCountNode(ValueNode value) { super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); @@ -46,14 +45,10 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - Constant c = getValue().asConstant(); - if (c.getKind() == Kind.Int) { - return ConstantNode.forInt(Integer.bitCount(c.asInt()), graph()); - } else if (c.getKind() == Kind.Long) { - return ConstantNode.forInt(Long.bitCount(c.asLong()), graph()); - } + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + Constant c = forValue.asConstant(); + return ConstantNode.forInt(forValue.getKind() == Kind.Int ? bitCount(c.asInt()) : bitCount(c.asLong())); } return this; } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,10 +24,15 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +/** + * Determines the index of the least significant "1" bit. Note that the result is undefined if the + * input is zero. + */ public class BitScanForwardNode extends UnaryNode implements LIRLowerable { public BitScanForwardNode(ValueNode value) { @@ -54,6 +59,15 @@ return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + Constant c = forValue.asConstant(); + return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong())); + } + return this; + } + @NodeIntrinsic public static int scan(long v) { if (v == 0) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,10 +24,15 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +/** + * Determines the index of the most significant "1" bit. Note that the result is undefined if the + * input is zero. + */ public class BitScanReverseNode extends UnaryNode implements LIRLowerable { public BitScanReverseNode(ValueNode value) { @@ -52,6 +57,15 @@ return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + Constant c = forValue.asConstant(); + return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong())); + } + return this; + } + @NodeIntrinsic public static int scan(int v) { if (v == 0) { diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -51,6 +52,15 @@ return updateStamp(newStamp); } + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (forValue.isConstant()) { + Constant c = forValue.asConstant(); + return ConstantNode.forIntegerKind(getKind(), getKind() == Kind.Int ? reverse(c.asInt()) : reverse(c.asLong())); + } + return this; + } + @NodeIntrinsic public static int reverse(int v) { return Integer.reverseBytes(v); diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -36,27 +35,27 @@ * Node representing an exact integer addition that will throw an {@link ArithmeticException} in * case the addition would overflow the 32 bit range. */ -public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode { +public class IntegerAddExactNode extends IntegerAddNode implements IntegerExactArithmeticNode { public IntegerAddExactNode(ValueNode x, ValueNode y) { - super(x.stamp().unrestricted(), x, y); + super(x, y); assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp; } @Override public boolean inferStamp() { - // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.add(x().stamp(), y().stamp())); + // TODO Should probably use a specialized version which understands that it can't overflow + return updateStamp(StampTool.add(getX().stamp(), getY().stamp())); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerAddExactNode(y(), x())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new IntegerAddExactNode(forY, forX); } - if (x().isConstant()) { - Constant xConst = x().asConstant(); - Constant yConst = y().asConstant(); + if (forX.isConstant()) { + Constant xConst = forX.asConstant(); + Constant yConst = forY.asConstant(); assert xConst.getKind() == yConst.getKind(); try { if (xConst.getKind() == Kind.Int) { @@ -68,10 +67,10 @@ } catch (ArithmeticException ex) { // The operation will result in an overflow exception, so do not canonicalize. } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 0) { - return x(); + return forX; } } return this; @@ -79,7 +78,7 @@ @Override public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) { - return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt)); + return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt)); } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -35,39 +34,39 @@ * Node representing an exact integer multiplication that will throw an {@link ArithmeticException} * in case the addition would overflow the 32 bit range. */ -public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode { +public class IntegerMulExactNode extends IntegerMulNode implements IntegerExactArithmeticNode { public IntegerMulExactNode(ValueNode x, ValueNode y) { - super(x.stamp().unrestricted(), x, y); + super(x, y); assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp; } @Override - public Node canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerMulExactNode(y(), x())); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (forX.isConstant() && !forY.isConstant()) { + return new IntegerMulExactNode(forY, forX); } - if (x().isConstant()) { - Constant xConst = x().asConstant(); - Constant yConst = y().asConstant(); + if (forX.isConstant()) { + Constant xConst = forX.asConstant(); + Constant yConst = forY.asConstant(); assert xConst.getKind() == yConst.getKind(); try { if (xConst.getKind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt()), graph()); + return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt())); } else { assert xConst.getKind() == Kind.Long; - return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong()), graph()); + return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong())); } } catch (ArithmeticException ex) { // The operation will result in an overflow exception, so do not canonicalize. } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 1) { - return x(); + return forX; } if (c == 0) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + return ConstantNode.forIntegerStamp(stamp(), 0); } } return this; @@ -75,7 +74,7 @@ @Override public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) { - return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt)); + return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt)); } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,10 +22,13 @@ */ package com.oracle.graal.truffle.nodes.arithmetic; +import java.util.function.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -56,10 +59,13 @@ } } - @Override - public boolean inferStamp() { - IntegerStamp xStamp = (IntegerStamp) x().stamp(); - IntegerStamp yStamp = (IntegerStamp) y().stamp(); + /** + * Determines the minimum and maximum result of this node for the given inputs and returns the + * result of the given BiFunction on the minimum and maximum values. + */ + private T processExtremes(ValueNode forX, ValueNode forY, BiFunction op) { + IntegerStamp xStamp = (IntegerStamp) forX.stamp(); + IntegerStamp yStamp = (IntegerStamp) forY.stamp(); Kind kind = getKind(); assert kind == Kind.Int || kind == Kind.Long; @@ -74,13 +80,24 @@ max = Math.max(max, result); } } - return updateStamp(StampFactory.forInteger(getKind(), min, max)); + return op.apply(min, max); + } + + @Override + public boolean inferStamp() { + return updateStamp(processExtremes(getX(), getY(), (min, max) -> StampFactory.forInteger(getKind(), min, max))); + } + + @SuppressWarnings("cast") + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this); } @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value a = builder.operand(x()); - Value b = builder.operand(y()); + Value a = builder.operand(getX()); + Value b = builder.operand(getY()); builder.setResult(this, gen.emitMulHigh(a, b)); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -24,39 +24,39 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -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.*; import com.oracle.truffle.api.*; /** * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in * case the addition would overflow the 32 bit range. */ -public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode { +public class IntegerSubExactNode extends IntegerSubNode implements IntegerExactArithmeticNode { public IntegerSubExactNode(ValueNode x, ValueNode y) { - super(StampTool.sub(x.stamp(), y.stamp()), x, y); + super(x, y); assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp; } @Override public boolean inferStamp() { - // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.sub(x().stamp(), y().stamp())); + // TODO Should probably use a specialized version which understands that it can't overflow + return updateStamp(StampTool.sub(getX().stamp(), getY().stamp())); } @Override - public Node canonical(CanonicalizerTool tool) { - if (x() == y()) { - return ConstantNode.forIntegerStamp(stamp(), 0, graph()); + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { + return ConstantNode.forIntegerStamp(stamp(), 0); } - if (x().isConstant() && y().isConstant()) { - Constant xConst = x().asConstant(); - Constant yConst = y().asConstant(); + if (forX.isConstant() && forY.isConstant()) { + Constant xConst = forX.asConstant(); + Constant yConst = forY.asConstant(); assert xConst.getKind() == yConst.getKind(); try { if (xConst.getKind() == Kind.Int) { @@ -68,10 +68,10 @@ } catch (ArithmeticException ex) { // The operation will result in an overflow exception, so do not canonicalize. } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); + } else if (forY.isConstant()) { + long c = forY.asConstant().asLong(); if (c == 0) { - return x(); + return forX; } } return this; @@ -79,7 +79,7 @@ @Override public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) { - return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt)); + return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt)); } @Override diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -22,10 +22,13 @@ */ package com.oracle.graal.truffle.nodes.arithmetic; +import java.util.function.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -56,10 +59,49 @@ } } + /** + * Determines the minimum and maximum result of this node for the given inputs and returns the + * result of the given BiFunction on the minimum and maximum values. Note that the minima and + * maxima are calculated using signed min/max functions, while the values themselves are + * unsigned. + */ + private T processExtremes(ValueNode forX, ValueNode forY, BiFunction op) { + IntegerStamp xStamp = (IntegerStamp) forX.stamp(); + IntegerStamp yStamp = (IntegerStamp) forY.stamp(); + + Kind kind = getKind(); + assert kind == Kind.Int || kind == Kind.Long; + long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()}; + long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()}; + long min = Long.MAX_VALUE; + long max = Long.MIN_VALUE; + for (long a : xExtremes) { + for (long b : yExtremes) { + long result = kind == Kind.Int ? ExactMath.multiplyHighUnsigned((int) a, (int) b) : ExactMath.multiplyHighUnsigned(a, b); + min = Math.min(min, result); + max = Math.max(max, result); + } + } + return op.apply(min, max); + } + + @SuppressWarnings("cast") + @Override + public boolean inferStamp() { + // if min is negative, then the value can reach into the unsigned range + return updateStamp(processExtremes(getX(), getY(), (min, max) -> (min == (long) max || min >= 0) ? StampFactory.forInteger(getKind(), min, max) : StampFactory.forKind(getKind()))); + } + + @SuppressWarnings("cast") + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this); + } + @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - Value a = builder.operand(x()); - Value b = builder.operand(y()); + Value a = builder.operand(getX()); + Value b = builder.operand(getY()); builder.setResult(this, gen.emitUMulHigh(a, b)); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -134,9 +134,9 @@ * Fold constant field reads, e.g. enum constants. */ protected void rewriteLoadField(StructuredGraph graph, LoadFieldNode node) { - ConstantNode constant = node.asConstant(metaAccess); + ConstantNode constant = node.asConstant(metaAccess, node.object()); if (constant != null) { - node.replaceAtUsages(constant); + node.replaceAtUsages(graph.unique(constant)); graph.removeFixed(node); } } @@ -199,7 +199,7 @@ ValueNode left = arguments.get(0); ValueNode right = operation.rightOperandIsInt() ? toUnsigned(graph, arguments.get(1), Kind.Int) : fromSigned(graph, arguments.get(1)); - ValueNode replacement = graph.addOrUnique(createBinaryNodeInstance(operation.node(), wordKind, left, right)); + ValueNode replacement = graph.addOrUnique(createBinaryNodeInstance(operation.node(), left, right)); if (replacement instanceof FixedWithNextNode) { graph.addBeforeFixed(invoke.asNode(), (FixedWithNextNode) replacement); } @@ -213,7 +213,7 @@ case NOT: assert arguments.size() == 1; - replace(invoke, graph.unique(new XorNode(StampFactory.forKind(wordKind), arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph)))); + replace(invoke, graph.unique(new XorNode(arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph)))); break; case READ_POINTER: @@ -333,10 +333,10 @@ * called for all Word operations which are annotated with @Operation(node = ...) and * encapsulates the reflective allocation of the node. */ - private static ValueNode createBinaryNodeInstance(Class nodeClass, Kind kind, ValueNode left, ValueNode right) { + private static ValueNode createBinaryNodeInstance(Class nodeClass, ValueNode left, ValueNode right) { try { - Constructor constructor = nodeClass.getConstructor(Stamp.class, ValueNode.class, ValueNode.class); - return constructor.newInstance(StampFactory.forKind(kind), left, right); + Constructor constructor = nodeClass.getConstructor(ValueNode.class, ValueNode.class); + return constructor.newInstance(left, right); } catch (Throwable ex) { throw new GraalInternalError(ex).addContext(nodeClass.getName()); } diff -r a47528fb2ea0 -r e34bb128f227 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Wed Jun 25 16:57:12 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -86,8 +86,8 @@ MethodCallTargetNode callTarget = (MethodCallTargetNode) usage; verifyInvoke(node, callTarget); } else if (usage instanceof ObjectEqualsNode) { - verify(!isWord(node) || ((ObjectEqualsNode) usage).x() != node, node, usage, "cannot use word type in comparison"); - verify(!isWord(node) || ((ObjectEqualsNode) usage).y() != node, node, usage, "cannot use word type in comparison"); + verify(!isWord(node) || ((ObjectEqualsNode) usage).getX() != node, node, usage, "cannot use word type in comparison"); + verify(!isWord(node) || ((ObjectEqualsNode) usage).getY() != node, node, usage, "cannot use word type in comparison"); } else if (usage instanceof ArrayLengthNode) { verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value"); } else if (usage instanceof ValuePhiNode) {