# HG changeset patch # User Thomas Wuerthinger # Date 1312818175 -7200 # Node ID 9afae29fefebacd8e3a8b1c1a999c06ecced86d6 # Parent 6b5e8da7daacbb200513a32724ad3c70d5aa4424# Parent 3fe8c149b0b614155732db2c9c1415efd274a345 Merge. diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Aug 08 17:42:55 2011 +0200 @@ -255,19 +255,24 @@ } } lastState = fs; - } else if (block.blockPredecessors().size() > 1) { - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("STATE RESET"); + } else if (block.blockPredecessors().size() > 0) { + FrameState fs = null; + for (LIRBlock pred : block.blockPredecessors()) { + if (fs == null) { + fs = pred.lastState(); + } else if (fs != pred.lastState()) { + fs = null; + break; + } } - lastState = null; - } else if (block.blockPredecessors().size() == 1) { - LIRBlock pred = block.blockPredecessors().get(0); - FrameState fs = pred.lastState(); - assert fs != null : "block B" + block.blockID() + " pred block B" + pred.blockID(); if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("STATE CHANGE (singlePred)"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println(fs.toString()); + if (fs == null) { + TTY.println("STATE RESET"); + } else { + TTY.println("STATE CHANGE (singlePred)"); + if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + TTY.println(fs.toString()); + } } } lastState = fs; diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java Mon Aug 08 17:42:55 2011 +0200 @@ -104,6 +104,11 @@ return unorderedIsTrue; } + + public void setUnorderedIsTrue(boolean unorderedIsTrue) { + this.unorderedIsTrue = unorderedIsTrue; + } + /** * Swaps the operands to this if and mirrors the condition (e.g. > becomes <). * @see Condition#mirror() diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java Mon Aug 08 17:42:55 2011 +0200 @@ -26,10 +26,10 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.gen.LIRGenerator.LIRGeneratorOp; +import com.oracle.max.graal.compiler.ir.Phi.*; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp; import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess; import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -41,7 +41,6 @@ */ public class Conditional extends Binary { @Input private BooleanNode condition; - @Input private FrameState stateDuring; public BooleanNode condition() { return condition; @@ -52,15 +51,6 @@ condition = n; } - public FrameState stateDuring() { - return stateDuring; - } - - public void setStateDuring(FrameState n) { - updateUsages(stateDuring, n); - stateDuring = n; - } - /** * Constructs a new IfOp. * @param x the instruction producing the first value to be compared @@ -135,6 +125,38 @@ return super.lookup(clazz); } + public static class ConditionalStructure { + public final If ifNode; + public final Phi phi; + public final Merge merge; + public ConditionalStructure(If ifNode, Phi phi, Merge merge) { + this.ifNode = ifNode; + this.phi = phi; + this.merge = merge; + } + } + + public static ConditionalStructure createConditionalStructure(BooleanNode condition, Value trueValue, Value falseValue) { + return createConditionalStructure(condition, trueValue, falseValue, 0.5); + } + + public static ConditionalStructure createConditionalStructure(BooleanNode condition, Value trueValue, Value falseValue, double trueProbability) { + Graph graph = condition.graph(); + CiKind kind = trueValue.kind.meet(falseValue.kind); + If ifNode = new If(condition, trueProbability, graph); + EndNode trueEnd = new EndNode(graph); + EndNode falseEnd = new EndNode(graph); + ifNode.setTrueSuccessor(trueEnd); + ifNode.setFalseSuccessor(falseEnd); + Merge merge = new Merge(graph); + merge.addEnd(trueEnd); + merge.addEnd(falseEnd); + Phi phi = new Phi(kind, merge, PhiType.Value, graph); + phi.addInput(trueValue); + phi.addInput(falseValue); + return new ConditionalStructure(ifNode, phi, merge); + } + private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() { @Override public Node canonical(Node node, NotifyReProcess reProcess) { @@ -162,16 +184,12 @@ TTY.println("> Conditional canon'ed to ~Materialize"); } reProcess.reProccess(condition); // because we negate it - MaterializeNode materializeNode = new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph()); - materializeNode.setStateDuring(conditional.stateDuring()); - return materializeNode; + return new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph()); } else if (trueInt == 1 && falseInt == 0) { if (GraalOptions.TraceCanonicalizer) { TTY.println("> Conditional canon'ed to Materialize"); } - MaterializeNode materializeNode = new MaterializeNode(condition, node.graph()); - materializeNode.setStateDuring(conditional.stateDuring()); - return materializeNode; + return new MaterializeNode(condition, node.graph()); } } else if (falseValue instanceof Constant && !(trueValue instanceof Constant)) { conditional.setTrueValue(falseValue); diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java Mon Aug 08 17:42:55 2011 +0200 @@ -23,6 +23,7 @@ package com.oracle.max.graal.compiler.phases; import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.graph.collections.*; @@ -54,6 +55,9 @@ for (Node node : nodeWorkList) { CanonicalizerOp op = node.lookup(CanonicalizerOp.class); if (op != null) { + if (GraalOptions.TraceCanonicalizer) { + TTY.println("Canonicalizer: work on " + node); + } graph.mark(); Node canonical = op.canonical(node, reProcess); if (canonical != node) { diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java Mon Aug 08 17:42:55 2011 +0200 @@ -23,9 +23,8 @@ package com.oracle.max.graal.compiler.phases; import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.ir.Phi.PhiType; +import com.oracle.max.graal.compiler.ir.Conditional.ConditionalStructure; import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; @@ -70,22 +69,7 @@ condition = ((NegateBooleanNode) condition).value(); } if (!(condition instanceof Compare || condition instanceof IsNonNull || condition instanceof NegateBooleanNode || condition instanceof Constant)) { - If ifNode = new If(conditional.condition(), 0.5, graph); - EndNode trueEnd = new EndNode(graph); - EndNode falseEnd = new EndNode(graph); - ifNode.setTrueSuccessor(trueEnd); - ifNode.setFalseSuccessor(falseEnd); - Merge merge = new Merge(graph); - merge.addEnd(trueEnd); - merge.addEnd(falseEnd); - Phi phi = new Phi(conditional.kind, merge, PhiType.Value, graph); - phi.addInput(conditional.trueValue()); - phi.addInput(conditional.falseValue()); - //recreate framestate - FrameState stateDuring = conditional.stateDuring(); - FrameStateBuilder builder = new FrameStateBuilder(stateDuring); - builder.push(phi.kind, phi); - merge.setStateAfter(builder.create(stateDuring.bci)); + ConditionalStructure conditionalStructure = Conditional.createConditionalStructure(condition, conditional.trueValue(), conditional.falseValue()); // schedule the if... if (schedule == null) { schedule = new IdentifyBlocksPhase(false, false); @@ -96,15 +80,9 @@ Anchor prev = block.createAnchor(); FixedNode next = prev.next(); prev.setNext(null); - merge.setNext(next); - prev.setNext(ifNode); - conditional.replaceAndDelete(phi); - } else { - FrameState stateDuring = conditional.stateDuring(); - conditional.setStateDuring(null); - if (stateDuring != null && stateDuring.usages().size() == 0) { - stateDuring.delete(); - } + conditionalStructure.merge.setNext(next); + prev.setNext(conditionalStructure.ifNode); + conditional.replaceAndDelete(conditionalStructure.phi); } } } diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Aug 08 17:42:55 2011 +0200 @@ -762,9 +762,7 @@ Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type.isResolved()); Value object = frameState.apop(); if (typeInstruction != null) { - MaterializeNode materialize = new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph); - materialize.setStateDuring(frameState.create(bci())); - frameState.ipush(append(materialize)); + frameState.ipush(append(new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph))); } else { frameState.ipush(appendConstant(CiConstant.INT_0)); } diff -r 6b5e8da7daac -r 9afae29fefeb graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Aug 08 17:42:34 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Mon Aug 08 17:42:55 2011 +0200 @@ -29,6 +29,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.ir.Conditional.ConditionalStructure; import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.runtime.nodes.*; @@ -46,6 +47,8 @@ * CRI runtime implementation for the HotSpot VM. */ public class HotSpotRuntime implements RiRuntime { + private static final long DOUBLENAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN); + private static final int FLOATNAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN); final HotSpotVMConfig config; final HotSpotRegisterConfig regConfig; @@ -515,12 +518,24 @@ return graph; } } else if (holderName.equals("Ljava/lang/Float;")) { //XXX (gd) the non-raw versions of (F/D)2(I/L) should return a sanitized NaN in the NaN case. - if (fullName.equals("floatToRawIntBits(F)I") || fullName.equals("floatToIntBits(F)I")) { + if (fullName.equals("floatToRawIntBits(F)I")) { CompilerGraph graph = new CompilerGraph(this); Return ret = new Return(new FPConversionNode(CiKind.Int, new Local(CiKind.Float, 0, graph), graph), graph); graph.start().setNext(ret); graph.setReturn(ret); intrinsicGraphs.put(method, graph); + } else if (fullName.equals("floatToIntBits(F)I")) { + CompilerGraph graph = new CompilerGraph(this); + Local arg = new Local(CiKind.Float, 0, graph); + Compare isNan = new Compare(arg, Condition.NE, arg, graph); + isNan.setUnorderedIsTrue(true); + FPConversionNode fpConv = new FPConversionNode(CiKind.Int, arg, graph); + ConditionalStructure conditionalStructure = Conditional.createConditionalStructure(isNan, Constant.forInt(FLOATNAN_RAW_INT_BITS, graph), fpConv, 0.1); + Return ret = new Return(conditionalStructure.phi, graph); + graph.start().setNext(conditionalStructure.ifNode); + conditionalStructure.merge.setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); } else if (fullName.equals("intBitsToFloat(I)F")) { CompilerGraph graph = new CompilerGraph(this); Return ret = new Return(new FPConversionNode(CiKind.Float, new Local(CiKind.Int, 0, graph), graph), graph); @@ -529,12 +544,24 @@ intrinsicGraphs.put(method, graph); } } else if (holderName.equals("Ljava/lang/Double;")) { - if (fullName.equals("doubleToRawLongBits(D)J") || fullName.equals("doubleToLongBits(D)J")) { + if (fullName.equals("doubleToRawLongBits(D)J")) { CompilerGraph graph = new CompilerGraph(this); Return ret = new Return(new FPConversionNode(CiKind.Long, new Local(CiKind.Double, 0, graph), graph), graph); graph.start().setNext(ret); graph.setReturn(ret); intrinsicGraphs.put(method, graph); + } else if (fullName.equals("doubleToLongBits(D)J")) { + CompilerGraph graph = new CompilerGraph(this); + Local arg = new Local(CiKind.Double, 0, graph); + Compare isNan = new Compare(arg, Condition.NE, arg, graph); + isNan.setUnorderedIsTrue(true); + FPConversionNode fpConv = new FPConversionNode(CiKind.Long, arg, graph); + ConditionalStructure conditionalStructure = Conditional.createConditionalStructure(isNan, Constant.forLong(DOUBLENAN_RAW_LONG_BITS, graph), fpConv, 0.1); + Return ret = new Return(conditionalStructure.phi, graph); + graph.start().setNext(conditionalStructure.ifNode); + conditionalStructure.merge.setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); } else if (fullName.equals("longBitsToDouble(J)D")) { CompilerGraph graph = new CompilerGraph(this); Return ret = new Return(new FPConversionNode(CiKind.Double, new Local(CiKind.Long, 0, graph), graph), graph);