changeset 15912:c44f617fb8d7

Optimize compare compressed pattern.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 26 May 2014 17:43:45 +0200
parents 03e09ed7039d
children 67e0015b21d6
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java
diffstat 2 files changed, 71 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon May 26 16:16:47 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon May 26 17:43:45 2014 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -39,7 +40,7 @@
  * Compress or uncompress an oop or metaspace pointer.
  */
 @NodeInfo(nameTemplate = "{p#op/s}")
-public final class CompressionNode extends FloatingNode implements LIRLowerable, Canonicalizable {
+public final class CompressionNode extends ConvertNode implements LIRLowerable, Canonicalizable {
 
     private enum CompressionOp {
         Compress,
@@ -49,13 +50,10 @@
     private final CompressionOp op;
     private final CompressEncoding encoding;
 
-    @Input private ValueNode input;
-
     private CompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
-        super(mkStamp(op, input.stamp(), encoding));
+        super(mkStamp(op, input.stamp(), encoding), input);
         this.op = op;
         this.encoding = encoding;
-        this.input = input;
     }
 
     public static CompressionNode compress(ValueNode input, CompressEncoding encoding) {
@@ -66,6 +64,61 @@
         return input.graph().unique(new CompressionNode(CompressionOp.Uncompress, input, encoding));
     }
 
+    private static Constant compress(Constant c, CompressEncoding encoding) {
+        if (Constant.NULL_OBJECT.equals(c)) {
+            return HotSpotCompressedNullConstant.COMPRESSED_NULL;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return ((HotSpotObjectConstant) c).compress();
+        } else if (c instanceof HotSpotMetaspaceConstant) {
+            assert c.getKind() == Kind.Long;
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+        } else {
+            throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c);
+        }
+    }
+
+    private static Constant uncompress(Constant c, CompressEncoding encoding) {
+        if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
+            return Constant.NULL_OBJECT;
+        } else if (c instanceof HotSpotObjectConstant) {
+            return ((HotSpotObjectConstant) c).uncompress();
+        } else if (c instanceof HotSpotMetaspaceConstant) {
+            assert c.getKind() == Kind.Int;
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+        } else {
+            throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c);
+        }
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        switch (op) {
+            case Compress:
+                return compress(c, encoding);
+            case Uncompress:
+                return uncompress(c, encoding);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        switch (op) {
+            case Compress:
+                return uncompress(c, encoding);
+            case Uncompress:
+                return compress(c, encoding);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public boolean isLossless() {
+        return true;
+    }
+
     private static Stamp mkStamp(CompressionOp op, Stamp input, CompressEncoding encoding) {
         switch (op) {
             case Compress:
@@ -93,20 +146,18 @@
         throw GraalInternalError.shouldNotReachHere(String.format("Unexpected input stamp %s", input));
     }
 
-    public ValueNode getInput() {
-        return input;
-    }
-
     public CompressEncoding getEncoding() {
         return encoding;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (input instanceof CompressionNode) {
-            CompressionNode other = (CompressionNode) input;
+        if (getInput().isConstant()) {
+            return ConstantNode.forConstant(stamp(), evalConst(getInput().asConstant()), tool.getMetaAccess(), graph());
+        } else if (getInput() instanceof CompressionNode) {
+            CompressionNode other = (CompressionNode) getInput();
             if (op != other.op && encoding.equals(other.encoding)) {
-                return other.input;
+                return other.getInput();
             }
         }
         return this;
@@ -116,8 +167,8 @@
     public void generate(NodeLIRBuilderTool gen) {
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool();
         boolean nonNull;
-        if (input.stamp() instanceof ObjectStamp) {
-            nonNull = StampTool.isObjectNonNull(input.stamp());
+        if (getInput().stamp() instanceof ObjectStamp) {
+            nonNull = StampTool.isObjectNonNull(getInput().stamp());
         } else {
             // metaspace pointers are never null
             nonNull = true;
@@ -126,10 +177,10 @@
         Value result;
         switch (op) {
             case Compress:
-                result = hsGen.emitCompress(gen.operand(input), encoding, nonNull);
+                result = hsGen.emitCompress(gen.operand(getInput()), encoding, nonNull);
                 break;
             case Uncompress:
-                result = hsGen.emitUncompress(gen.operand(input), encoding, nonNull);
+                result = hsGen.emitUncompress(gen.operand(getInput()), encoding, nonNull);
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Mon May 26 16:16:47 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Mon May 26 17:43:45 2014 +0200
@@ -126,14 +126,14 @@
             }
         } else if (x() instanceof ConvertNode && y().isConstant()) {
             ConvertNode convertX = (ConvertNode) x();
-            ConstantNode newY = canonicalConvertConstant(convertX, y().asConstant());
+            ConstantNode newY = canonicalConvertConstant(tool, convertX, y().asConstant());
             if (newY != null) {
                 setX(convertX.getInput());
                 setY(newY);
             }
         } else if (y() instanceof ConvertNode && x().isConstant()) {
             ConvertNode convertY = (ConvertNode) y();
-            ConstantNode newX = canonicalConvertConstant(convertY, x().asConstant());
+            ConstantNode newX = canonicalConvertConstant(tool, convertY, x().asConstant());
             if (newX != null) {
                 setX(newX);
                 setY(convertY.getInput());
@@ -142,11 +142,11 @@
         return this;
     }
 
-    private ConstantNode canonicalConvertConstant(ConvertNode convert, Constant constant) {
+    private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) {
         if (convert.preservesOrder(condition())) {
             Constant reverseConverted = convert.reverse(constant);
             if (convert.convert(reverseConverted).equals(constant)) {
-                return ConstantNode.forPrimitive(convert.getInput().stamp(), reverseConverted, convert.graph());
+                return ConstantNode.forConstant(convert.getInput().stamp(), reverseConverted, tool.getMetaAccess(), convert.graph());
             }
         }
         return null;