# HG changeset patch # User Lukas Stadler # Date 1395332136 -3600 # Node ID b602356a9cfc825bb8b82dede17e60eeac6a3704 # Parent c8fb80093621eff1ec9796c2aed81e9a08512553 additional canonicalizers for accesses and value nodes (improves number of implicit null checks) diff -r c8fb80093621 -r b602356a9cfc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Fri Mar 21 11:51:14 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Thu Mar 20 17:15:36 2014 +0100 @@ -43,6 +43,11 @@ return object; } + protected void setObject(ValueNode x) { + updateUsages(object, x); + object = x; + } + public LocationNode location() { return (LocationNode) location; } diff -r c8fb80093621 -r b602356a9cfc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Mar 21 11:51:14 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Thu Mar 20 17:15:36 2014 +0100 @@ -67,6 +67,9 @@ @Override public Node canonical(CanonicalizerTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + return graph().unique(new FloatingReadNode(((PiNode) object()).getOriginalValue(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType(), isCompressible())); + } return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible()); } diff -r c8fb80093621 -r b602356a9cfc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Mar 21 11:51:14 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Mar 20 17:15:36 2014 +0100 @@ -60,6 +60,9 @@ @Override public Node canonical(CanonicalizerTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + return graph().add(new ReadNode(((PiNode) object()).getOriginalValue(), location(), stamp(), getGuard(), getBarrierType(), isCompressible())); + } return canonicalizeRead(this, location(), object(), tool, isCompressible()); } diff -r c8fb80093621 -r b602356a9cfc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Mar 21 11:51:14 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Thu Mar 20 17:15:36 2014 +0100 @@ -22,16 +22,17 @@ */ package com.oracle.graal.nodes.extended; -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.*; /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode { +public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, GuardingNode { @Input private ValueNode anchored; @@ -50,19 +51,40 @@ } @Override - public Node canonical(CanonicalizerTool tool) { - if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) { - // Found entry that needs this anchor. - return this; + public void simplify(SimplifierTool tool) { + while (next() instanceof ValueAnchorNode) { + ValueAnchorNode nextAnchor = (ValueAnchorNode) next(); + if (nextAnchor.anchored == anchored || nextAnchor.anchored == null) { + // two anchors for the same anchored -> coalesce + // nothing anchored on the next anchor -> coalesce + nextAnchor.replaceAtUsages(this); + GraphUtil.removeFixedWithUnusedInputs(nextAnchor); + } else { + break; + } + } + if (usages().isEmpty() && next() instanceof FixedAccessNode) { + FixedAccessNode next = (FixedAccessNode) next(); + if (next.getGuard() == anchored) { + GraphUtil.removeFixedWithUnusedInputs(this); + return; + } else if (next.getGuard() == null && anchored instanceof GuardNode && ((GuardNode) anchored).condition() instanceof IsNullNode) { + // coalesce null check guards into subsequent read/write + next.setGuard((GuardingNode) anchored); + tool.addToWorkList(next()); + return; + } } - if (usages().isNotEmpty()) { - // A not uses this anchor => anchor is necessary. - return this; + if (anchored != null && (anchored.isConstant() || anchored instanceof FixedNode)) { + // anchoring fixed nodes and constants is useless + removeAnchoredNode(); } - // Anchor is not necessary any more => remove. - return null; + if (anchored == null && usages().isEmpty()) { + // anchor is not necessary any more => remove. + GraphUtil.removeFixedWithUnusedInputs(this); + } } @Override diff -r c8fb80093621 -r b602356a9cfc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Mar 21 11:51:14 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Thu Mar 20 17:15:36 2014 +0100 @@ -24,6 +24,7 @@ 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.extended.LocationNode.Location; import com.oracle.graal.nodes.spi.*; @@ -33,7 +34,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain FixedAccessNode memory location}. */ -public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Virtualizable { +public final class WriteNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, MemoryAccess, Simplifiable, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -102,6 +103,13 @@ gen.emitStore(location().getValueKind(), address, v, this); } + @Override + public void simplify(SimplifierTool tool) { + if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { + setObject(((PiNode) object()).getOriginalValue()); + } + } + @NodeIntrinsic public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType, @ConstantNodeParameter boolean compressible);