changeset 15522:589c3627fab8

special cases for addresses involving compressed references
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 05 May 2014 20:33:00 -0700
parents 76213c9350ad
children 44d700e2faba
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/GraalMatchableNodes.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java
diffstat 6 files changed, 144 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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) {
--- 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) {
--- 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()) {
--- 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;
             };
         }
--- 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) {