# HG changeset patch # User Roland Schatz # Date 1433784779 -7200 # Node ID 2766fee1809a1446deeaecee0d5e53d55e455494 # Parent ae2a39857ab4702d4a8259fb48b13aee990b45f6 Use the fact that a range checked array index is not negative to avoid sign-extension of the index register. diff -r ae2a39857ab4 -r 2766fee1809a graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java Mon Jun 08 19:32:53 2015 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java Mon Jun 08 19:32:59 2015 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.memory.address.*; @@ -56,13 +57,13 @@ } protected boolean improve(AMD64AddressNode ret) { - ValueNode newBase = improveConstDisp(ret, ret.getBase(), 0); + ValueNode newBase = improveInput(ret, ret.getBase(), 0); if (newBase != ret.getBase()) { ret.setBase(newBase); return true; } - ValueNode newIdx = improveConstDisp(ret, ret.getIndex(), ret.getScale().log2); + ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2); if (newIdx != ret.getIndex()) { ret.setIndex(newIdx); return true; @@ -107,19 +108,31 @@ return false; } - private ValueNode improveConstDisp(AMD64AddressNode address, ValueNode node, int shift) { + private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift) { if (node == null) { return null; } if (node.isConstant()) { return improveConstDisp(address, node, node.asJavaConstant(), null, shift); - } else if (node instanceof AddNode) { - AddNode add = (AddNode) node; - if (add.getX().isConstant()) { - return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift); - } else if (add.getY().isConstant()) { - return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift); + } else { + if (node.stamp() instanceof IntegerStamp && ((IntegerStamp) node.stamp()).getBits() == 64) { + if (node instanceof ZeroExtendNode) { + if (((ZeroExtendNode) node).getInputBits() == 32) { + /* + * We can just swallow a zero-extend from 32 bit to 64 bit because the upper + * half of the register will always be zero. + */ + return ((ZeroExtendNode) node).getValue(); + } + } else if (node instanceof AddNode) { + AddNode add = (AddNode) node; + if (add.getX().isConstant()) { + return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift); + } else if (add.getY().isConstant()) { + return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift); + } + } } } diff -r ae2a39857ab4 -r 2766fee1809a 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 Mon Jun 08 19:32:53 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Jun 08 19:32:59 2015 +0200 @@ -204,11 +204,19 @@ Kind elementKind = loadIndexed.elementKind(); Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind); - AddressNode address = createArrayAddress(graph, loadIndexed.array(), elementKind, loadIndexed.index()); + PiNode pi = getBoundsCheckedIndex(loadIndexed, tool); + ValueNode checkedIndex = pi; + if (checkedIndex == null) { + checkedIndex = loadIndexed.index(); + } + + AddressNode address = createArrayAddress(graph, loadIndexed.array(), elementKind, checkedIndex); ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE)); ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead); - memoryRead.setGuard(createBoundsCheck(loadIndexed, tool)); + if (pi != null) { + memoryRead.setGuard(pi.getGuard()); + } loadIndexed.replaceAtUsages(readValue); graph.replaceFixed(loadIndexed, memoryRead); @@ -216,7 +224,18 @@ protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) { StructuredGraph graph = storeIndexed.graph(); - GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); + + PiNode pi = getBoundsCheckedIndex(storeIndexed, tool); + ValueNode checkedIndex; + GuardingNode boundsCheck; + if (pi == null) { + checkedIndex = storeIndexed.index(); + boundsCheck = null; + } else { + checkedIndex = pi; + boundsCheck = pi.getGuard(); + } + Kind elementKind = storeIndexed.elementKind(); ValueNode value = storeIndexed.value(); @@ -241,7 +260,7 @@ } } - AddressNode address = createArrayAddress(graph, array, elementKind, storeIndexed.index()); + AddressNode address = createArrayAddress(graph, array, elementKind, checkedIndex); WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value), arrayStoreBarrierType(storeIndexed.elementKind()))); memoryWrite.setGuard(boundsCheck); @@ -639,7 +658,7 @@ protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor); - protected GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { + protected PiNode getBoundsCheckedIndex(AccessIndexedNode n, LoweringTool tool) { StructuredGraph graph = n.graph(); ValueNode array = n.array(); ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); @@ -663,7 +682,10 @@ } } - return tool.createGuard(n, graph.unique(new IntegerBelowNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile); + GuardingNode guard = tool.createGuard(n, graph.unique(new IntegerBelowNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile); + IntegerStamp lengthStamp = (IntegerStamp) arrayLength.stamp(); + IntegerStamp indexStamp = StampFactory.forInteger(32, 0, lengthStamp.upperBound()); + return graph.unique(new PiNode(n.index(), indexStamp, guard.asNode())); } protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {