# HG changeset patch # User Christian Haeubl # Date 1330916185 28800 # Node ID cbedef8b4d15dbd21c4b9f8481ea8a386ed70067 # Parent a7c079d5dc87ce683e40e56e6adcddb183279444# Parent 0b781cdb0cfb65f2531632ba20a240426cdc7738 Merge diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java --- a/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.alloc/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java Sun Mar 04 18:56:25 2012 -0800 @@ -144,11 +144,18 @@ private CiValue[] curInRegisterState; private CiValue[] curOutRegisterState; private BitSet curLiveIn; - private int curOpId; - private boolean curPhiDefs; + private LIRInstruction curOp; + /** + * The spill slot for a variable, if the variable has ever been spilled. + */ private LocationMap canonicalSpillLocations; + /** + * The register that a variable got assigned at its definition, and so it should get that register when reloading after spilling. + */ + private LocationMap hintRegisterLocations; + public void execute() { assert LIRVerifier.verify(true, lir, frameMap); @@ -184,6 +191,7 @@ Debug.log("==== start linear scan allocation ===="); canonicalSpillLocations = new LocationMap(lir.numVariables()); + hintRegisterLocations = new LocationMap(lir.numVariables()); curInRegisterState = new CiValue[maxRegisterNum()]; curOutRegisterState = new CiValue[maxRegisterNum()]; for (Block block : lir.linearScanOrder()) { @@ -204,8 +212,7 @@ for (int opIdx = 0; opIdx < block.lir.size(); opIdx++) { LIRInstruction op = block.lir.get(opIdx); - curOpId = op.id(); - curPhiDefs = opIdx == 0; + curOp = op; Debug.log(" op %d %s", op.id(), op); @@ -230,9 +237,13 @@ if (op.hasCall()) { spillCallerSaveRegisters(); } + if (op instanceof StandardOp.PhiLabelOp) { + assert opIdx == 0; + phiRegisterHints(block); + } + op.forEachOutput(defProc); op.forEachTemp(defProc); - op.forEachOutput(defProc); // Fixed temp and output registers can evict variables from their assigned register, allocate new location for them. fixupEvicted(); @@ -248,7 +259,7 @@ dataFlow.forEachKilled(op, true, unblockProc); dataFlow.forEachKilled(op, true, killProc); - curOpId = -1; + curOp = null; } assert endLocationsFor(block) == null; @@ -323,8 +334,8 @@ private CiValue recordUse(CiValue value) { if (isVariable(value)) { - assert lastUseFor(asVariable(value)) <= curOpId; - setLastUseFor(asVariable(value), curOpId); + assert lastUseFor(asVariable(value)) <= curOp.id(); + setLastUseFor(asVariable(value), curOp.id()); } return value; @@ -396,30 +407,61 @@ } - private Location allocateRegister(final Variable variable, OperandMode mode, EnumSet flags) { -// if (flags.contains(OperandFlag.RegisterHint)) { -// CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() { -// @Override -// public CiValue doValue(CiValue registerHint) { -// Debug.log(" registerHint %s", registerHint); -// CiRegister hint = null; -// if (isRegister(registerHint)) { -// hint = asRegister(registerHint); -// } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) { -// hint = asRegister(asLocation(registerHint).location); -// } -// if (hint != null && hint.isSet(variable.flag) && isFree(hint, inRegisterState, outRegisterState)) { -// return selectRegister(hint, variable, inRegisterState, outRegisterState); -// } -// return null; -// } -// }); -// -// if (result != null) { -// return asLocation(result); -// } -// } -// + private void phiRegisterHints(Block block) { + Debug.log(" phi register hints for %s", block); + CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions(); + for (Block pred : block.getPredecessors()) { + CiValue[] phiInputs = ((StandardOp.PhiJumpOp) pred.lir.get(pred.lir.size() - 1)).getPhiInputs(); + + for (int i = 0; i < phiDefinitions.length; i++) { + CiValue phiDefinition = phiDefinitions[i]; + CiValue phiInput = phiInputs[i]; + + if (isVariable(phiDefinition)) { + Location hintResult = processRegisterHint(asVariable(phiDefinition), OperandMode.Output, phiInput); + if (hintResult != null) { + phiDefinitions[i] = hintResult; + } + } + } + } + } + + private Location processRegisterHint(Variable variable, OperandMode mode, CiValue registerHint) { + if (registerHint == null) { + return null; + } + Debug.log(" try registerHint for %s %s: %s", mode, variable, registerHint); + CiRegister hint = null; + if (isRegister(registerHint)) { + hint = asRegister(registerHint); + } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) { + hint = asRegister(asLocation(registerHint).location); + } + if (hint != null && hint.isSet(variable.flag) && isFree(hint, mode)) { + return selectRegister(hint, variable, mode); + } + return null; + } + + private Location allocateRegister(final Variable variable, final OperandMode mode, EnumSet flags) { + if (flags.contains(OperandFlag.RegisterHint)) { + CiValue hintResult = curOp.forEachRegisterHint(variable, mode, new ValueProcedure() { + @Override + public CiValue doValue(CiValue registerHint) { + return processRegisterHint(variable, mode, registerHint); + } + }); + if (hintResult != null) { + return asLocation(hintResult); + } + } + + CiValue hintResult = processRegisterHint(variable, mode, hintRegisterLocations.get(variable)); + if (hintResult != null) { + return asLocation(hintResult); + } + EnumMap categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters(); CiRegister[] availableRegs = categorizedRegs.get(variable.flag); @@ -440,10 +482,6 @@ } if (bestSpillCandidate == null) { - if (curPhiDefs) { - return selectSpillSlot(variable); - } - // This should not happen as long as all LIR instructions have fulfillable register constraints. But be safe in product mode and bail out. assert false; throw new GraalInternalError("No register available"); @@ -457,7 +495,7 @@ private void spill(Location value) { Location newLoc = spillLocation(value.variable); Debug.log(" spill %s to %s", value, newLoc); - if (!curPhiDefs) { + if (!(curOp instanceof StandardOp.PhiLabelOp)) { moveResolver.add(value, newLoc); } curLocations.put(newLoc); @@ -483,7 +521,7 @@ private Location spillCandidate(CiRegister reg) { CiValue in = curInRegisterState[reg.number]; CiValue out = curOutRegisterState[reg.number]; - if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOpId) { + if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOp.id()) { return asLocation(in); } return null; @@ -521,6 +559,9 @@ curOutRegisterState[reg.number] = loc; curLocations.put(loc); recordUse(variable); + if (hintRegisterLocations.get(variable) == null) { + hintRegisterLocations.put(loc); + } Debug.log(" selected register %s", loc); return loc; diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Sun Mar 04 18:56:25 2012 -0800 @@ -81,10 +81,8 @@ if (osrBCI != -1) { throw new CiBailout("No OSR supported"); } - Debug.dump(this, "compiler"); - Debug.dump(method, "method"); - return Debug.scope(createScopeName(method), graph, new Callable() { + return Debug.scope(createScopeName(method), new Object[] {graph, method, this}, new Callable() { public CiTargetMethod call() { final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null; final LIR lir = Debug.scope("FrontEnd", new Callable() { @@ -213,7 +211,7 @@ assert startBlock != null; assert startBlock.numberOfPreds() == 0; - return Debug.scope("Compute Linear Scan Order", new Callable() { + return Debug.scope("ComputeLinearScanOrder", new Callable() { @Override public LIR call() { @@ -237,9 +235,8 @@ public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final RiResolvedMethod method) { final FrameMap frameMap = backend.newFrameMap(runtime.getRegisterConfig(method)); final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir, xir); - Debug.dump(lirGenerator, "LIRGenerator"); - Debug.scope("LIRGen", new Runnable() { + Debug.scope("LIRGen", lirGenerator, new Runnable() { public void run() { for (Block b : lir.linearScanOrder()) { lirGenerator.doBlock(b); diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java --- a/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Sun Mar 04 18:56:25 2012 -0800 @@ -64,16 +64,20 @@ } public static void scope(String name, Runnable runnable) { - scope(name, null, runnable); + scope(name, new Object[0], runnable); } public static T scope(String name, Callable callable) { - return scope(name, null, callable); + return scope(name, new Object[0], callable); } public static void scope(String name, Object context, Runnable runnable) { + scope(name, new Object[] {context}, runnable); + } + + public static void scope(String name, Object[] context, Runnable runnable) { if (ENABLED) { - DebugScope.getInstance().scope(name, runnable, null, false, new Object[] {context}); + DebugScope.getInstance().scope(name, runnable, null, false, context); } else { runnable.run(); } @@ -88,8 +92,12 @@ } public static T scope(String name, Object context, Callable callable) { + return scope(name, new Object[] {context}, callable); + } + + public static T scope(String name, Object[] context, Callable callable) { if (ENABLED) { - return DebugScope.getInstance().scope(name, null, callable, false, new Object[] {context}); + return DebugScope.getInstance().scope(name, null, callable, false, context); } else { return DebugScope.call(callable); } diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/BitMap.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/BitMap.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/BitMap.java Sun Mar 04 18:56:25 2012 -0800 @@ -261,6 +261,27 @@ } /** + * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two + * bitmaps will be set in this bitmap following this operation. It returns whether this bitmap was changed by the operation. + * + * @param other the other bitmap for the union operation + */ + public boolean setUnionWithResult(BitMap other) { + long temp = low | other.low; + boolean changed = temp != low; + low = temp; + + if (extra != null && other.extra != null) { + for (int i = 0; i < extra.length && i < other.extra.length; i++) { + temp = extra[i] | other.extra[i]; + changed = changed || temp != extra[i]; + extra[i] |= temp; + } + } + return changed; + } + + /** * Performs the union operation on this bitmap with the specified bitmap. That is, a bit is set in this * bitmap if and only if it is set in both this bitmap and the specified bitmap. * diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeList.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeList.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeList.java Sun Mar 04 18:56:25 2012 -0800 @@ -363,6 +363,15 @@ @Override public String toString() { - return Arrays.toString(nodes); + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (int i = 0; i < size; i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(nodes[i]); + } + sb.append(']'); + return sb.toString(); } } diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java Sun Mar 04 18:56:25 2012 -0800 @@ -39,6 +39,12 @@ size = values.length; } + public NodeMap(NodeMap copyFrom) { + this.graph = copyFrom.graph; + this.values = Arrays.copyOf(copyFrom.values, copyFrom.values.length); + this.size = copyFrom.size; + } + @SuppressWarnings("unchecked") public T get(Node node) { check(node); diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/ArrayCopySnippets.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/snippets/ArrayCopySnippets.java Sun Mar 04 18:56:25 2012 -0800 @@ -259,7 +259,7 @@ @Snippet public static void copyIntsDown(Object src, long srcOffset, Object dest, long destOffset, int length) { - long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short); + long header = ArrayHeaderSizeNode.sizeFor(CiKind.Int); for (long i = (length - 1) * 4; i >= 0; i -= 4) { Integer a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Int); UnsafeStoreNode.store(dest, i + (destOffset + header), a.intValue(), CiKind.Int); @@ -268,7 +268,7 @@ @Snippet public static void copyLongsDown(Object src, long srcOffset, Object dest, long destOffset, int length) { - long header = ArrayHeaderSizeNode.sizeFor(CiKind.Short); + long header = ArrayHeaderSizeNode.sizeFor(CiKind.Long); for (long i = (length - 1) * 8; i >= 0; i -= 8) { Long a = UnsafeLoadNode.load(src, i + (srcOffset + header), CiKind.Long); UnsafeStoreNode.store(dest, i + (destOffset + header), a.longValue(), CiKind.Long); diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java --- a/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/cfg/ControlFlowGraph.java Sun Mar 04 18:56:25 2012 -0800 @@ -123,10 +123,8 @@ } } - // Compute reverse postorder. - reversePostOrder = new Block[numBlocks]; - int reversePostOrderId = numBlocks - 1; - + // Compute postorder. + ArrayList postOrder = new ArrayList<>(numBlocks); ArrayList stack = new ArrayList<>(); stack.add(blockFor(graph.start())); @@ -136,45 +134,60 @@ // First time we see this block: push all successors. for (Node suxNode : block.getEndNode().cfgSuccessors()) { Block suxBlock = blockFor(suxNode); - assert suxBlock.id != BLOCK_ID_VISITED : "Sux already visited?? from " + block.getEndNode() + " to " + suxNode; if (suxBlock.id == BLOCK_ID_INITIAL) { stack.add(suxBlock); } } block.id = BLOCK_ID_VISITED; } else if (block.id == BLOCK_ID_VISITED) { - // Second time we see this block: All successors haved been processed, so insert block into reverse postorder list. + // Second time we see this block: All successors have been processed, so add block to postorder list. stack.remove(stack.size() - 1); - reversePostOrder[reversePostOrderId] = block; - block.id = reversePostOrderId; - reversePostOrderId--; + postOrder.add(block); } else { throw GraalInternalError.shouldNotReachHere(); } } while (!stack.isEmpty()); - assert reversePostOrderId == -1; + + // Compute reverse postorder and number blocks. + assert postOrder.size() <= numBlocks : "some blocks originally created can be unreachable, so actual block list can be shorter"; + numBlocks = postOrder.size(); + reversePostOrder = new Block[numBlocks]; + for (int i = 0; i < numBlocks; i++) { + reversePostOrder[i] = postOrder.get(numBlocks - i - 1); + reversePostOrder[i].id = i; + } } - // Connect blocks (including loop backward edges). + // Connect blocks (including loop backward edges), but ignoring dead code (blocks with id < 0). private void connectBlocks() { for (Block block : reversePostOrder) { List predecessors = new ArrayList<>(); for (Node predNode : block.getBeginNode().cfgPredecessors()) { - predecessors.add(nodeToBlock.get(predNode)); + Block predBlock = nodeToBlock.get(predNode); + if (predBlock.id >= 0) { + predecessors.add(predBlock); + } } if (block.getBeginNode() instanceof LoopBeginNode) { for (LoopEndNode predNode : ((LoopBeginNode) block.getBeginNode()).orderedLoopEnds()) { - predecessors.add(nodeToBlock.get(predNode)); + Block predBlock = nodeToBlock.get(predNode); + if (predBlock.id >= 0) { + predecessors.add(predBlock); + } } } block.predecessors = predecessors; List successors = new ArrayList<>(); for (Node suxNode : block.getEndNode().cfgSuccessors()) { - successors.add(nodeToBlock.get(suxNode)); + Block suxBlock = nodeToBlock.get(suxNode); + assert suxBlock.id >= 0; + successors.add(suxBlock); } if (block.getEndNode() instanceof LoopEndNode) { - successors.add(nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin())); + Block suxBlock = nodeToBlock.get(((LoopEndNode) block.getEndNode()).loopBegin()); + assert suxBlock.id >= 0; + successors.add(suxBlock); } block.successors = successors; } diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/LoopBeginNode.java Sun Mar 04 18:56:25 2012 -0800 @@ -126,7 +126,6 @@ @Override public boolean verify() { assertTrue(loopEnds().isNotEmpty(), "missing loopEnd"); - assertTrue(forwardEndCount() == 1, "LoopBegin should only have one forward edge"); return super.verify(); } diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/ConditionalNode.java Sun Mar 04 18:56:25 2012 -0800 @@ -22,10 +22,7 @@ */ package com.oracle.max.graal.nodes.calc; -import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.PhiNode.PhiType; import com.oracle.max.graal.nodes.spi.*; /** @@ -54,41 +51,6 @@ return y(); } - public static class ConditionalStructure { - - public final IfNode ifNode; - public final PhiNode phi; - public final MergeNode merge; - - public ConditionalStructure(IfNode ifNode, PhiNode phi, MergeNode merge) { - this.ifNode = ifNode; - this.phi = phi; - this.merge = merge; - } - } - - public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { - return createConditionalStructure(condition, trueValue, falseValue, 0.5); - } - - public static ConditionalStructure createConditionalStructure(BooleanNode condition, ValueNode trueValue, ValueNode falseValue, double trueProbability) { - Graph graph = condition.graph(); - assert trueValue.kind() == falseValue.kind(); - CiKind kind = trueValue.kind(); - IfNode ifNode = graph.add(new IfNode(condition, trueProbability)); - EndNode trueEnd = graph.add(new EndNode()); - EndNode falseEnd = graph.add(new EndNode()); - ifNode.setTrueSuccessor(BeginNode.begin(trueEnd)); - ifNode.setFalseSuccessor(BeginNode.begin(falseEnd)); - MergeNode merge = graph.add(new MergeNode()); - merge.addForwardEnd(trueEnd); - merge.addForwardEnd(falseEnd); - PhiNode phi = graph.unique(new PhiNode(kind, merge, PhiType.Value)); - phi.addInput(trueValue); - phi.addInput(falseValue); - return new ConditionalStructure(ifNode, phi, merge); - } - @Override public ValueNode canonical(CanonicalizerTool tool) { if (condition instanceof ConstantNode) { diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java Sun Mar 04 18:56:25 2012 -0800 @@ -28,13 +28,11 @@ import java.util.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.alloc.util.*; import com.oracle.max.graal.compiler.alloc.*; import com.oracle.max.graal.compiler.alloc.Interval.UsePosList; import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.graph.Node.Verbosity; import com.oracle.max.graal.graph.NodeClass.NodeClassIterator; @@ -50,20 +48,18 @@ */ class CFGPrinter extends CompilationPrinter { - public final CiTarget target; - public final RiRuntime runtime; - public LIR lir; - public LIRGenerator lirGenerator; + protected CiTarget target; + protected LIR lir; + protected LIRGenerator lirGenerator; + protected ControlFlowGraph cfg; /** * Creates a control flow graph printer. * * @param buffer where the output generated via this printer shown be written */ - public CFGPrinter(OutputStream out, CiTarget target, RiRuntime runtime) { + public CFGPrinter(OutputStream out) { super(out); - this.target = target; - this.runtime = runtime; } /** @@ -119,22 +115,78 @@ } + private NodeMap latestScheduling; + private NodeBitMap printedNodes; + + private boolean inFixedSchedule(Node node) { + return lir != null || node.isDeleted() || cfg.getNodeToBlock().get(node) != null; + } + /** * Prints the specified list of blocks. * * @param label A label describing the compilation phase that produced the control flow graph. * @param blocks The list of blocks to be printed. */ - public void printCFG(String label, List blocks, SchedulePhase schedule) { + public void printCFG(String label, List blocks) { + if (lir == null) { + latestScheduling = new NodeMap<>(cfg.getNodeToBlock()); + for (Block block : blocks) { + Node cur = block.getBeginNode(); + while (true) { + assert inFixedSchedule(cur) && latestScheduling.get(cur) == block; + scheduleInputs(cur, block); + + if (cur == block.getEndNode()) { + break; + } + assert cur.successors().count() == 1; + cur = cur.successors().first(); + } + } + } + printedNodes = new NodeBitMap(cfg.graph); + begin("cfg"); out.print("name \"").print(label).println('"'); for (Block block : blocks) { - printBlock(block, schedule); + printBlock(block); } end("cfg"); + + latestScheduling = null; + printedNodes = null; } - private void printBlock(Block block, SchedulePhase schedule) { + private void scheduleInputs(Node node, Block nodeBlock) { + if (node instanceof PhiNode) { + PhiNode phi = (PhiNode) node; + assert nodeBlock.getBeginNode() == phi.merge(); + for (Block pred : nodeBlock.getPredecessors()) { + schedule(phi.valueAt((EndNode) pred.getEndNode()), pred); + } + + } else { + for (Node input : node.inputs()) { + schedule(input, nodeBlock); + } + } + } + + private void schedule(Node input, Block block) { + if (!inFixedSchedule(input)) { + Block inputBlock = block; + if (latestScheduling.get(input) != null) { + inputBlock = ControlFlowGraph.commonDominator(inputBlock, latestScheduling.get(input)); + } + if (inputBlock != latestScheduling.get(input)) { + latestScheduling.set(input, inputBlock); + scheduleInputs(input, inputBlock); + } + } + } + + private void printBlock(Block block) { begin("block"); out.print("name \"").print(blockToString(block)).println('"'); @@ -180,15 +232,12 @@ out.print("loop_depth ").println(block.getLoop().depth); } - printNodes(block, schedule); + printNodes(block); printLIR(block); end("block"); } - private void printNodes(Block block, SchedulePhase schedule) { - if (schedule == null) { - return; - } + private void printNodes(Block block) { begin("IR"); out.println("HIR"); out.disableIndentation(); @@ -196,25 +245,59 @@ if (block.getPredecessors().size() == 0) { // Currently method parameters are not in the schedule, so print them separately here. for (ValueNode param : block.getBeginNode().graph().getNodes(LocalNode.class)) { - printNode(param); + printNode(param, false); } } if (block.getBeginNode() instanceof MergeNode) { // Currently phi functions are not in the schedule, so print them separately here. for (ValueNode phi : ((MergeNode) block.getBeginNode()).phis()) { - printNode(phi); + printNode(phi, false); } } - for (Node node : schedule.nodesFor(block)) { - printNode(node); + if (lir != null) { + for (Node node : lir.nodesFor(block)) { + printNode(node, false); + } + } else { + Node cur = block.getBeginNode(); + while (true) { + printNode(cur, false); + + if (cur == block.getEndNode()) { + for (Map.Entry entry : latestScheduling.entries()) { + if (entry.getValue() == block && !inFixedSchedule(entry.getKey()) && !printedNodes.isMarked(entry.getKey())) { + printNode(entry.getKey(), true); + } + } + break; + } + assert cur.successors().count() == 1; + cur = cur.successors().first(); + } + } + out.enableIndentation(); end("IR"); } - private void printNode(Node node) { - if (node instanceof FixedWithNextNode) { + private void printNode(Node node, boolean unscheduled) { + assert !printedNodes.isMarked(node); + printedNodes.mark(node); + + if (!(node instanceof PhiNode)) { + for (Node input : node.inputs()) { + if (!inFixedSchedule(input) && !printedNodes.isMarked(input)) { + printNode(input, true); + } + } + } + + if (unscheduled) { + assert lir == null : "unscheduled nodes can only be present before LIR generation"; + out.print("f ").print(HOVER_START).print("u").print(HOVER_SEP).print("unscheduled").print(HOVER_END).println(COLUMN_END); + } else if (node instanceof FixedWithNextNode) { out.print("f ").print(HOVER_START).print("#").print(HOVER_SEP).print("fixed with next").print(HOVER_END).println(COLUMN_END); } else if (node instanceof FixedNode) { out.print("f ").print(HOVER_START).print("*").print(HOVER_SEP).print("fixed").print(HOVER_END).println(COLUMN_END); diff -r a7c079d5dc87 -r cbedef8b4d15 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Fri Mar 02 18:50:51 2012 -0800 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Sun Mar 04 18:56:25 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,10 +32,11 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.alloc.*; import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.debug.*; +import com.oracle.max.graal.graph.*; import com.oracle.max.graal.java.*; import com.oracle.max.graal.lir.*; +import com.oracle.max.graal.lir.cfg.*; import com.oracle.max.graal.nodes.*; /** @@ -45,30 +46,11 @@ public class CFGPrinterObserver implements DebugDumpHandler { private CFGPrinter cfgPrinter; - - private GraalCompiler compiler; - private RiResolvedMethod method; - private SchedulePhase schedule; + private Graph curGraph; @Override - public void dump(final Object object, final String message) { - Debug.sandbox("CFGPrinter", new Runnable() { - @Override - public void run() { - dumpSandboxed(object, message); - } - }); - } - - private void dumpSandboxed(final Object object, final String message) { - if (object instanceof GraalCompiler) { - compiler = (GraalCompiler) object; - return; - } else if (object instanceof SchedulePhase) { - schedule = (SchedulePhase) object; - return; - } - + public void dump(Object object, String message) { + GraalCompiler compiler = Debug.contextLookup(GraalCompiler.class); if (compiler == null) { return; } @@ -77,57 +59,61 @@ File file = new File("compilations-" + System.currentTimeMillis() + ".cfg"); try { OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); - cfgPrinter = new CFGPrinter(out, compiler.target, compiler.runtime); + cfgPrinter = new CFGPrinter(out); } catch (FileNotFoundException e) { - throw new InternalError("Could not open " + file.getAbsolutePath()); + throw new GraalInternalError("Could not open " + file.getAbsolutePath()); } TTY.println("CFGPrinter: Output to file %s", file); } - RiRuntime runtime = cfgPrinter.runtime; - if (object instanceof LIRGenerator) { - cfgPrinter.lirGenerator = (LIRGenerator) object; - } else if (object instanceof RiResolvedMethod) { - method = (RiResolvedMethod) object; - cfgPrinter.printCompilation(method); + StructuredGraph newGraph = Debug.contextLookup(StructuredGraph.class); + if (newGraph != curGraph) { + cfgPrinter.printCompilation(newGraph.method()); + TTY.println("CFGPrinter: Dumping method %s", newGraph.method()); + curGraph = newGraph; + } - cfgPrinter.lir = null; - cfgPrinter.lirGenerator = null; - schedule = null; - TTY.println("CFGPrinter: Dumping method %s", method); + cfgPrinter.target = compiler.target; + if (object instanceof LIR) { + cfgPrinter.lir = (LIR) object; + } else { + cfgPrinter.lir = Debug.contextLookup(LIR.class); + } + cfgPrinter.lirGenerator = Debug.contextLookup(LIRGenerator.class); + if (cfgPrinter.lir != null) { + cfgPrinter.cfg = cfgPrinter.lir.cfg; + } - } else if (object instanceof BciBlockMapping) { + RiRuntime runtime = compiler.runtime; + + if (object instanceof BciBlockMapping) { BciBlockMapping blockMap = (BciBlockMapping) object; cfgPrinter.printCFG(message, blockMap); cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method)); } else if (object instanceof LIR) { - cfgPrinter.lir = (LIR) object; - cfgPrinter.printCFG(message, ((LIR) object).codeEmittingOrder(), schedule); + cfgPrinter.printCFG(message, cfgPrinter.lir.codeEmittingOrder()); } else if (object instanceof StructuredGraph) { - SchedulePhase curSchedule = schedule; - if (curSchedule == null) { - try { - curSchedule = new SchedulePhase(); - curSchedule.apply((StructuredGraph) object); - } catch (Throwable ex) { - curSchedule = null; - // ignore - } + if (cfgPrinter.cfg == null) { + cfgPrinter.cfg = ControlFlowGraph.compute((StructuredGraph) object, true, true, true, false); } - if (curSchedule != null && curSchedule.getCFG() != null) { - cfgPrinter.printCFG(message, Arrays.asList(curSchedule.getCFG().getBlocks()), curSchedule); - } + cfgPrinter.printCFG(message, Arrays.asList(cfgPrinter.cfg.getBlocks())); } else if (object instanceof CiTargetMethod) { cfgPrinter.printMachineCode(runtime.disassemble((CiTargetMethod) object), null); + } else if (object instanceof Interval[]) { cfgPrinter.printIntervals(message, (Interval[]) object); + } else if (object instanceof IntervalPrinter.Interval[]) { cfgPrinter.printIntervals(message, (IntervalPrinter.Interval[]) object); } + cfgPrinter.target = null; + cfgPrinter.lir = null; + cfgPrinter.lirGenerator = null; + cfgPrinter.cfg = null; cfgPrinter.flush(); } } diff -r a7c079d5dc87 -r cbedef8b4d15 mx/commands.py --- a/mx/commands.py Fri Mar 02 18:50:51 2012 -0800 +++ b/mx/commands.py Sun Mar 04 18:56:25 2012 -0800 @@ -656,31 +656,10 @@ clean([] if args.buildNative else ['--no-native']) tasks.append(t.stop()) - t = Task('Checkstyle') - if mx.checkstyle([]) != 0: - t.abort('Checkstyle warnings were found') - tasks.append(t.stop()) - - t = Task('Canonicalization Check') - mx.log(time.strftime('%d %b %Y %H:%M:%S - Ensuring mx/projects files are canonicalized...')) - if mx.canonicalizeprojects([]) != 0: - t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.') - tasks.append(t.stop()) - t = Task('BuildJava') build(['--no-native']) tasks.append(t.stop()) - t = Task('CleanAndBuildGraalVisualizer') - mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build']) - tasks.append(t.stop()) - - # Prevent Graal modifications from breaking the standard builds - if args.buildNative and args.buildNonGraal: - t = Task('BuildHotSpotVarieties') - buildvms(['--vms', 'client,server', '--builds', 'fastdebug,product']) - tasks.append(t.stop()) - for vmbuild in ['fastdebug', 'product']: global _vmbuild _vmbuild = vmbuild @@ -707,6 +686,28 @@ if not test.test('graal'): t.abort(test.group + ' ' + test.name + ' Failed') tasks.append(t.stop()) + + t = Task('Checkstyle') + if mx.checkstyle([]) != 0: + t.abort('Checkstyle warnings were found') + tasks.append(t.stop()) + + t = Task('Canonicalization Check') + mx.log(time.strftime('%d %b %Y %H:%M:%S - Ensuring mx/projects files are canonicalized...')) + if mx.canonicalizeprojects([]) != 0: + t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.') + tasks.append(t.stop()) + + t = Task('CleanAndBuildGraalVisualizer') + mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build']) + tasks.append(t.stop()) + + # Prevent Graal modifications from breaking the standard builds + if args.buildNative and args.buildNonGraal: + t = Task('BuildHotSpotVarieties') + buildvms(['--vms', 'client,server', '--builds', 'fastdebug,product']) + tasks.append(t.stop()) + except KeyboardInterrupt: total.abort(1) diff -r a7c079d5dc87 -r cbedef8b4d15 mxtool/URLConnectionDownload.java --- a/mxtool/URLConnectionDownload.java Fri Mar 02 18:50:51 2012 -0800 +++ b/mxtool/URLConnectionDownload.java Sun Mar 04 18:56:25 2012 -0800 @@ -53,6 +53,10 @@ System.setProperty("java.net.useSystemProxies", "true"); String proxy = System.getenv("HTTP_PROXY"); + if (proxy == null) { + String proxy = System.getenv("http_proxy"); + } + String proxyMsg = ""; if (proxy != null) { Pattern p = Pattern.compile("(?:http://)?([^:]+)(:\\d+)?");