# HG changeset patch # User Tom Rodriguez # Date 1399347180 25200 # Node ID 589c3627fab83a107ccf15e4cc93a9548956aa91 # Parent 76213c9350ad2e8c02d1f6bea43e01d80076bcfd special cases for addresses involving compressed references diff -r 76213c9350ad -r 589c3627fab8 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 05 20:33:00 2014 -0700 @@ -601,7 +601,7 @@ } } - protected Value emitBinaryMemory(AMD64Arithmetic op, Kind kind, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { + public Value emitBinaryMemory(AMD64Arithmetic op, Kind kind, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { Variable result = newVariable(a.getKind()); append(new BinaryMemory(op, kind, result, a, location, state)); return result; diff -r 76213c9350ad -r 589c3627fab8 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 Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon May 05 20:33:00 2014 -0700 @@ -316,7 +316,7 @@ throw GraalInternalError.shouldNotReachHere(); } - private AMD64Arithmetic getOp(ValueNode operation, Access access) { + protected AMD64Arithmetic getOp(ValueNode operation, Access access) { Kind memoryKind = getMemoryKind(access); if (operation.getClass() == IntegerAddNode.class) { switch (memoryKind) { diff -r 76213c9350ad -r 589c3627fab8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java Mon May 05 20:33:00 2014 -0700 @@ -59,7 +59,19 @@ @MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryOpLogicNodeAdapter.class, commutative = true) @MatchableNode(nodeClass = OrNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) @MatchableNode(nodeClass = XorNode.class, inputs = 2, adapter = GraalMatchableNodes.BinaryNodeAdapter.class, commutative = true) +@MatchableNode(nodeClass = PiNode.class, inputs = 1, adapter = GraalMatchableNodes.PiNodeAdapter.class) +@MatchableNode(nodeClass = ConstantLocationNode.class, shareable = true) public class GraalMatchableNodes { + public static class PiNodeAdapter extends MatchNodeAdapter { + @Override + public ValueNode getInput(int input, ValueNode node) { + if (input == 0) { + return ((PiNode) node).object(); + } + throw GraalInternalError.shouldNotReachHere(); + } + } + public static class BinaryNodeAdapter extends MatchNodeAdapter { @Override public ValueNode getInput(int input, ValueNode node) { diff -r 76213c9350ad -r 589c3627fab8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Mon May 05 20:33:00 2014 -0700 @@ -31,7 +31,7 @@ import com.oracle.graal.compiler.match.MatchPattern.Result; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.virtual.*; /** @@ -100,9 +100,9 @@ // Ensure that there's no unsafe work in between these operations. for (int i = startIndex; i <= endIndex; i++) { ScheduledNode node = nodes.get(i); - if (node instanceof ConstantNode || node instanceof LocationNode || node instanceof VirtualObjectNode || node instanceof ParameterNode) { - // these can be evaluated lazily so don't worry about them. This should probably be - // captured by some interface that indicates that their generate method is empty. + if (node instanceof VirtualObjectNode || node instanceof FloatingNode) { + // The order of evaluation of these nodes controlled by data dependence so they + // don't interfere with this match. continue; } else if ((consumed == null || !consumed.contains(node)) && node != root) { if (LogVerbose.getValue()) { diff -r 76213c9350ad -r 589c3627fab8 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 Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Mon May 05 20:33:00 2014 -0700 @@ -41,6 +41,7 @@ import com.oracle.graal.hotspot.amd64.AMD64HotSpotLIRGenerator.SaveRbp; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.amd64.*; @@ -65,7 +66,7 @@ return result; } - private void emitCompareCompressedMemory(IfNode ifNode, ValueNode valueNode, Access access, CompareNode compare) { + private void emitCompareMemoryObject(IfNode ifNode, ValueNode valueNode, Access access, CompareNode compare) { Value value; // This works by embedding the compressed form for constants, so force a constant instead of // respecting what operand() would return. @@ -95,6 +96,22 @@ getGen().emitCompareBranchMemoryCompressed(left, right, cond, trueLabel, falseLabel, trueLabelProbability, getState(access)); } + private void emitCompareCompressedMemory(Kind kind, IfNode ifNode, ValueNode valueNode, CompressionNode compress, ConstantLocationNode location, Access access, CompareNode compare) { + Value value = gen.load(operand(valueNode)); + AMD64AddressValue address = makeCompressedAddress(compress, location); + Condition cond = compare.condition(); + if (access == filterCompression(compare.x())) { + cond = cond.mirror(); + } else { + assert access == filterCompression(compare.y()); + } + + LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor()); + LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor()); + double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor()); + getGen().emitCompareBranchMemory(kind, value, address, getState(access), cond, compare.unorderedIsTrue(), trueLabel, falseLabel, trueLabelProbability); + } + public AMD64HotSpotNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen) { super(graph, gen); assert gen instanceof AMD64HotSpotLIRGenerator; @@ -244,14 +261,116 @@ setResult(x, result); } + boolean canFormCompressedMemory(CompressionNode compress, ConstantLocationNode location) { + HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); + if (config.useCompressedOops && compress.getEncoding().shift <= 3 && NumUtil.isInt(location.getDisplacement())) { + PlatformKind objectKind = compress.getInput().stamp().getPlatformKind(getGen()); + if (objectKind == NarrowOopStamp.NarrowOop || objectKind == Kind.Int && config.narrowKlassBase == config.narrowOopBase) { + return true; + } + } + return false; + } + + private AMD64AddressValue makeCompressedAddress(CompressionNode compress, ConstantLocationNode location) { + assert canFormCompressedMemory(compress, location); + AMD64AddressValue address = getGen().emitAddress(getGen().getProviders().getRegisters().getHeapBaseRegister().asValue(), location.getDisplacement(), operand(compress.getInput()), + 1 << compress.getEncoding().shift); + return address; + } + + @MatchRule("(If (ObjectEquals=compare Constant=value (Pi (Compression Read=access))))") + @MatchRule("(If (ObjectEquals=compare Constant=value (Pi (Compression FloatingRead=access))))") + @MatchRule("(If (ObjectEquals=compare (Compression value) (Pi (Compression Read=access))))") + @MatchRule("(If (ObjectEquals=compare (Compression value) (Pi (Compression FloatingRead=access))))") @MatchRule("(If (ObjectEquals=compare Constant=value (Compression Read=access)))") @MatchRule("(If (ObjectEquals=compare Constant=value (Compression FloatingRead=access)))") @MatchRule("(If (ObjectEquals=compare (Compression value) (Compression Read=access)))") @MatchRule("(If (ObjectEquals=compare (Compression value) (Compression FloatingRead=access)))") - public ComplexMatchResult ifCompareCompressedMemory(IfNode root, CompareNode compare, ValueNode value, Access access) { + public ComplexMatchResult ifCompareMemoryObject(IfNode root, CompareNode compare, ValueNode value, Access access) { if (HotSpotGraalRuntime.runtime().getConfig().useCompressedOops) { return builder -> { - emitCompareCompressedMemory(root, value, access, compare); + emitCompareMemoryObject(root, value, access, compare); + return null; + }; + } + return null; + } + + @MatchRule("(If (IntegerEquals=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (IntegerLessThan=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (IntegerBelowThan=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (FloatEquals=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (FloatLessThan=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (IntegerEquals=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (IntegerLessThan=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (IntegerBelowThan=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") + @MatchRule("(If (FloatEquals=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") + @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.getPlatformKind(compare.x().stamp()); + if (cmpKind instanceof Kind) { + Kind kind = (Kind) cmpKind; + return builder -> { + emitCompareCompressedMemory(kind, root, value, compress, location, access, compare); + return null; + }; + } + } + return null; + } + + @MatchRule("(IntegerAdd value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(IntegerSub value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(IntegerMul value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatAdd value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatSub value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatMul value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(Or value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(Xor value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(And value (Read=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(IntegerAdd value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(IntegerSub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(IntegerMul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatAdd value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatSub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(FloatMul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(Or value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(Xor value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + @MatchRule("(And value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") + public ComplexMatchResult binaryReadCompressed(BinaryNode root, ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { + if (canFormCompressedMemory(compress, location)) { + AMD64Arithmetic op = getOp(root, access); + if (op != null) { + return builder -> getLIRGeneratorTool().emitBinaryMemory(op, getMemoryKind(access), getLIRGeneratorTool().asAllocatable(operand(value)), makeCompressedAddress(compress, location), + getState(access)); + } + } + return null; + } + + @MatchRule("(Read (Compression=compress object) ConstantLocation=location)") + @MatchRule("(Read (Pi (Compression=compress object)) ConstantLocation=location)") + @MatchRule("(FloatingRead (Compression=compress object) ConstantLocation=location)") + @MatchRule("(FloatingRead (Pi (Compression=compress object)) ConstantLocation=location)") + public ComplexMatchResult readCompressed(Access root, CompressionNode compress, ConstantLocationNode location) { + if (canFormCompressedMemory(compress, location)) { + PlatformKind readKind = getGen().getPlatformKind(root.asNode().stamp()); + return builder -> { + return getGen().emitLoad(readKind, makeCompressedAddress(compress, location), getState(root)); + }; + } + return null; + } + + @MatchRule("(Write (Compression=compress object) ConstantLocation=location value)") + @MatchRule("(Write (Pi (Compression=compress object)) ConstantLocation=location value)") + public ComplexMatchResult writeCompressed(Access root, CompressionNode compress, ConstantLocationNode location, ValueNode value) { + if (canFormCompressedMemory(compress, location)) { + PlatformKind readKind = getGen().getPlatformKind(value.asNode().stamp()); + return builder -> { + getGen().emitStore(readKind, makeCompressedAddress(compress, location), operand(value), getState(root)); return null; }; } diff -r 76213c9350ad -r 589c3627fab8 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 Mon May 05 16:13:53 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon May 05 20:33:00 2014 -0700 @@ -97,6 +97,10 @@ return input; } + public CompressEncoding getEncoding() { + return encoding; + } + @Override public Node canonical(CanonicalizerTool tool) { if (input instanceof CompressionNode) {