# HG changeset patch # User Tom Rodriguez # Date 1396392139 25200 # Node ID 8ce9a950fbe2ff037ee8bac0c9fdc58057fa92c1 # Parent d45e8c3063494d6b533cd96173789cd11d9d6d62 allow memory arithmetic to swallow UnsafeCastNode diff -r d45e8c306349 -r 8ce9a950fbe2 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Tue Apr 01 15:41:28 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Tue Apr 01 15:42:19 2014 -0700 @@ -82,7 +82,7 @@ protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) { ValueNode other = x; - if (other == access) { + if (uncast(other) == access) { if (commutative) { other = y; } else { @@ -194,7 +194,7 @@ case Long: return emitBinaryMemory(LAND, true, x, y, access); case Short: { - ValueNode other = x == access ? y : x; + ValueNode other = selectOtherInput(x, y, access); Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null; if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) { // Convert to unsigned load @@ -207,7 +207,7 @@ if (OptFoldMemory.getValue()) { return null; } - ValueNode other = x == access ? y : x; + ValueNode other = selectOtherInput(x, y, access); Constant constant = other instanceof ConstantNode ? ((ConstantNode) other).asConstant() : null; if (constant != null && constant.asInt() == IntegerStamp.defaultMask(kind.getBitCount())) { // Convert to unsigned load @@ -398,10 +398,12 @@ } private boolean emitIntegerTestBranchMemory(ValueNode left, ValueNode right, Access access, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { - assert left == access || right == access; - ValueNode other = left == access ? right : left; + ValueNode other = selectOtherInput(left, right, access); Kind kind = access.nullCheckLocation().getValueKind(); if (other.isConstant()) { + if (kind != kind.getStackKind()) { + return false; + } Constant constant = other.asConstant(); if (kind == Kind.Long && !NumUtil.isInt(constant.asLong())) { // Only imm32 as long @@ -418,10 +420,25 @@ return true; } + /** + * @return the input which is not equal to access, accounting for possible UnsafeCastNodes. + */ + protected ValueNode selectOtherInput(ValueNode left, ValueNode right, Access access) { + assert uncast(left) == access || uncast(right) == access; + return uncast(left) == access ? right : left; + } + + protected ValueNode uncast(ValueNode value) { + if (value instanceof UnsafeCastNode) { + UnsafeCastNode cast = (UnsafeCastNode) value; + return cast.getOriginalValue(); + } + return value; + } + protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { - assert left == access || right == access; - ValueNode other = left == access ? right : left; + ValueNode other = selectOtherInput(left, right, access); Kind kind = access.nullCheckLocation().getValueKind(); boolean mirrored = false; @@ -447,7 +464,7 @@ } ensureEvaluated(other); gen.getLIRGenerator().emitCompareMemoryConOp(kind, makeAddress(access), constant, getState(access)); - mirrored = right == access; + mirrored = uncast(right) == access; } else { if (kind != kind.getStackKind()) { // Register compares only work for stack kinds @@ -461,7 +478,7 @@ evaluateDeferred(); gen.getLIRGenerator().emitCompareRegMemoryOp(kind, gen.operand(other), makeAddress(access), getState(access)); - mirrored = left == access; + mirrored = uncast(left) == access; } Condition finalCondition = mirrored ? cond.mirror() : cond; diff -r d45e8c306349 -r 8ce9a950fbe2 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 Tue Apr 01 15:41:28 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Tue Apr 01 15:42:19 2014 -0700 @@ -273,9 +273,15 @@ // This is all bit hacky since it's happening on the linearized schedule. This needs // to be revisited at some point. + // Uncast the memory operation. + Node use = access.usages().first(); + if (use instanceof UnsafeCastNode && use.usages().count() == 1) { + use = use.usages().first(); + } + // Find a memory lowerable usage of this operation - if (access.usages().first() instanceof MemoryArithmeticLIRLowerable) { - ValueNode operation = (ValueNode) access.usages().first(); + if (use instanceof MemoryArithmeticLIRLowerable) { + ValueNode operation = (ValueNode) use; if (!nodes.contains(operation)) { Debug.log("node %1s in different block from %1s", access, operation); MemoryFoldFailedDifferentBlock.increment(); @@ -316,11 +322,12 @@ int opIndex = nodes.indexOf(operation); int current = i + 1; ArrayList deferred = null; - while (current < opIndex) { + for (; current < opIndex; current++) { ScheduledNode node = nodes.get(current); if (node != firstOperation) { if (node instanceof LocationNode || node instanceof VirtualObjectNode) { // nothing to do + continue; } else if (node instanceof ConstantNode) { if (deferred == null) { deferred = new ArrayList<>(2); @@ -330,13 +337,18 @@ // basically works around unfriendly scheduling of values which // are defined in a block but not used there. deferred.add((ValueNode) node); - } else { - Debug.log("unexpected node %1s", node); - // Unexpected inline node - break; + continue; + } else if (node instanceof UnsafeCastNode) { + UnsafeCastNode cast = (UnsafeCastNode) node; + if (cast.getOriginalValue() == access) { + continue; + } } + + // Unexpected inline node + // Debug.log("unexpected node %1s", node); + break; } - current++; } if (current == opIndex) { @@ -369,7 +381,7 @@ } else { MemoryFoldFailedNonAdjacent.increment(); } - } else { + } else if (!(use instanceof Access) && !(use instanceof PhiNode) && use.usages().count() == 1) { // memory usage which isn't considered lowerable. Mostly these are // uninteresting but it might be worth looking at to ensure that interesting // nodes are being properly handled. diff -r d45e8c306349 -r 8ce9a950fbe2 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Tue Apr 01 15:41:28 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMemoryPeephole.java Tue Apr 01 15:42:19 2014 -0700 @@ -84,9 +84,8 @@ @Override protected boolean emitCompareBranchMemory(ValueNode left, ValueNode right, Access access, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) { - assert left == access || right == access; if (HotSpotGraalRuntime.runtime().getConfig().useCompressedOops) { - ValueNode other = left == access ? right : left; + ValueNode other = selectOtherInput(left, right, access); Kind kind = access.nullCheckLocation().getValueKind(); if (other.isConstant() && kind == Kind.Object && access.isCompressible()) {