# HG changeset patch # User Christian Wimmer # Date 1448988384 28800 # Node ID 88fb9daa58fbfbb4c181bd7d63d2d9b120a95d67 # Parent 80cf191586747bc152721be15623d23acc82aaa6# Parent 99b21d7f7ed64356d38ef4f175019df2d765aa63 Merge diff -r 99b21d7f7ed6 -r 88fb9daa58fb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java Mon Nov 30 16:24:57 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java Tue Dec 01 08:46:24 2015 -0800 @@ -28,10 +28,15 @@ import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.MetaAccessProvider; +import com.oracle.graal.compiler.common.type.Stamp; import com.oracle.graal.graph.Graph; import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.Canonicalizable; import com.oracle.graal.graph.spi.CanonicalizerTool; +import com.oracle.graal.nodeinfo.NodeInfo; +import com.oracle.graal.nodes.calc.FloatingNode; +import com.oracle.graal.nodes.extended.GuardingNode; import com.oracle.graal.nodes.extended.IntegerSwitchNode; import com.oracle.graal.nodes.spi.StampProvider; import com.oracle.graal.nodes.util.GraphUtil; @@ -71,6 +76,20 @@ } } + @NodeInfo + static class CanonicalizeToNullNode extends FloatingNode implements Canonicalizable, GuardingNode { + public static final NodeClass TYPE = NodeClass.create(CanonicalizeToNullNode.class); + + protected CanonicalizeToNullNode(Stamp stamp) { + super(TYPE, stamp); + } + + @Override + public Node canonical(CanonicalizerTool tool) { + return null; + } + } + public SimplifyingGraphDecoder(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, StampProvider stampProvider, boolean canonicalizeReads, Architecture architecture) { super(architecture); this.metaAccess = metaAccess; @@ -149,43 +168,75 @@ } } + } else if (node instanceof FixedGuardNode) { + FixedGuardNode guard = (FixedGuardNode) node; + if (guard.getCondition() instanceof LogicConstantNode) { + LogicConstantNode condition = (LogicConstantNode) guard.getCondition(); + Node canonical; + if (condition.getValue() == guard.isNegated()) { + DeoptimizeNode deopt = new DeoptimizeNode(guard.getAction(), guard.getReason(), guard.getSpeculation()); + if (guard.stateBefore() != null) { + deopt.setStateBefore(guard.stateBefore()); + } + canonical = deopt; + } else { + /* + * The guard is unnecessary, but we cannot remove the node completely yet + * because there might be nodes that use it as a guard input. Therefore, we + * replace it with a more lightweight node (which is floating and has no + * inputs). + */ + canonical = new CanonicalizeToNullNode(node.stamp); + } + handleCanonicaliation(methodScope, loopScope, nodeOrderId, node, canonical); + } + } else if (node instanceof Canonicalizable) { Node canonical = ((Canonicalizable) node).canonical(new PECanonicalizerTool()); - if (canonical == null) { - /* - * This is a possible return value of canonicalization. However, we might need to - * add additional usages later on for which we need a node. Therefore, we just do - * nothing and leave the node in place. - */ - } else if (canonical != node) { - if (!canonical.isAlive()) { - assert !canonical.isDeleted(); - canonical = methodScope.graph.addOrUniqueWithInputs(canonical); - if (canonical instanceof FixedWithNextNode) { - methodScope.graph.addBeforeFixed(node, (FixedWithNextNode) canonical); - } else if (canonical instanceof ControlSinkNode) { - FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor(); - predecessor.setNext((ControlSinkNode) canonical); - node.safeDelete(); - for (Node successor : node.successors()) { - successor.safeDelete(); - } - - } else { - assert !(canonical instanceof FixedNode); - } - } - if (!node.isDeleted()) { - GraphUtil.unlinkFixedNode((FixedWithNextNode) node); - node.replaceAtUsages(canonical); - node.safeDelete(); - } - assert lookupNode(loopScope, nodeOrderId) == node; - registerNode(loopScope, nodeOrderId, canonical, true, false); + if (canonical != node) { + handleCanonicaliation(methodScope, loopScope, nodeOrderId, node, canonical); } } } + private void handleCanonicaliation(MethodScope methodScope, LoopScope loopScope, int nodeOrderId, FixedNode node, Node c) { + Node canonical = c; + + if (canonical == null) { + /* + * This is a possible return value of canonicalization. However, we might need to add + * additional usages later on for which we need a node. Therefore, we just do nothing + * and leave the node in place. + */ + return; + } + + if (!canonical.isAlive()) { + assert !canonical.isDeleted(); + canonical = methodScope.graph.addOrUniqueWithInputs(canonical); + if (canonical instanceof FixedWithNextNode) { + methodScope.graph.addBeforeFixed(node, (FixedWithNextNode) canonical); + } else if (canonical instanceof ControlSinkNode) { + FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor(); + predecessor.setNext((ControlSinkNode) canonical); + node.safeDelete(); + for (Node successor : node.successors()) { + successor.safeDelete(); + } + + } else { + assert !(canonical instanceof FixedNode); + } + } + if (!node.isDeleted()) { + GraphUtil.unlinkFixedNode((FixedWithNextNode) node); + node.replaceAtUsages(canonical); + node.safeDelete(); + } + assert lookupNode(loopScope, nodeOrderId) == node; + registerNode(loopScope, nodeOrderId, canonical, true, false); + } + @Override protected Node handleFloatingNodeBeforeAdd(MethodScope methodScope, LoopScope loopScope, Node node) { if (node instanceof Canonicalizable) { diff -r 99b21d7f7ed6 -r 88fb9daa58fb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Mon Nov 30 16:24:57 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Tue Dec 01 08:46:24 2015 -0800 @@ -92,8 +92,8 @@ @Override public Object getObject(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, OBJECT_TAG); - return getObjectUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, OBJECT_TAG); + return getObjectUnsafe(slotIndex, slot, condition); } private Object[] getLocals() { @@ -108,8 +108,7 @@ return unsafeCast(tags, byte[].class, true, true); } - private Object getObjectUnsafe(int slotIndex, FrameSlot slot) { - boolean condition = this.getTags()[slotIndex] == OBJECT_TAG; + private Object getObjectUnsafe(int slotIndex, FrameSlot slot, boolean condition) { return unsafeGetObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, condition, slot); } @@ -127,13 +126,12 @@ @Override public byte getByte(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, BYTE_TAG); - return getByteUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, BYTE_TAG); + return getByteUnsafe(slotIndex, slot, condition); } - private byte getByteUnsafe(int slotIndex, FrameSlot slot) { + private byte getByteUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slotIndex] == BYTE_TAG; return (byte) unsafeGetInt(getPrimitiveLocals(), offset, condition, slot); } @@ -152,13 +150,12 @@ @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, BOOLEAN_TAG); - return getBooleanUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, BOOLEAN_TAG); + return getBooleanUnsafe(slotIndex, slot, condition); } - private boolean getBooleanUnsafe(int slotIndex, FrameSlot slot) { + private boolean getBooleanUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slotIndex] == BOOLEAN_TAG; return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot) != 0; } @@ -177,13 +174,12 @@ @Override public float getFloat(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, FLOAT_TAG); - return getFloatUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, FLOAT_TAG); + return getFloatUnsafe(slotIndex, slot, condition); } - private float getFloatUnsafe(int slotIndex, FrameSlot slot) { + private float getFloatUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slotIndex] == FLOAT_TAG; return unsafeGetFloat(getPrimitiveLocals(), offset, condition, slot); } @@ -202,13 +198,12 @@ @Override public long getLong(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, LONG_TAG); - return getLongUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, LONG_TAG); + return getLongUnsafe(slotIndex, slot, condition); } - private long getLongUnsafe(int slotIndex, FrameSlot slot) { + private long getLongUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slotIndex] == LONG_TAG; return unsafeGetLong(getPrimitiveLocals(), offset, condition, slot); } @@ -227,13 +222,12 @@ @Override public int getInt(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, INT_TAG); - return getIntUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, INT_TAG); + return getIntUnsafe(slotIndex, slot, condition); } - private int getIntUnsafe(int slotIndex, FrameSlot slot) { + private int getIntUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slot.getIndex()] == INT_TAG; return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot); } @@ -252,13 +246,12 @@ @Override public double getDouble(FrameSlot slot) throws FrameSlotTypeException { int slotIndex = slot.getIndex(); - verifyGet(slotIndex, DOUBLE_TAG); - return getDoubleUnsafe(slotIndex, slot); + boolean condition = verifyGet(slotIndex, DOUBLE_TAG); + return getDoubleUnsafe(slotIndex, slot, condition); } - private double getDoubleUnsafe(int slotIndex, FrameSlot slot) { + private double getDoubleUnsafe(int slotIndex, FrameSlot slot, boolean condition) { long offset = getPrimitiveOffset(slotIndex); - boolean condition = this.getTags()[slotIndex] == DOUBLE_TAG; return unsafeGetDouble(getPrimitiveLocals(), offset, condition, slot); } @@ -284,12 +277,14 @@ getTags()[slotIndex] = tag; } - private void verifyGet(int slotIndex, byte tag) throws FrameSlotTypeException { + private boolean verifyGet(int slotIndex, byte tag) throws FrameSlotTypeException { checkSlotIndex(slotIndex); - if (getTags()[slotIndex] != tag) { + boolean condition = getTags()[slotIndex] == tag; + if (!condition) { CompilerDirectives.transferToInterpreter(); throw new FrameSlotTypeException(); } + return condition; } private void checkSlotIndex(int slotIndex) { @@ -312,22 +307,34 @@ resize(); } byte tag = getTags()[slotIndex]; - if (tag == BOOLEAN_TAG) { - return getBooleanUnsafe(slotIndex, slot); - } else if (tag == BYTE_TAG) { - return getByteUnsafe(slotIndex, slot); - } else if (tag == INT_TAG) { - return getIntUnsafe(slotIndex, slot); - } else if (tag == DOUBLE_TAG) { - return getDoubleUnsafe(slotIndex, slot); - } else if (tag == LONG_TAG) { - return getLongUnsafe(slotIndex, slot); - } else if (tag == FLOAT_TAG) { - return getFloatUnsafe(slotIndex, slot); - } else { - assert tag == OBJECT_TAG; - return getObjectUnsafe(slotIndex, slot); + boolean condition = (tag == BOOLEAN_TAG); + if (condition) { + return getBooleanUnsafe(slotIndex, slot, condition); + } + condition = (tag == BYTE_TAG); + if (condition) { + return getByteUnsafe(slotIndex, slot, condition); + } + condition = (tag == INT_TAG); + if (condition) { + return getIntUnsafe(slotIndex, slot, condition); } + condition = (tag == DOUBLE_TAG); + if (condition) { + return getDoubleUnsafe(slotIndex, slot, condition); + } + condition = (tag == LONG_TAG); + if (condition) { + return getLongUnsafe(slotIndex, slot, condition); + } + condition = (tag == FLOAT_TAG); + if (condition) { + return getFloatUnsafe(slotIndex, slot, condition); + } + condition = tag == OBJECT_TAG; + assert condition; + return getObjectUnsafe(slotIndex, slot, condition); + } private boolean resize() { @@ -345,10 +352,13 @@ private byte getTag(FrameSlot slot) { int slotIndex = slot.getIndex(); - if (slotIndex >= getTags().length) { - CompilerDirectives.transferToInterpreter(); - resize(); + byte[] cachedTags = getTags(); + if (slotIndex < cachedTags.length) { + return cachedTags[slotIndex]; } + + CompilerDirectives.transferToInterpreter(); + resize(); return getTags()[slotIndex]; } diff -r 99b21d7f7ed6 -r 88fb9daa58fb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Nov 30 16:24:57 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Dec 01 08:46:24 2015 -0800 @@ -340,8 +340,23 @@ getCompilationNotify().notifyShutdown(this); } + protected void doCompile(OptimizedCallTarget optimizedCallTarget) { + int repeats = TruffleCompilerOptions.TruffleCompilationRepeats.getValue(); + if (repeats <= 1) { + /* Normal compilation. */ + doCompile0(optimizedCallTarget); + + } else { + /* Repeated compilation for compilation time benchmarking. */ + for (int i = 0; i < repeats; i++) { + doCompile0(optimizedCallTarget); + } + System.exit(0); + } + } + @SuppressWarnings("try") - protected void doCompile(OptimizedCallTarget optimizedCallTarget) { + private void doCompile0(OptimizedCallTarget optimizedCallTarget) { boolean success = true; try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) { truffleCompiler.compileMethod(optimizedCallTarget); diff -r 99b21d7f7ed6 -r 88fb9daa58fb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Nov 30 16:24:57 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Dec 01 08:46:24 2015 -0800 @@ -126,6 +126,9 @@ @Option(help = "Print information for compilation results", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilation = new OptionValue<>(false); + @Option(help = "Compile time benchmarking: repeat Truffle compilation n times and then exit the VM", type = OptionType.Debug) + public static final OptionValue TruffleCompilationRepeats = new OptionValue<>(0); + @Option(help = "Print information for compilation queuing", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false);