# HG changeset patch # User Roland Schatz # Date 1401119025 -7200 # Node ID c44f617fb8d7474e44d60a0e6254d6e98235a3a4 # Parent 03e09ed7039d37f5b82be587de86638d54a18f2c Optimize compare compressed pattern. diff -r 03e09ed7039d -r c44f617fb8d7 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 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(); diff -r 03e09ed7039d -r c44f617fb8d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- 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;