Mercurial > hg > graal-compiler
changeset 2792:2f3258e3800e
Merge.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Thu, 26 May 2011 11:55:16 +0200 |
parents | 6d14aa4fbf90 (diff) 9253df721472 (current diff) |
children | d3fc4fe063bf |
files | graal/GraalGraph/src/com/oracle/graal/graph/Node.java |
diffstat | 15 files changed, 153 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java Thu May 26 11:55:16 2011 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; import com.sun.c1x.ir.*; +import com.sun.c1x.lir.*; public class Schedule { @@ -67,18 +68,20 @@ private Block assignBlock(Node n, Block b) { assert nodeToBlock.get(n) == null; nodeToBlock.set(n, b); - b.getInstructions().add((Instruction) n); + if (n != n.graph().start()) { + b.getInstructions().add((Instruction) n); + } return b; } private boolean isCFG(Node n) { - return n != null && (n instanceof Instruction); + return n != null && ((n instanceof Instruction) || n == n.graph().start()); } private void identifyBlocks() { // Identify blocks. final ArrayList<Node> blockBeginNodes = new ArrayList<Node>(); - NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start().successors().get(0), null, new NodeVisitor() { + NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() { @Override public boolean visit(Node n) { if (!isCFG(n)) { @@ -185,8 +188,11 @@ TTY.print(pred + ";"); } TTY.println(); - TTY.print("first instr: " + b.getInstructions().get(0)); - TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1)); + + if (b.getInstructions().size() > 0) { + TTY.print("first instr: " + b.getInstructions().get(0)); + TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1)); + } } /*
--- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java Thu May 26 11:55:16 2011 +0200 @@ -27,6 +27,7 @@ import java.util.*; +import com.oracle.graal.graph.*; import com.sun.c1x.*; import com.sun.c1x.alloc.Interval.*; import com.sun.c1x.debug.*; @@ -725,7 +726,7 @@ // this is checked by these assertions to be sure about it. // the entry block may have incoming // values in registers, which is ok. - if (!operand.isVariable() /*&& block != ir.startBlock*/) { + if (!operand.isVariable() && block != ir.startBlock) { if (isProcessed(operand)) { assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block"; } @@ -812,12 +813,16 @@ reportFailure(numBlocks); } + TTY.println("preds=" + startBlock.blockPredecessors().size() + ", succs=" + startBlock.blockSuccessors().size()); + TTY.println("startBlock-ID: " + startBlock.blockID()); + // bailout of if this occurs in product mode. throw new CiBailout("liveIn set of first block must be empty"); } } private void reportFailure(int numBlocks) { + TTY.println(compilation.method.toString()); TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)"); TTY.print("affected registers:"); TTY.println(ir.startBlock.liveIn.toString()); @@ -829,6 +834,17 @@ Value instr = operand.isVariable() ? gen.operands.instructionForResult(((CiVariable) operand)) : null; TTY.println(" var %d (HIR instruction %s)", operandNum, instr == null ? " " : instr.toString()); + if (instr instanceof Phi) { + Phi phi = (Phi) instr; + TTY.println("phi block begin: " + phi.block()); + TTY.println("pred count on blockbegin: " + phi.block().predecessors().size()); + TTY.println("phi values: " + phi.valueCount()); + TTY.println("phi block preds:"); + for (Node n : phi.block().predecessors()) { + TTY.println(n.toString()); + } + } + for (int j = 0; j < numBlocks; j++) { LIRBlock block = blockAt(j); if (block.liveGen.get(operandNum)) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Thu May 26 11:55:16 2011 +0200 @@ -253,6 +253,10 @@ } } } + if (block.blockSuccessors().size() == 1 && (block.getInstructions().size() == 0 || !(block.getInstructions().get(block.getInstructions().size() - 1) instanceof BlockEnd))) { + moveToPhi(); + block.lir().jump(block.blockSuccessors().get(0)); + } if (C1XOptions.TraceLIRGeneratorLevel >= 1) { TTY.println("END Generating LIR for block B" + block.blockID()); @@ -587,7 +591,11 @@ } protected LIRBlock getLIRBlock(Instruction b) { - return ir.valueToBlock.get(b); + LIRBlock result = ir.valueToBlock.get(b); + if (result == null) { + TTY.println("instruction without lir block: " + b); + } + return result; } @Override @@ -1320,7 +1328,7 @@ PhiResolver resolver = new PhiResolver(this); for (Phi phi : phis) { - if (!phi.isDeadPhi() && phi.valueCount() > predIndex) { + if (!phi.isDeadPhi()) { Value curVal = phi.valueAt(predIndex); if (curVal != null && curVal != phi) { if (curVal instanceof Phi) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/PhiSimplifier.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/PhiSimplifier.java Thu May 26 11:55:16 2011 +0200 @@ -44,6 +44,11 @@ return x; } Phi phi = (Phi) x; + + if (phi.valueCount() == 1) { + return (Value) phi.replace(phi.valueAt(0)); + } + if (phi.checkFlag(Value.Flag.PhiCannotSimplify)) { // already tried, cannot simplify this phi return phi;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Thu May 26 11:55:16 2011 +0200 @@ -45,9 +45,9 @@ * The graph edges represented as a map from source to target nodes. * Using a linked hash map makes compilation tracing more deterministic and thus eases debugging. */ - private Map<LIRBlock, Set<LIRBlock>> edges = C1XOptions.DetailedAsserts ? - new LinkedHashMap<LIRBlock, Set<LIRBlock>>() : - new HashMap<LIRBlock, Set<LIRBlock>>(); + private Map<LIRBlock, List<LIRBlock>> edges = C1XOptions.DetailedAsserts ? + new LinkedHashMap<LIRBlock, List<LIRBlock>>() : + new HashMap<LIRBlock, List<LIRBlock>>(); public CriticalEdgeFinder(List<LIRBlock> lirBlocks, Graph graph) { this.lirBlocks = lirBlocks; @@ -71,14 +71,14 @@ private void recordCriticalEdge(LIRBlock block, LIRBlock succ) { if (!edges.containsKey(block)) { - edges.put(block, new HashSet<LIRBlock>()); + edges.put(block, new ArrayList<LIRBlock>()); } edges.get(block).add(succ); } public void splitCriticalEdges() { - for (Map.Entry<LIRBlock, Set<LIRBlock>> entry : edges.entrySet()) { + for (Map.Entry<LIRBlock, List<LIRBlock>> entry : edges.entrySet()) { LIRBlock from = entry.getKey(); for (LIRBlock to : entry.getValue()) { LIRBlock split = splitEdge(from, to); @@ -104,17 +104,20 @@ lirBlocks.add(newSucc); // This goto is not a safepoint. - Goto e = new Goto(target.getInstructions().get(0), graph); + Goto e = new Goto(null, graph); + Instruction sourceInstruction = source.getInstructions().get(source.getInstructions().size() - 1); + Instruction targetInstruction = target.getInstructions().get(0); + int sourceInstructionPredIndex = targetInstruction.predecessors().indexOf(sourceInstruction); + int replacedIndex = targetInstruction.predecessorsIndex().get(sourceInstructionPredIndex); + assert replacedIndex != -1 && sourceInstruction.successors().get(replacedIndex) != null; + e.successors().setAndClear(1, sourceInstruction, replacedIndex); + sourceInstruction.successors().set(replacedIndex, e); newSucc.getInstructions().add(e); - - // link predecessor to new block - ((BlockEnd) source.getInstructions().get(source.getInstructions().size() - 1)).successors().replace(target.getInstructions().get(0), newSucc.getInstructions().get(0)); - + assert e.defaultSuccessor() != null; source.substituteSuccessor(target, newSucc); target.substitutePredecessor(source, newSucc); newSucc.blockPredecessors().add(source); newSucc.blockSuccessors().add(target); - return newSucc; } }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Thu May 26 11:55:16 2011 +0200 @@ -178,6 +178,7 @@ } } flags |= Flag.HasHandler.mask; + } // 1. create the start block @@ -220,20 +221,11 @@ for (Node n : graph.getNodes()) { if (n instanceof Placeholder) { Placeholder p = (Placeholder) n; - - /*if (p == graph.start().successors().get(0)) { - // nothing to do... - } else*/ if (p.blockPredecessors().size() == 0) { - assert p.next() == null; - p.delete(); - } else { - assert p.blockPredecessors().size() == 1; - for (Node pred : new ArrayList<Node>(p.predecessors())) { - pred.successors().replace(p, p.next()); - } - p.successors().clearAll(); - p.delete(); - } + assert p.blockPredecessors().size() == 1; + Node pred = p.blockPredecessors().get(0); + int predIndex = p.predecessorsIndex().get(0); + pred.successors().setAndClear(predIndex, p, 0); + p.delete(); } } @@ -290,8 +282,7 @@ private void finishStartBlock(Block startBlock) { assert bci() == 0; Instruction target = createTargetAt(0, frameState); - Goto base = new Goto(target, graph); - appendWithBCI(base); + appendGoto(target); } public void mergeOrClone(Block target, FrameStateAccess newState) { @@ -319,6 +310,8 @@ } else { if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { // stacks or locks do not match--bytecodes would not verify + TTY.println(existingState.toString()); + TTY.println(newState.duplicate(0).toString()); throw new CiBailout("stack or locks do not match"); } assert existingState.localsSize() == newState.localsSize(); @@ -326,9 +319,10 @@ if (first instanceof Placeholder) { BlockBegin merge = new BlockBegin(existingState.bci, target.blockID, target.isLoopHeader, graph); - for (Node n : new ArrayList<Node>(first.predecessors())) { - n.successors().replace(first, merge); - } + + Placeholder p = (Placeholder) first; + assert p.next() == null; + p.replace(merge); target.firstInstruction = merge; merge.setStateBefore(existingState); } @@ -610,7 +604,7 @@ } private void genGoto(int fromBCI, int toBCI) { - append(new Goto(createTargetAt(toBCI, frameState), graph)); + appendGoto(createTargetAt(toBCI, frameState)); } private void ifNode(Value x, Condition cond, Value y) { @@ -1062,9 +1056,14 @@ } private Instruction createTarget(Block block, FrameStateAccess stateAfter) { + assert block != null && stateAfter != null; assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors"; + if (block.isExceptionEntry) { + assert stateAfter.stackSize() == 1; + } + if (block.firstInstruction == null) { if (block.isLoopHeader) { block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); @@ -1165,17 +1164,26 @@ deopt.setMessage("unresolved " + block.handler.catchType().name()); append(deopt); Instruction nextDispatch = createTarget(block.next, frameState); - append(new Goto(nextDispatch, graph)); + appendGoto(nextDispatch); } } } + private void appendGoto(Instruction target) { + //if (target instanceof BlockBegin && !((BlockBegin)target).isLoopHeader) { + // System.out.println("NOTOMITTED"); + //append(new Goto(target, graph)); + //} else { + // System.out.println("omitted"); + lastInstr.appendNext(target); + //} + } + private void iterateBytecodesForBlock(Block block) { assert frameState != null; stream.setBCI(block.startBci); - BlockEnd end = null; int endBCI = stream.endBCI(); boolean blockStart = true; @@ -1183,10 +1191,10 @@ while (bci < endBCI) { Block nextBlock = blockFromBci[bci]; if (nextBlock != null && nextBlock != block) { + assert !nextBlock.isExceptionEntry; // we fell through to the next block, add a goto and break Instruction next = createTarget(nextBlock, frameState); - end = new Goto(next, graph); - lastInstr = lastInstr.appendNext(end); + appendGoto(next); break; } // read the opcode @@ -1196,10 +1204,10 @@ traceInstruction(bci, opcode, blockStart); processBytecode(bci, opcode); - if (lastInstr instanceof BlockEnd) { - end = (BlockEnd) lastInstr; + if (lastInstr instanceof BlockEnd || lastInstr.next() != null) { break; } + stream.next(); bci = stream.currentBCI(); if (lastInstr instanceof StateSplit) {
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Thu May 26 11:55:16 2011 +0200 @@ -122,9 +122,17 @@ valueToBlock.put(i, b); } } - startBlock = valueToBlock.get(getHIRStartBlock()); + startBlock = lirBlocks.get(0); assert startBlock != null; - verifyAndPrint("After linear scan order"); + assert startBlock.blockPredecessors().size() == 0; + +/* if (startBlock.blockPredecessors().size() > 0) { + LIRBlock oldStartBlock = startBlock; + startBlock = new LIRBlock(orderedBlocks.size()); + startBlock.blockSuccessors().add(oldStartBlock); + + orderedBlocks.add(startBlock); + }*/ ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), startBlock); orderedBlocks = clso.linearScanOrder(); @@ -135,7 +143,7 @@ b.setLinearScanNumber(z++); } - + verifyAndPrint("After linear scan order"); if (C1XOptions.PrintTimers) { C1XTimers.HIR_OPTIMIZE.stop();
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Thu May 26 11:55:16 2011 +0200 @@ -174,12 +174,12 @@ if (end() != null) { builder.append(" -> "); boolean hasSucc = false; - for (BlockBegin s : end().blockSuccessors()) { + for (Instruction s : end().blockSuccessors()) { if (hasSucc) { builder.append(", "); } builder.append("#"); - builder.append(s.blockID); + builder.append(s.id()); hasSucc = true; } }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Thu May 26 11:55:16 2011 +0200 @@ -35,8 +35,7 @@ private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 1; - private static final int SUCCESSOR_STATE_AFTER = 0; + private static final int SUCCESSOR_COUNT = 0; private final int blockSuccessorCount; @Override @@ -143,18 +142,6 @@ } /** - * This method reorders the predecessors of the i-th successor in such a way that this BlockEnd is at position backEdgeIndex. - */ - public void reorderSuccessor(int i, int backEdgeIndex) { - assert i >= 0 && i < blockSuccessorCount; - Instruction successor = blockSuccessor(i); - if (successor != null) { - successors().set(super.successorCount() + SUCCESSOR_COUNT + i, Node.Null); - successors().set(super.successorCount() + SUCCESSOR_COUNT + i, successor, backEdgeIndex); - } - } - - /** * Gets this block end's list of successors. * @return the successor list */
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Thu May 26 11:55:16 2011 +0200 @@ -461,9 +461,9 @@ // the start block is always the first block in the linear scan order linearScanOrder = new ArrayList<LIRBlock>(numBlocks); - appendBlock(startBlock); +// appendBlock(startBlock); - LIRBlock stdEntry = startBlock.suxAt(0); + LIRBlock stdEntry = startBlock; //.suxAt(0); // start processing with standard entry block assert workList.isEmpty() : "list must be empty before processing";
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Thu May 26 11:55:16 2011 +0200 @@ -256,6 +256,7 @@ for (int i = 0; i < successors.size(); ++i) { if (successors.get(i) == target) { successors.set(i, newSucc); + break; } } } @@ -264,6 +265,7 @@ for (int i = 0; i < predecessors.size(); ++i) { if (predecessors.get(i) == source) { predecessors.set(i, newSucc); + break; } } }
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java Thu May 26 11:55:16 2011 +0200 @@ -482,7 +482,7 @@ } public final LIRBlock exceptionEdge() { - return info.exceptionEdge; + return (info == null) ? null : info.exceptionEdge; } @Override
--- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Thu May 26 11:55:16 2011 +0200 @@ -39,6 +39,7 @@ final NodeArray successors; final ArrayList<Node> usages; final ArrayList<Node> predecessors; + final ArrayList<Integer> predecessorsIndex; public Node(int inputCount, int successorCount, Graph graph) { assert graph != null; @@ -48,12 +49,17 @@ this.successors = new NodeArray(this, successorCount); this.predecessors = new ArrayList<Node>(); this.usages = new ArrayList<Node>(); + this.predecessorsIndex = new ArrayList<Integer>(); } public List<Node> predecessors() { return Collections.unmodifiableList(predecessors); } + public List<Integer> predecessorsIndex() { + return Collections.unmodifiableList(predecessorsIndex); + } + public List<Node> usages() { return Collections.unmodifiableList(usages); } @@ -78,22 +84,28 @@ return getClass().getSimpleName(); } - public void replace(Node other) { - assert !isDeleted() && !other.isDeleted(); + public Node replace(Node other) { + assert !isDeleted() && (other == null || !other.isDeleted()); assert other == null || other.graph == graph; for (Node usage : usages) { usage.inputs.replaceFirstOccurrence(this, other); } + int z = 0; for (Node predecessor : predecessors) { - predecessor.successors.replaceFirstOccurrence(this, other); + int predIndex = predecessorsIndex.get(z); + predecessor.successors.nodes[predIndex] = other; + ++z; } if (other != null) { other.usages.addAll(usages); other.predecessors.addAll(predecessors); + other.predecessorsIndex.addAll(predecessorsIndex); } usages.clear(); predecessors.clear(); + predecessorsIndex.clear(); delete(); + return other; } public boolean isDeleted() { @@ -103,6 +115,7 @@ public void delete() { assert !isDeleted(); assert usages.size() == 0 && predecessors.size() == 0; + assert predecessorsIndex.size() == 0; for (int i = 0; i < inputs.size(); ++i) { inputs.set(i, Null); }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java Thu May 26 11:55:16 2011 +0200 @@ -24,12 +24,13 @@ import java.util.AbstractList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; public class NodeArray extends AbstractList<Node> { private final Node node; - private final Node[] nodes; + final Node[] nodes; public NodeArray(Node node, int length) { this.node = node; @@ -61,40 +62,17 @@ } else { assert self().successors == this; if (old != null) { - old.predecessors.remove(self()); + for (int i = 0; i < old.predecessors.size(); ++i) { + Node cur = old.predecessors.get(i); + if (cur == self() && old.predecessorsIndex.get(i) == index) { + old.predecessors.remove(i); + old.predecessorsIndex.remove(i); + } + } } if (node != null) { node.predecessors.add(self()); - } - } - } - - return old; - } - - /** - * Sets the specified input/successor to the given node, and inserts the back edge (usage/predecessor) at the given index. - */ - public Node set(int index, Node node, int backIndex) { - assert node == Node.Null || node.graph == self().graph; - Node old = nodes[index]; - - if (old != node) { - nodes[index] = node; - if (self().inputs == this) { - if (old != null) { - old.usages.remove(self()); - } - if (node != null) { - node.usages.add(backIndex, self()); - } - } else { - assert self().successors == this; - if (old != null) { - old.predecessors.remove(self()); - } - if (node != null) { - node.predecessors.add(backIndex, self()); + node.predecessorsIndex.add(index); } } } @@ -138,6 +116,22 @@ return result; } + public void setAndClear(int index, Node clearedNode, int clearedIndex) { + assert self().successors == this; + Node value = clearedNode.successors.get(clearedIndex); + assert value != Node.Null; + clearedNode.successors.nodes[clearedIndex] = Node.Null; + set(index, Node.Null); + nodes[index] = value; + + for (int i = 0; i < value.predecessors.size(); ++i) { + if (value.predecessors.get(i) == clearedNode && value.predecessorsIndex.get(i) == clearedIndex) { + value.predecessors.set(i, self()); + value.predecessorsIndex.set(i, index); + } + } + } + public int size() { return nodes.length; }
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java Wed May 25 17:48:56 2011 +0200 +++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java Thu May 26 11:55:16 2011 +0200 @@ -31,7 +31,6 @@ public class HotSpotOptions { public static void setDefaultOptions() { - C1XOptions.DetailedAsserts = false; C1XOptions.CommentedAssembly = false; C1XOptions.MethodEndBreakpointGuards = 2; C1XOptions.ResolveClassBeforeStaticInvoke = false; @@ -78,7 +77,7 @@ } if (value != null) { f.set(null, value); - Logger.info("Set option " + fieldName + " to " + value); + //Logger.info("Set option " + fieldName + " to " + value); } else { Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); return false;