Mercurial > hg > graal-compiler
changeset 2991:499851efab4d
merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Thu, 16 Jun 2011 10:59:27 +0200 |
parents | 66ecfc755c86 (current diff) a8e8035916a3 (diff) |
children | 3671e31615c9 47aef13c569c |
files | graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SplitCriticalEdgesPhase.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java |
diffstat | 46 files changed, 906 insertions(+), 615 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Jun 15 16:49:46 2011 +0200 +++ b/.hgignore Thu Jun 16 10:59:27 2011 +0200 @@ -17,6 +17,7 @@ \.orig$ output\.txt$ output\.cfg$ +java\.hprof\.txt$ /nbproject/private/ ^graal/hotspot/java$ ^scratch/
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Thu Jun 16 10:59:27 2011 +0200 @@ -25,8 +25,10 @@ import java.util.*; import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.lir.*; +import com.oracle.max.graal.graph.*; /** * This class optimizes moves, particularly those that result from eliminating SSA form. @@ -190,6 +192,12 @@ List<LIRInstruction> instructions = block.lir().instructionsList(); assert numSux == 2 : "method should not be called otherwise"; + + if ( instructions.get(instructions.size() - 1).code != LIROpcode.Branch) { + for (Node n : block.getInstructions()) { + TTY.println("instr: " + n); + } + } assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch block=B" + block.blockID(); assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch"; assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch";
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jun 16 10:59:27 2011 +0200 @@ -240,7 +240,7 @@ nodes.add(merge.stateBefore()); } for (Node usage : merge.usages()) { - if (usage instanceof Phi) { + if (usage instanceof Phi || usage instanceof LoopCounter) { nodes.add(usage); } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 16 10:59:27 2011 +0200 @@ -226,10 +226,16 @@ } if (block.blockPredecessors().size() > 1) { + if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + TTY.println("STATE RESET"); + } lastState = null; } for (Node instr : block.getInstructions()) { + if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + TTY.println("LIRGen for " + instr); + } FrameState stateAfter = null; if (instr instanceof Instruction) { stateAfter = ((Instruction) instr).stateAfter(); @@ -247,7 +253,7 @@ } } } - if (!(instr instanceof Merge) && instr != instr.graph().start()) { + if (instr != instr.graph().start()) { walkState(instr, stateAfter); doRoot((Value) instr); } @@ -261,9 +267,8 @@ } } } - if (block.blockSuccessors().size() >= 1 && (block.getInstructions().size() == 0 || !jumpsToNextBlock(block.getInstructions().get(block.getInstructions().size() - 1)))) { - moveToPhi(); - block.lir().jump(block.blockSuccessors().get(0)); + if (block.blockSuccessors().size() >= 1 && !jumpsToNextBlock(block.lastInstruction())) { + block.lir().jump(getLIRBlock((FixedNode) block.lastInstruction().successors().get(0))); } if (GraalOptions.TraceLIRGeneratorLevel >= 1) { @@ -275,8 +280,13 @@ blockDoEpilog(); } + @Override + public void visitMerge(Merge x) { + // Nothing to do. + } + private static boolean jumpsToNextBlock(Node node) { - return node instanceof BlockEnd || node instanceof Anchor; + return node instanceof BlockEnd || node instanceof EndNode || node instanceof LoopEnd; } @Override @@ -456,12 +466,6 @@ @Override public void visitAnchor(Anchor x) { setNoResult(x); - - // emit phi-instruction moves after safepoint since this simplifies - // describing the state at the safepoint. - - moveToPhi(); - lir.jump(getLIRBlock(x.next())); } @Override @@ -469,7 +473,9 @@ emitCompare(x.compare()); emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor())); assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination above"; - lir.jump(getLIRBlock(x.defaultSuccessor())); + LIRBlock block = getLIRBlock(x.defaultSuccessor()); + assert block != null : x; + lir.jump(block); } public void emitBranch(Compare compare, LIRBlock trueSuccessor, LIRBlock falseSucc) { @@ -698,7 +704,7 @@ } } - protected LIRBlock getLIRBlock(Instruction b) { + protected LIRBlock getLIRBlock(FixedNode b) { if (b == null) { return null; } @@ -1019,10 +1025,22 @@ emitXir(prologue, null, null, null, false); } FrameState fs = setOperandsForLocals(); + if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + TTY.println("STATE CHANGE (setOperandsForLocals)"); + if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + TTY.println(fs.toString()); + } + } lastState = fs; } else if (block.blockPredecessors().size() == 1) { FrameState fs = block.blockPredecessors().get(0).lastState(); assert fs != null; + if (GraalOptions.TraceLIRGeneratorLevel >= 2) { + TTY.println("STATE CHANGE (singlePred)"); + if (GraalOptions.TraceLIRGeneratorLevel >= 3) { + TTY.println(fs.toString()); + } + } lastState = fs; } } @@ -1191,7 +1209,7 @@ } } - protected void arithmeticOpLong(int code, CiValue result, CiValue left, CiValue right, LIRDebugInfo info) { + protected void arithmeticOpLong(int code, CiValue result, CiValue left, CiValue right) { CiValue leftOp = left; if (isTwoOperand && leftOp != result) { @@ -1411,47 +1429,62 @@ return null; } - protected void moveToPhi() { - // Moves all stack values into their phi position - LIRBlock bb = currentBlock; - if (bb.numberOfSux() == 1) { - LIRBlock sux = bb.suxAt(0); - assert sux.numberOfPreds() > 0 : "invalid CFG"; - - // a block with only one predecessor never has phi functions - if (sux.numberOfPreds() > 1) { + @Override + public void visitEndNode(EndNode end) { + setNoResult(end); + Merge merge = end.merge(); + moveToPhi(merge, merge.endIndex(end)); + lir.jump(getLIRBlock(end.merge())); + } - List<Phi> phis = getPhis(sux); - - if (phis != null) { + @Override + public void visitLoopEnd(LoopEnd x) { + setNoResult(x); + moveToPhi(x.loopBegin(), x.loopBegin().endCount()); + lir.jump(getLIRBlock(x.loopBegin())); + } - int predIndex = 0; - for (; predIndex < sux.numberOfPreds(); ++predIndex) { - if (sux.predAt(predIndex) == bb) { - break; + private void moveToPhi(Merge merge, int nextSuccIndex) { + PhiResolver resolver = new PhiResolver(this); + for (Node n : merge.usages()) { + if (n instanceof Phi) { + Phi phi = (Phi) n; + if (!phi.isDead()) { + Value curVal = phi.valueAt(nextSuccIndex); + if (curVal != null && curVal != phi) { + if (curVal instanceof Phi) { + operandForPhi((Phi) curVal); + } + CiValue operand = curVal.operand(); + if (operand.isIllegal()) { + assert curVal instanceof Constant || curVal instanceof Local : "these can be produced lazily" + curVal + "/" + phi; + operand = operandForInstruction(curVal); + } + resolver.move(operand, operandForPhi(phi)); + } + } + } + } + resolver.dispose(); + //TODO (gd) remove that later + if (merge instanceof LoopBegin) { + for (Node usage : merge.usages()) { + if (usage instanceof LoopCounter) { + LoopCounter counter = (LoopCounter) usage; + if (counter.operand().isIllegal()) { + createResultVariable(counter); + } + if (nextSuccIndex == 0) { // (gd) nasty + lir.move(operandForInstruction(counter.init()), counter.operand()); + } else { + if (counter.kind == CiKind.Int) { + this.arithmeticOpInt(IADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride()), CiValue.IllegalValue); + } else { + assert counter.kind == CiKind.Long; + this.arithmeticOpLong(LADD, counter.operand(), counter.operand(), operandForInstruction(counter.stride())); } } - assert predIndex < sux.numberOfPreds(); - - PhiResolver resolver = new PhiResolver(this); - for (Phi phi : phis) { - if (!phi.isDead()) { - Value curVal = phi.valueAt(predIndex); - if (curVal != null && curVal != phi) { - if (curVal instanceof Phi) { - operandForPhi((Phi) curVal); - } - CiValue operand = curVal.operand(); - if (operand.isIllegal()) { - assert curVal instanceof Constant || curVal instanceof Local : "these can be produced lazily" + curVal + "/" + phi; - operand = operandForInstruction(curVal); - } - resolver.move(operand, operandForPhi(phi)); - } - } - } - resolver.dispose(); } } } @@ -1473,7 +1506,7 @@ if (x instanceof Constant) { x.setOperand(x.asConstant()); } else { - assert x instanceof Phi || x instanceof Local : "only for Phi and Local"; + assert x instanceof Phi || x instanceof Local : "only for Phi and Local : " + x; // allocate a variable for this local or phi createResultVariable(x); } @@ -1485,8 +1518,7 @@ assert !phi.isDead() : "dead phi: " + phi.id(); if (phi.operand().isIllegal()) { // allocate a variable for this phi - CiVariable operand = newVariable(phi.kind); - setResult(phi, operand); + createResultVariable(phi); } return phi.operand(); }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Thu Jun 16 10:59:27 2011 +0200 @@ -69,19 +69,20 @@ */ public void build() { new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph); - printGraph("After GraphBuilding", compilation.graph); + + //printGraph("After GraphBuilding", compilation.graph); if (GraalOptions.TestGraphDuplication) { new DuplicationPhase().apply(compilation.graph); - printGraph("After Duplication", compilation.graph); + //printGraph("After Duplication", compilation.graph); } new DeadCodeEliminationPhase().apply(compilation.graph); - printGraph("After DeadCodeElimination", compilation.graph); + //printGraph("After DeadCodeElimination", compilation.graph); if (GraalOptions.Inline) { new InliningPhase(compilation, this, GraalOptions.TraceInlining).apply(compilation.graph); - printGraph("After Ininling", compilation.graph); + //printGraph("After Ininling", compilation.graph); } if (GraalOptions.Time) { @@ -96,9 +97,9 @@ printGraph("After Canonicalization", graph); } - new LoweringPhase().apply(graph); + new LoopPhase().apply(graph); - new SplitCriticalEdgesPhase().apply(graph); + new LoweringPhase().apply(graph); IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); schedule.apply(graph); @@ -135,7 +136,7 @@ valueToBlock.put(i, b); } } - startBlock = lirBlocks.get(0); + startBlock = valueToBlock.get(graph.start()); assert startBlock != null; assert startBlock.blockPredecessors().size() == 0;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BlockEnd.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BlockEnd.java Thu Jun 16 10:59:27 2011 +0200 @@ -51,14 +51,14 @@ /** * The list of instructions that produce input for this instruction. */ - public Instruction blockSuccessor(int index) { + public FixedNode blockSuccessor(int index) { assert index >= 0 && index < blockSuccessorCount; - return (Instruction) successors().get(super.successorCount() + SUCCESSOR_COUNT + index); + return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_COUNT + index); } - public Instruction setBlockSuccessor(int index, Instruction n) { + public FixedNode setBlockSuccessor(int index, FixedNode n) { assert index >= 0 && index < blockSuccessorCount; - return (Merge) successors().set(super.successorCount() + SUCCESSOR_COUNT + index, n); + return (FixedNode) successors().set(super.successorCount() + SUCCESSOR_COUNT + index, n); } public int blockSuccessorCount() { @@ -87,19 +87,6 @@ } /** - * Gets the block begin associated with this block end. - * @return the beginning of this basic block - */ - public Merge begin() { - for (Node n : predecessors()) { - if (n instanceof Merge) { - return (Merge) n; - } - } - return null; - } - - /** * Substitutes a successor block in this block end's successor list. Note that * this method updates all occurrences in the list. * @param oldSucc the old successor to replace @@ -121,7 +108,7 @@ * Gets the successor corresponding to the default (fall through) case. * @return the default successor */ - public Instruction defaultSuccessor() { + public FixedNode defaultSuccessor() { return blockSuccessor(blockSuccessorCount - 1); }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Thu Jun 16 10:59:27 2011 +0200 @@ -121,7 +121,7 @@ case AT: return BE; case AE: return BT; } - throw new IllegalArgumentException(); + throw new IllegalArgumentException(this.toString()); } /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java Thu Jun 16 10:59:27 2011 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.compiler.ir; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class EndNode extends FixedNode { + public static final int SUCCESSOR_COUNT = 0; + public static final int INPUT_COUNT = 0; + public EndNode(Graph graph) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + } + + @Override + public void accept(ValueVisitor v) { + v.visitEndNode(this); + } + + @Override + public void print(LogStream out) { + out.print("end"); + } + + @Override + public Node copy(Graph into) { + return new EndNode(into); + } + + public Merge merge() { + if (usages().size() == 0) { + return null; + } else { + assert usages().size() == 1; + return (Merge) usages().get(0); + } + } +}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java Thu Jun 16 10:59:27 2011 +0200 @@ -64,7 +64,7 @@ /** * Constructs a new ExceptionDispatch instruction. */ - public ExceptionDispatch(Value exception, Instruction catchSuccessor, Instruction otherSuccessor, RiType catchType, Graph graph) { + public ExceptionDispatch(Value exception, FixedNode catchSuccessor, FixedNode otherSuccessor, RiType catchType, Graph graph) { super(CiKind.Int, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph); setException(exception); setBlockSuccessor(0, otherSuccessor); @@ -80,7 +80,7 @@ * Gets the block corresponding to the catch block. * @return the true successor */ - public Instruction catchSuccessor() { + public FixedNode catchSuccessor() { return blockSuccessor(1); } @@ -88,7 +88,7 @@ * Gets the block corresponding to the rest of the dispatch chain. * @return the false successor */ - public Instruction otherSuccessor() { + public FixedNode otherSuccessor() { return blockSuccessor(0); } @@ -97,7 +97,7 @@ * @param istrue {@code true} if the true successor is requested, {@code false} otherwise * @return the corresponding successor */ - public Instruction successor(boolean istrue) { + public FixedNode successor(boolean istrue) { return blockSuccessor(istrue ? 1 : 0); }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java Thu Jun 16 10:59:27 2011 +0200 @@ -83,12 +83,14 @@ if (c == 0.0f) { return x; } + return new FloatAdd(kind, x, Constant.forFloat(-c, graph), sub.isStrictFP(), graph); } else { assert kind == CiKind.Double; double c = y.asConstant().asDouble(); if (c == 0.0) { return x; } + return new FloatAdd(kind, x, Constant.forDouble(-c, graph), sub.isStrictFP(), graph); } } else if (x.isConstant()) { // TODO (gd) check that Negate impl for floating point is really faster/better than 0.0 - x
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Thu Jun 16 10:59:27 2011 +0200 @@ -67,7 +67,7 @@ * Gets the block corresponding to the true successor. * @return the true successor */ - public Instruction trueSuccessor() { + public FixedNode trueSuccessor() { return blockSuccessor(0); } @@ -75,7 +75,7 @@ * Gets the block corresponding to the false successor. * @return the false successor */ - public Instruction falseSuccessor() { + public FixedNode falseSuccessor() { return blockSuccessor(1); } @@ -84,7 +84,7 @@ * @param istrue {@code true} if the true successor is requested, {@code false} otherwise * @return the corresponding successor */ - public Instruction successor(boolean istrue) { + public FixedNode successor(boolean istrue) { return blockSuccessor(istrue ? 0 : 1); } @@ -109,7 +109,7 @@ @Override public String shortName() { - return "If " + (compare() == null ? "?" : compare().condition.operator); + return "If"; } @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Instruction.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Instruction.java Thu Jun 16 10:59:27 2011 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.max.graal.compiler.ir; -import java.util.*; - import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; @@ -62,11 +60,11 @@ * Links to next instruction in a basic block, to {@code null} if this instruction is the end of a basic block or to * itself if not in a block. */ - public Instruction next() { - return (Instruction) successors().get(super.successorCount() + SUCCESSOR_NEXT); + public FixedNode next() { + return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_NEXT); } - public Node setNext(Instruction next) { + public Node setNext(FixedNode next) { return successors().set(super.successorCount() + SUCCESSOR_NEXT, next); } @@ -88,28 +86,6 @@ GraalMetrics.HIRInstructions++; } - - /** - * Gets the list of predecessors of this block. - * @return the predecessor list - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public List<Instruction> blockPredecessors() { - return (List) Collections.unmodifiableList(predecessors()); - } - - /** - * Get the number of predecessors. - * @return the number of predecessors - */ - public int numberOfPreds() { - return predecessors().size(); - } - - public Instruction predAt(int j) { - return (Instruction) predecessors().get(j); - } - /** * Gets the state after the instruction, if it is recorded. * @return the state after the instruction
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java Thu Jun 16 10:59:27 2011 +0200 @@ -82,6 +82,12 @@ if (c == 0) { return x; } + if (kind == CiKind.Int) { + return new IntegerAdd(kind, x, Constant.forInt((int) -c, graph), graph); + } else { + assert kind == CiKind.Long; + return new IntegerAdd(kind, x, Constant.forLong(-c, graph), graph); + } } else if (x.isConstant()) { long c = x.asConstant().asLong(); if (c == 0) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java Thu Jun 16 10:59:27 2011 +0200 @@ -26,7 +26,6 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.graph.*; -import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopCounter.java Thu Jun 16 10:59:27 2011 +0200 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.compiler.ir; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class LoopCounter extends FloatingNode { + + private static final int INPUT_COUNT = 3; + private static final int INPUT_MERGE = 0; + private static final int INPUT_INIT = 1; + private static final int INPUT_STRIDE = 2; + + private static final int SUCCESSOR_COUNT = 0; + + public LoopCounter(CiKind kind, Value init, Value stride, LoopBegin loop, Graph graph) { + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + setInit(init); + setStride(stride); + setLoopBegin(loop); + } + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + public Value init() { + return (Value) inputs().get(super.inputCount() + INPUT_INIT); + } + + public Value setInit(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_INIT, n); + } + + public Value stride() { + return (Value) inputs().get(super.inputCount() + INPUT_STRIDE); + } + + public Value setStride(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_STRIDE, n); + } + + public LoopBegin loopBegin() { + return (LoopBegin) inputs().get(super.inputCount() + INPUT_MERGE); + } + + public Value setLoopBegin(LoopBegin n) { + return (Value) inputs().set(super.inputCount() + INPUT_MERGE, n); + } + + @Override + public void accept(ValueVisitor v) { + // TODO Auto-generated method stub + + } + + @Override + public void print(LogStream out) { + out.print("loopcounter [").print(init()).print(",+").print(stride()).print("]"); + + } + + @Override + public Node copy(Graph into) { + return new LoopCounter(kind, null, null, null, into); + } + +}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopEnd.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopEnd.java Thu Jun 16 10:59:27 2011 +0200 @@ -78,4 +78,9 @@ LoopEnd x = new LoopEnd(into); return x; } + + @Override + public String toString() { + return "LoopEnd:" + super.toString(); + } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Thu Jun 16 10:59:27 2011 +0200 @@ -73,6 +73,23 @@ v.visitMerge(this); } + public int endIndex(EndNode end) { + assert inputs().variablePart().contains(end); + return inputs().variablePart().indexOf(end); + } + + public void addEnd(EndNode end) { + inputs().variablePart().add(end); + } + + public int endCount() { + return inputs().variablePart().size(); + } + + public EndNode endAt(int index) { + return (EndNode) inputs().variablePart().get(index); + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); @@ -96,7 +113,6 @@ } hasSucc = true; } - return builder.toString(); } @@ -263,18 +279,17 @@ @Override public Node copy(Graph into) { assert getClass() == Merge.class : "copy of " + getClass(); - Merge x = new Merge(into); - return x; + return new Merge(into); } - public void removePhiPredecessor(Node pred) { - int predIndex = predecessors().lastIndexOf(pred); + public void removeEnd(EndNode pred) { + int predIndex = inputs().variablePart().indexOf(pred); assert predIndex != -1; + inputs().variablePart().remove(predIndex); for (Node usage : usages()) { if (usage instanceof Phi) { Phi phi = (Phi) usage; -// assert phi.valueCount() == predecessors().size(); phi.removeInput(predIndex); } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Thu Jun 16 10:59:27 2011 +0200 @@ -37,16 +37,13 @@ private static final int INPUT_COUNT = 1; private static final int INPUT_MERGE = 0; - private final int maxValues; - private static final int SUCCESSOR_COUNT = 0; - private int usedInputCount; private boolean isDead; @Override protected int inputCount() { - return super.inputCount() + INPUT_COUNT + maxValues; + return super.inputCount() + INPUT_COUNT; } @Override @@ -61,24 +58,12 @@ return (Merge) inputs().get(super.inputCount() + INPUT_MERGE); } - public Value setMerge(Value n) { - return (Merge) inputs().set(super.inputCount() + INPUT_MERGE, n); + public void setMerge(Value n) { + inputs().set(super.inputCount() + INPUT_MERGE, n); } - /** - * Create a new Phi for the specified join block and local variable (or operand stack) slot. - * @param kind the type of the variable - * @param merge the join point - * @param graph - */ public Phi(CiKind kind, Merge merge, Graph graph) { - this(kind, merge, DEFAULT_MAX_VALUES, graph); - } - - public Phi(CiKind kind, Merge merge, int maxValues, Graph graph) { - super(kind, INPUT_COUNT + maxValues, SUCCESSOR_COUNT, graph); - this.maxValues = maxValues; - usedInputCount = 0; + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); setMerge(merge); } @@ -89,11 +74,11 @@ * @return the instruction that produced the value in the i'th predecessor */ public Value valueAt(int i) { - return (Value) inputs().get(INPUT_COUNT + i); + return (Value) inputs().variablePart().get(i); } - public Node setValueAt(int i, Node x) { - return inputs().set(INPUT_COUNT + i, x); + public void setValueAt(int i, Value x) { + inputs().set(INPUT_COUNT + i, x); } /** @@ -101,7 +86,7 @@ * @return the number of inputs in this phi */ public int valueCount() { - return usedInputCount; + return inputs().variablePart().size(); } @Override @@ -144,36 +129,17 @@ return "Phi: (" + str + ")"; } - public Phi addInput(Node y) { - assert !this.isDeleted() && !y.isDeleted(); - Phi phi = this; - if (usedInputCount == maxValues) { - phi = new Phi(kind, merge(), maxValues * 2, graph()); - for (int i = 0; i < valueCount(); ++i) { - phi.addInput(valueAt(i)); - } - phi.addInput(y); - this.replace(phi); - } else { - setValueAt(usedInputCount++, y); - } - return phi; + public void addInput(Node y) { + inputs().variablePart().add(y); } public void removeInput(int index) { - assert index < valueCount() : "index: " + index + ", valueCount: " + valueCount() + "@phi " + id(); - setValueAt(index, Node.Null); - for (int i = index + 1; i < valueCount(); ++i) { - setValueAt(i - 1, valueAt(i)); - } - setValueAt(valueCount() - 1, Node.Null); - usedInputCount--; + inputs().variablePart().remove(index); } @Override public Node copy(Graph into) { - Phi x = new Phi(kind, null, maxValues, into); - x.usedInputCount = usedInputCount; + Phi x = new Phi(kind, null, into); x.isDead = isDead; return x; }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Thu Jun 16 10:59:27 2011 +0200 @@ -134,19 +134,6 @@ return null; // default: unknown declared type } - /** - * Apply the specified closure to all the input values of this instruction. - * @param closure the closure to apply - */ - public void inputValuesDo(ValueClosure closure) { - for (int i = 0; i < inputs().size(); i++) { - inputs().set(i, closure.apply((Value) inputs().get(i))); - } - for (int i = 0; i < successors().size(); i++) { - successors().set(i, closure.apply((Value) successors().get(i))); - } - } - @Override public String toString() { StringBuilder builder = new StringBuilder();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Thu Jun 16 10:59:27 2011 +0200 @@ -39,6 +39,7 @@ public abstract void visitConstant(Constant i); public abstract void visitConvert(Convert i); public abstract void visitExceptionObject(ExceptionObject i); + public abstract void visitEndNode(EndNode i); public abstract void visitFrameState(FrameState i); public abstract void visitAnchor(Anchor i); public abstract void visitIf(If i);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.graph.*; @@ -44,22 +45,9 @@ // remove chained Merges for (Merge merge : graph.getNodes(Merge.class)) { - if (merge.predecessors().size() == 1 && merge.usages().size() == 0) { - if (merge.successors().get(0) instanceof Merge) { - Node pred = merge.predecessors().get(0); - int predIndex = merge.predecessorsIndex().get(0); - pred.successors().setAndClear(predIndex, merge, 0); - merge.delete(); - } - } - } - Node startSuccessor = graph.start().successors().get(0); - if (startSuccessor instanceof Merge) { - Merge startMerge = (Merge) startSuccessor; - if (startMerge.predecessors().size() == 1 && startMerge.usages().size() == 0) { - int predIndex = startMerge.predecessorsIndex().get(0); - graph.start().successors().setAndClear(predIndex, startMerge, 0); - startMerge.delete(); + if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopEnd) && !(merge instanceof LoopBegin)) { + merge.endAt(0).replace(merge.next()); + merge.delete(); } } @@ -67,20 +55,15 @@ iterateSuccessors(); disconnectCFGNodes(); - deleteBrokenLoops(); - iterateInputs(); disconnectNonCFGNodes(); - - deleteCFGNodes(); - deleteNonCFGNodes(); + deleteNodes(); new PhiSimplifier(graph); - if (GraalOptions.TraceDeadCodeElimination) { - System.out.printf("dead code elimination finished\n"); + TTY.println("dead code elimination finished"); } } @@ -90,30 +73,31 @@ private void iterateSuccessors() { for (Node current : flood) { - for (Node successor : current.successors()) { - flood.add(successor); + if (current instanceof EndNode) { + EndNode end = (EndNode) current; + flood.add(end.merge()); + } else { + for (Node successor : current.successors()) { + flood.add(successor); + } } } } private void disconnectCFGNodes() { for (Node node : graph.getNodes()) { - if (node != Node.Null && !flood.isMarked(node) && isCFG(node)) { - if (node instanceof LoopEnd) { - assert ((LoopEnd) node).loopBegin() != null : "node " + node; - brokenLoops.add(((LoopEnd) node).loopBegin()); - } - // iterate backwards so that the predecessor indexes in removePhiPredecessor are correct - for (int i = node.successors().size() - 1; i >= 0; i--) { - Node successor = node.successors().get(i); - if (successor != Node.Null && flood.isMarked(successor)) { - if (successor instanceof Merge) { - ((Merge) successor).removePhiPredecessor(node); - } + if (node != Node.Null && !flood.isMarked(node)) { + if (isCFG(node)) { + node.successors().clearAll(); + node.inputs().clearAll(); + } else if (node instanceof EndNode) { + EndNode end = (EndNode) node; + Merge merge = end.merge(); + if (merge != null && flood.isMarked(merge)) { + // We are a dead end node leading to a live merge. + merge.removeEnd(end); } } - node.successors().clearAll(); - node.inputs().clearAll(); } } } @@ -126,16 +110,13 @@ usage.replace(((Phi) usage).valueAt(0)); } - Node pred = loop.predecessors().get(0); - int predIndex = loop.predecessorsIndex().get(0); - pred.successors().setAndClear(predIndex, loop, 0); - loop.delete(); + loop.replace(loop.next()); } } - private void deleteCFGNodes() { + private void deleteNodes() { for (Node node : graph.getNodes()) { - if (node != Node.Null && !flood.isMarked(node) && isCFG(node)) { + if (node != Node.Null && !flood.isMarked(node)) { node.delete(); } } @@ -170,12 +151,4 @@ } } } - - private void deleteNonCFGNodes() { - for (Node node : graph.getNodes()) { - if (node != Node.Null && !flood.isMarked(node) && !isCFG(node)) { - node.delete(); - } - } - } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -162,7 +162,7 @@ // 1. create the start block Block startBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); markOnWorkList(startBlock); - lastInstr = createTarget(startBlock, frameState); + lastInstr = (Instruction) createTarget(startBlock, frameState); graph.start().setStart(lastInstr); if (isSynchronized(method.accessFlags())) { @@ -193,11 +193,7 @@ for (Node n : graph.getNodes()) { if (n instanceof Placeholder) { Placeholder p = (Placeholder) n; - 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(); + p.replace(p.next()); } } @@ -264,8 +260,7 @@ private void finishStartBlock(Block startBlock) { assert bci() == 0; - Instruction target = createTargetAt(0, frameState); - appendGoto(target); + appendGoto(createTargetAt(0, frameState)); } public void mergeOrClone(Block target, FrameStateAccess newState) { @@ -305,9 +300,16 @@ assert !target.isLoopHeader; Merge merge = new Merge(graph); + + Placeholder p = (Placeholder) first; + assert p.predecessors().size() == 1; assert p.next() == null; - p.replace(merge); + + EndNode end = new EndNode(graph); + p.replace(end); + merge.addEnd(end); + //end.setNext(merge); target.firstInstruction = merge; merge.setStateBefore(existingState); first = merge; @@ -423,8 +425,7 @@ } FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject); - Instruction successor = createTarget(dispatchBlock, stateWithException); - currentNext.setNext(successor); + currentNext.setNext(createTarget(dispatchBlock, stateWithException)); return entry; } return null; @@ -657,14 +658,14 @@ If ifNode = new If(new Compare(x, cond, y, graph), graph); append(ifNode); BlockMap.BranchOverride override = branchOverride.get(bci()); - Instruction tsucc; + FixedNode tsucc; if (override == null || override.taken == false) { tsucc = createTargetAt(stream().readBranchDest(), frameState); } else { tsucc = createTarget(override.block, frameState); } ifNode.setBlockSuccessor(0, tsucc); - Instruction fsucc; + FixedNode fsucc; if (override == null || override.taken == true) { fsucc = createTargetAt(stream().nextBCI(), frameState); } else { @@ -1110,11 +1111,11 @@ return x; } - private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) { + private FixedNode createTargetAt(int bci, FrameStateAccess stateAfter) { return createTarget(blockFromBci[bci], stateAfter); } - private Instruction createTarget(Block block, FrameStateAccess stateAfter) { + private FixedNode 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. startBci=" + block.startBci + ", " + block.getClass().getSimpleName() + ", " + block.firstInstruction.next(); @@ -1125,8 +1126,6 @@ if (block.firstInstruction == null) { if (block.isLoopHeader) { -// block.firstInstruction = new Merge(block.startBci, graph); - LoopBegin loopBegin = new LoopBegin(graph); LoopEnd loopEnd = new LoopEnd(graph); loopEnd.setLoopBegin(loopBegin); @@ -1138,11 +1137,22 @@ mergeOrClone(block, stateAfter); addToWorkList(block); + FixedNode result = null; if (block.firstInstruction instanceof LoopBegin && isVisited(block)) { - return ((LoopBegin) block.firstInstruction).loopEnd(); + result = ((LoopBegin) block.firstInstruction).loopEnd(); } else { - return block.firstInstruction; + result = block.firstInstruction; } + + assert result instanceof Merge || result instanceof Placeholder : result; + + if (result instanceof Merge) { + EndNode end = new EndNode(graph); + //end.setNext(result); + ((Merge) result).addEnd(end); + result = end; + } + return result; } private Value synchronizedObject(FrameStateAccess state, RiMethod target) { @@ -1201,7 +1211,8 @@ } else { end.delete(); Merge merge = new Merge(graph); - merge.successors().setAndClear(merge.nextIndex(), begin, begin.nextIndex()); + merge.setNext(begin.next()); + begin.setNext(null); begin.replace(merge); } } @@ -1245,20 +1256,20 @@ Block nextBlock = block.next == null ? unwindBlock() : block.next; if (block.handler.catchType().isResolved()) { - Instruction catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState); - Instruction nextDispatch = createTarget(nextBlock, frameState); + FixedNode catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState); + FixedNode nextDispatch = createTarget(nextBlock, frameState); append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph)); } else { Deoptimize deopt = new Deoptimize(DeoptAction.InvalidateRecompile, graph); deopt.setMessage("unresolved " + block.handler.catchType().name()); append(deopt); - Instruction nextDispatch = createTarget(nextBlock, frameState); + FixedNode nextDispatch = createTarget(nextBlock, frameState); appendGoto(nextDispatch); } } } - private void appendGoto(Instruction target) { + private void appendGoto(FixedNode target) { lastInstr.setNext(target); }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -262,6 +262,7 @@ System.out.println("inlining " + name + ": " + frameStates.size() + " frame states, " + nodes.size() + " nodes"); } + assert invoke.successors().get(0) != null : invoke; assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size(); Instruction pred; if (withReceiver) { @@ -269,7 +270,7 @@ clipNode.setNode(new IsNonNull(parameters[0], compilation.graph)); pred = clipNode; } else { - pred = new Merge(compilation.graph); + pred = new Placeholder(compilation.graph);//(Instruction) invoke.predecessors().get(0);//new Merge(compilation.graph); } invoke.predecessors().get(0).successors().replace(invoke, pred); replacements.put(startNode, pred); @@ -293,6 +294,10 @@ } } + if (pred instanceof Placeholder) { + pred.replace(((Placeholder)pred).next()); + } + if (returnNode != null) { List<Node> usages = new ArrayList<Node>(invoke.usages()); for (Node usage : usages) { @@ -304,18 +309,8 @@ } Node returnDuplicate = duplicates.get(returnNode); returnDuplicate.inputs().clearAll(); - - Merge mergeAfter = new Merge(compilation.graph); - - assert returnDuplicate.predecessors().size() == 1; - Node returnPred = returnDuplicate.predecessors().get(0); - int index = returnDuplicate.predecessorsIndex().get(0); - mergeAfter.successors().setAndClear(0, invoke, 0); - returnPred.successors().set(index, mergeAfter); - - returnDuplicate.delete(); - - mergeAfter.setStateBefore(stateAfter); + returnDuplicate.replace(invoke.next()); + invoke.setNext(null); } if (exceptionEdge != null) { @@ -330,14 +325,7 @@ usage.inputs().replace(obj, unwindDuplicate.exception()); } unwindDuplicate.inputs().clearAll(); - - assert unwindDuplicate.predecessors().size() == 1; - Node unwindPred = unwindDuplicate.predecessors().get(0); - int index = unwindDuplicate.predecessorsIndex().get(0); - unwindPred.successors().setAndClear(index, obj, 0); - - obj.inputs().clearAll(); - unwindDuplicate.delete(); + unwindDuplicate.replace(obj.next()); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2011, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.graal.compiler.phases; + +import java.util.*; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.value.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public class LoopPhase extends Phase { + + @Override + protected void run(Graph graph) { + List<Node> nodes = new ArrayList<Node>(graph.getNodes()); + for (Node n : nodes) { + if (n instanceof LoopBegin) { + doLoop((LoopBegin) n); + } + } + } + + private void doLoop(LoopBegin loopBegin) { + NodeBitMap loopNodes = computeLoopNodes(loopBegin); + List<LoopCounter> counters = findLoopCounters(loopBegin, loopNodes); + mergeLoopCounters(counters, loopBegin); + } + + private void mergeLoopCounters(List<LoopCounter> counters, LoopBegin loopBegin) { + Graph graph = loopBegin.graph(); + LoopCounter[] acounters = counters.toArray(new LoopCounter[counters.size()]); + for (int i = 0; i < acounters.length; i++) { + LoopCounter c1 = acounters[i]; + if (c1 == null) { + continue; + } + for (int j = i + 1; j < acounters.length; j++) { + LoopCounter c2 = acounters[j]; + if (c2 != null && c1.stride().valueEqual(c2.stride())) { + acounters[j] = null; + CiKind kind = c1.kind; + IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph); + IntegerAdd addStride = new IntegerAdd(kind, sub, c1.stride(), graph); + IntegerAdd add = new IntegerAdd(kind, c1, addStride, graph); + Phi phi = new Phi(kind, loopBegin, graph); // TODO (gd) assumes order on loopBegin preds + phi.addInput(c2.init()); + phi.addInput(add); + c2.replace(phi); + //System.out.println("--> merged Loop Counters"); + } + } + } + } + + private List<LoopCounter> findLoopCounters(LoopBegin loopBegin, NodeBitMap loopNodes) { + LoopEnd loopEnd = loopBegin.loopEnd(); + List<Node> usages = new ArrayList<Node>(loopBegin.usages()); + List<LoopCounter> counters = new LinkedList<LoopCounter>(); + for (Node usage : usages) { + if (usage instanceof Phi) { + Phi phi = (Phi) usage; + if (phi.valueCount() == 2) { + Value backEdge = phi.valueAt(1); + Value init = phi.valueAt(0); + if (loopNodes.isMarked(init)) { + // try to reverse init/backEdge order + Value tmp = backEdge; + backEdge = init; + init = tmp; + } + Value stride = null; + boolean useCounterAfterAdd = false; + if (!loopNodes.isMarked(init) && backEdge instanceof IntegerAdd && loopNodes.isMarked(backEdge)) { + IntegerAdd add = (IntegerAdd) backEdge; + int addUsageCount = 0; + for (Node u : add.usages()) { + if (u != loopEnd.stateBefore() && u != phi) { + addUsageCount++; + } + } + if (add.x() == phi) { + stride = add.y(); + } else if (add.y() == phi) { + stride = add.x(); + } + if (addUsageCount > 0) { + useCounterAfterAdd = true; + } + } + if (stride != null && !loopNodes.isMarked(stride)) { + Graph graph = loopBegin.graph(); + LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph); + counters.add(counter); + phi.replace(counter); + loopEnd.stateBefore().inputs().replace(backEdge, counter); + if (useCounterAfterAdd) { + /*IntegerAdd otherInit = new IntegerAdd(init.kind, init, stride, graph); // would be nice to canonicalize + LoopCounter otherCounter = new LoopCounter(init.kind, otherInit, stride, loopBegin, graph); + backEdge.replace(otherCounter);*/ + } else { + backEdge.delete(); + } + } + } + } + } + return counters; + } + + private NodeBitMap computeLoopNodes(LoopBegin loopBegin) { + LoopEnd loopEnd = loopBegin.loopEnd(); + NodeBitMap loopNodes = loopBegin.graph().createNodeBitMap(); + NodeFlood workCFG = loopBegin.graph().createNodeFlood(); + NodeFlood workData = loopBegin.graph().createNodeFlood(); + workCFG.add(loopEnd); + for (Node n : workCFG) { + workData.add(n); + loopNodes.mark(n); + if (n == loopBegin) { + continue; + } + for (Node pred : n.predecessors()) { + workCFG.add(pred); + } + if (n instanceof Merge) { + Merge merge = (Merge) n; + for (int i = 0; i < merge.endCount(); i++) { + workCFG.add(merge.endAt(i)); + } + } + } + for (Node n : workData) { + loopNodes.mark(n); + for (Node usage : n.usages()) { + if (usage instanceof FrameState) { + continue; + } + workData.add(usage); + } + } + return loopNodes; + } +}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.schedule.*; +import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; public class LoweringPhase extends Phase { @@ -33,21 +34,22 @@ s.apply(graph); for (Block b : s.getBlocks()) { - final Node firstNode = b.firstNode(); + //final Node firstNode = b.firstNode(); final LoweringTool loweringTool = new LoweringTool() { @Override public Node createStructuredBlockAnchor() { - if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) { - Anchor a = new Anchor(graph); - assert firstNode.predecessors().size() == 1; - Node pred = firstNode.predecessors().get(0); - int predIndex = firstNode.predecessorsIndex().get(0); - a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, pred, predIndex); - pred.successors().set(predIndex, a); - return a; - } - return firstNode; + throw Util.unimplemented(); +// if (!(firstNode instanceof Anchor) && !(firstNode instanceof Merge)) { +// Anchor a = new Anchor(graph); +// assert firstNode.predecessors().size() == 1; +// Node pred = firstNode.predecessors().get(0); +// int predIndex = firstNode.predecessorsIndex().get(0); +// a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, pred, predIndex); +// pred.successors().set(predIndex, a); +// return a; +// } +// return firstNode; } };
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Thu Jun 16 10:59:27 2011 +0200 @@ -23,6 +23,8 @@ package com.oracle.max.graal.compiler.phases; import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.observer.*; +import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.graph.Graph; public abstract class Phase { @@ -67,6 +69,10 @@ GraalMetrics.get(getName().concat(".deletedNodes")).increment(deletedNodeCount); GraalMetrics.get(getName().concat(".createdNodes")).increment(createdNodeCount); } + GraalCompilation compilation = GraalCompilation.compilation(); + if (compilation.compiler.isObserved() && this.getClass() != IdentifyBlocksPhase.class) { + compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getName(), graph, true, false)); + } // (Item|Graph|Phase|Value) }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/SplitCriticalEdgesPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.max.graal.compiler.phases; - -import java.util.*; - -import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; - - -public class SplitCriticalEdgesPhase extends Phase { - - @Override - protected void run(Graph graph) { - List<Node> nodes = graph.getNodes(); - for (int i = 0; i < nodes.size(); ++i) { - Node n = nodes.get(i); - if (IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { - for (int j = 0; j < n.successors().size(); ++j) { - Node succ = n.successors().get(j); - if (IdentifyBlocksPhase.truePredecessorCount(succ) > 1) { - Anchor a = new Anchor(graph); - a.successors().setAndClear(Instruction.SUCCESSOR_NEXT, n, j); - n.successors().set(j, a); - } - } - } - } - } -}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jun 16 10:59:27 2011 +0200 @@ -78,6 +78,13 @@ private Block assignBlock(Node n, Block b) { assert nodeToBlock.get(n) == null; nodeToBlock.set(n, b); + for (Node input : n.inputs()) { + if (input instanceof FrameState) { + assert nodeToBlock.get(n) == null; + nodeToBlock.set(n, b); + } + } + if (b.firstNode() == null) { b.setFirstNode(n); b.setLastNode(n); @@ -91,6 +98,26 @@ return b; } + private Block assignBlockNew(Node n, Block b) { + if (b == null) { + b = createBlock(); + } + + assert nodeToBlock.get(n) == null; + nodeToBlock.set(n, b); + if (b.lastNode() == null) { + b.setFirstNode(n); + b.setLastNode(n); + } else { + if (b.firstNode() != b.lastNode()) { + b.getInstructions().add(0, b.firstNode()); + } + b.setFirstNode(n); + } + + return b; + } + public static boolean isFixed(Node n) { return n != null && ((n instanceof FixedNode) || n == n.graph().start()); } @@ -100,67 +127,49 @@ } private void identifyBlocks() { + // Identify blocks. - final ArrayList<Node> blockBeginNodes = new ArrayList<Node>(); - NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() { - @Override - public boolean visit(Node n) { - if (!isFixed(n)) { - return false; - } - - if (n instanceof LoopBegin) { - // a LoopBegin is always a merge - assignBlock(n); - blockBeginNodes.add(n); - return true; - } - - Node singlePred = null; - for (Node pred : n.predecessors()) { - if (isFixed(pred)) { - if (singlePred == null) { - singlePred = pred; - } else { - // We have more than one predecessor => we are a merge block. - assignBlock(n); - blockBeginNodes.add(n); - return true; + for (Node n : graph.getNodes()) { + if (n != null) { + if (n instanceof EndNode || n instanceof Return || n instanceof Unwind || n instanceof LoopEnd || n instanceof Deoptimize) { + Block block = null; + while (nodeToBlock.get(n) == null) { + if (block != null && IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { + // We are at a split node => start a new block. + block = null; } + block = assignBlockNew(n, block); + if (n.predecessors().size() == 0) { + // Either dead code or at a merge node => stop iteration. + break; + } + assert n.predecessors().size() == 1 : "preds: " + n; + n = n.predecessors().get(0); } } + } + } - if (singlePred == null) { - // We have no predecessor => we are the start block. - assignBlock(n); - blockBeginNodes.add(n); - } else { - // We have a single predecessor => check its successor count. - if (isBlockEnd(singlePred)) { - assignBlock(n); - blockBeginNodes.add(n); - } else { - assignBlock(n, nodeToBlock.get(singlePred)); + // Connect blocks. + for (Block block : blocks) { + Node n = block.firstNode(); + if (n instanceof Merge) { + for (Node usage : n.usages()) { + if (usage instanceof Phi || usage instanceof LoopCounter) { + nodeToBlock.set(usage, block); } } - return true; - }} - ); - - // Connect blocks. - for (Node n : blockBeginNodes) { - Block block = nodeToBlock.get(n); - for (Node pred : n.predecessors()) { - if (isFixed(pred)) { - Block predBlock = nodeToBlock.get(pred); + Merge m = (Merge) n; + for (int i = 0; i < m.endCount(); ++i) { + EndNode end = m.endAt(i); + Block predBlock = nodeToBlock.get(end); predBlock.addSuccessor(block); } - } - - if (n instanceof Merge) { - for (Node usage : n.usages()) { - if (usage instanceof Phi) { - nodeToBlock.set(usage, block); + } else { + for (Node pred : n.predecessors()) { + if (isFixed(pred)) { + Block predBlock = nodeToBlock.get(pred); + predBlock.addSuccessor(block); } } } @@ -186,10 +195,11 @@ if (scheduleAllNodes) { // Add successors of loop end nodes. Makes the graph cyclic. - for (Node n : blockBeginNodes) { - Block block = nodeToBlock.get(n); + for (Block block : blocks) { + Node n = block.firstNode(); if (n instanceof LoopBegin) { LoopBegin loopBegin = (LoopBegin) n; + assert loopBegin.loopEnd() != null; nodeToBlock.get(loopBegin.loopEnd()).addSuccessor(block); } } @@ -295,10 +305,16 @@ } } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { Merge merge = ((FrameState) usage).block(); - for (Node pred : merge.predecessors()) { - if (isFixed(pred)) { - block = getCommonDominator(block, nodeToBlock.get(pred)); - } + for (int i = 0; i < merge.endCount(); ++i) { + EndNode pred = merge.endAt(i); + block = getCommonDominator(block, nodeToBlock.get(pred)); + } + } else if (usage instanceof LoopCounter) { + LoopCounter counter = (LoopCounter) usage; + if (n == counter.init()) { + LoopBegin loopBegin = counter.loopBegin(); + Block mergeBlock = nodeToBlock.get(loopBegin); + block = getCommonDominator(block, mergeBlock.dominator()); } } else { block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); @@ -335,10 +351,12 @@ assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; boolean scheduleFirst = true; + assert !instructions.contains(b.lastNode()); + assert !instructions.contains(b.firstNode()); if (b.firstNode() == b.lastNode()) { Node node = b.firstNode(); - if (!(node instanceof Merge)) { + if (!(node instanceof Merge) || node instanceof LoopEnd) { scheduleFirst = false; } } @@ -349,16 +367,22 @@ addToSorting(b, i, sortedInstructions, map); } addToSorting(b, b.lastNode(), sortedInstructions, map); + assert sortedInstructions.get(sortedInstructions.size() - 1) == b.lastNode() : "lastNode=" + b.lastNode() + ", firstNode=" + b.firstNode() + ", sorted(sz-1)=" + sortedInstructions.get(sortedInstructions.size() - 1); b.setInstructions(sortedInstructions); } private void addToSorting(Block b, Node i, List<Node> sortedInstructions, NodeBitMap map) { - if (i == null || map.isMarked(i) || nodeToBlock.get(i) != b || i instanceof Phi || i instanceof Local) { + if (i == null || map.isMarked(i) || nodeToBlock.get(i) != b || i instanceof Phi || i instanceof Local || i instanceof LoopCounter) { return; } + FrameState state = null; for (Node input : i.inputs()) { - addToSorting(b, input, sortedInstructions, map); +// if (input instanceof FrameState) { +// state = (FrameState) input; +// } else { + addToSorting(b, input, sortedInstructions, map); +// } } for (Node pred : i.predecessors()) { @@ -367,6 +391,10 @@ map.mark(i); + if (state != null) { + addToSorting(b, state, sortedInstructions, map); + } + for (Node succ : i.successors()) { if (succ instanceof FrameState) { addToSorting(b, succ, sortedInstructions, map); @@ -458,21 +486,4 @@ } return i; } - - public static int truePredecessorCount(Node n) { - if (n == null) { - return 0; - } - int i = 0; - for (Node s : n.predecessors()) { - if (isFixed(s)) { - i++; - } - } - - if (n instanceof LoopBegin) { - i++; - } - return i; - } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Jun 16 10:59:27 2011 +0200 @@ -214,7 +214,7 @@ CiValue left = load(x.x()); right.loadItem(); - arithmeticOpLong(opcode, LMUL_OUT, left, right.result(), null); + arithmeticOpLong(opcode, LMUL_OUT, left, right.result()); CiValue result = createResultVariable(x); lir.move(LMUL_OUT, result); } else { @@ -224,7 +224,7 @@ // don't load constants to save register right.loadNonconstant(); createResultVariable(x); - arithmeticOpLong(opcode, x.operand(), left, right.result(), null); + arithmeticOpLong(opcode, x.operand(), left, right.result()); } } @@ -344,7 +344,7 @@ right.loadItem(); CiValue reg = LMUL_OUT; - arithmeticOpLong(opcode, reg, left, right.result(), null); + arithmeticOpLong(opcode, reg, left, right.result()); CiValue result = createResultVariable(x); lir.move(reg, result); } else { @@ -354,7 +354,7 @@ // don't load constants to save register right.loadNonconstant(); createResultVariable(x); - arithmeticOpLong(opcode, x.operand(), left, right.result(), null); + arithmeticOpLong(opcode, x.operand(), left, right.result()); } } @@ -466,11 +466,6 @@ } @Override - public void visitMerge(Merge x) { - // nothing to do for now - } - - @Override public void visitExceptionDispatch(ExceptionDispatch x) { // TODO ls: this needs some more work... @@ -494,17 +489,6 @@ } @Override - public void visitLoopEnd(LoopEnd x) { - setNoResult(x); - - // emit phi-instruction moves after safepoint since this simplifies - // describing the state at the safepoint. - - moveToPhi(); - lir.jump(getLIRBlock(x.loopBegin())); - } - - @Override public void visitValueAnchor(ValueAnchor valueAnchor) { // nothing to do for ValueAnchors }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jun 16 10:59:27 2011 +0200 @@ -377,28 +377,20 @@ phi = setupPhiForStack(block, i - localsSize); } - Phi originalPhi = phi; if (phi.valueCount() == 0) { - int size = block.predecessors().size(); + int size = block.endCount(); for (int j = 0; j < size; ++j) { - phi = phi.addInput(x); + phi.addInput(x); } - phi = phi.addInput((x == y) ? phi : y); + phi.addInput((x == y) ? phi : y); } else { - phi = phi.addInput((x == y) ? phi : y); - } - if (originalPhi != phi) { - for (int j = 0; j < other.localsSize() + other.stackSize(); ++j) { - if (other.valueAt(j) == originalPhi) { - other.setValueAt(j, phi); - } - } + phi.addInput((x == y) ? phi : y); } if (block instanceof LoopBegin) { // assert phi.valueCount() == ((LoopBegin) block).loopEnd().predecessors().size() + 1 : "loop, valueCount=" + phi.valueCount() + " predSize= " + ((LoopBegin) block).loopEnd().predecessors().size(); } else { - assert phi.valueCount() == block.predecessors().size() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.predecessors().size(); + assert phi.valueCount() == block.endCount() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.endCount(); } } }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java Thu Jun 16 10:59:27 2011 +0200 @@ -171,7 +171,7 @@ if (target == null) { target = newNodes.get(input); } - node.inputs().set(i, target); + node.inputs().setOrExpand(i, target); } } for (Entry<Node, Node> entry : replacements.entrySet()) { @@ -180,32 +180,31 @@ for (int i = 0; i < oldNode.inputs().size(); i++) { Node input = oldNode.inputs().get(i); if (newNodes.containsKey(input)) { - node.inputs().set(i, newNodes.get(input)); + node.inputs().setOrExpand(i, newNodes.get(input)); } } } + // re-wire successors for (Entry<Node, Node> entry : newNodes.entrySet()) { Node oldNode = entry.getKey(); Node node = entry.getValue(); - for (int i = 0; i < oldNode.predecessors().size(); i++) { - Node pred = oldNode.predecessors().get(i); - int predIndex = oldNode.predecessorsIndex().get(i); - Node source = replacements.get(pred); - if (source == null) { - source = newNodes.get(pred); + for (int i = 0; i < oldNode.successors().size(); i++) { + Node succ = oldNode.successors().get(i); + Node target = replacements.get(succ); + if (target == null) { + target = newNodes.get(succ); } - source.successors().set(predIndex, node); + node.successors().setOrExpand(i, target); } } for (Entry<Node, Node> entry : replacements.entrySet()) { Node oldNode = entry.getKey(); Node node = entry.getValue(); - for (int i = 0; i < oldNode.predecessors().size(); i++) { - Node pred = oldNode.predecessors().get(i); - int predIndex = oldNode.predecessorsIndex().get(i); - if (newNodes.containsKey(pred)) { - newNodes.get(pred).successors().set(predIndex, node); + for (int i = 0; i < oldNode.successors().size(); i++) { + Node succ = oldNode.successors().get(i); + if (newNodes.containsKey(succ)) { + node.successors().setOrExpand(i, newNodes.get(succ)); } } }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Thu Jun 16 10:59:27 2011 +0200 @@ -39,7 +39,6 @@ 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 : "cannot create a node for a null graph"; @@ -47,19 +46,14 @@ this.id = graph.register(this); this.inputs = new NodeArray(this, inputCount); this.successors = new NodeArray(this, successorCount); - this.predecessors = new ArrayList<Node>(); - this.usages = new ArrayList<Node>(); - this.predecessorsIndex = new ArrayList<Integer>(); + this.predecessors = new ArrayList<Node>(1); + this.usages = new ArrayList<Node>(4); } public List<Node> predecessors() { return Collections.unmodifiableList(predecessors); } - public List<Integer> predecessorsIndex() { - return Collections.unmodifiableList(predecessorsIndex); - } - public List<Node> usages() { return Collections.unmodifiableList(usages); } @@ -96,18 +90,19 @@ } int z = 0; for (Node predecessor : predecessors) { - int predIndex = predecessorsIndex.get(z); - predecessor.successors.nodes[predIndex] = other; + for (int i=0; i<predecessor.successors.size(); i++) { + if (predecessor.successors.get(i) == this) { + predecessor.successors.silentSet(i, 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; } @@ -125,14 +120,12 @@ } usages.clear(); predecessors.clear(); - predecessorsIndex.clear(); - delete(); } public void delete() { assert !isDeleted(); - assert checkDeletion(); - assert predecessorsIndex.size() == 0; + assert checkDeletion() : "Could not delete " + this; + for (int i = 0; i < inputs.size(); ++i) { inputs.set(i, Null); }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java Thu Jun 16 10:59:27 2011 +0200 @@ -29,11 +29,14 @@ public class NodeArray extends AbstractList<Node> { private final Node node; - final Node[] nodes; + private Node[] nodes; + private final int fixedLength; + private int variableLength; public NodeArray(Node node, int length) { this.node = node; this.nodes = new Node[length]; + this.fixedLength = length; } @Override @@ -50,14 +53,84 @@ nodes[index] = node; return result; } + + public AbstractList<Node> variablePart() { + return new AbstractList<Node>() { + + @Override + public Node get(int index) { + checkIndex(index); + return NodeArray.this.get(fixedLength + index); + } + + @Override + public int size() { + return variableLength; + } + + public Node set(int index, Node element) { + checkIndex(index); + return NodeArray.this.set(fixedLength + index, element); + } + + public void add(int index, Node element) { + variableLength++; + checkIndex(index); + NodeArray.this.ensureSize(); + for (int i=size() - 1; i > index; i--) { + NodeArray.this.nodes[fixedLength + i] = NodeArray.this.nodes[fixedLength + i-1]; + } + set(index, element); + } + + private void checkIndex(int index) { + if (index < 0 || index >= size()) { + throw new IndexOutOfBoundsException(); + } + } + + @Override + public Node remove(int index) { + checkIndex(index); + Node n = get(index); + set(index, Node.Null); + for (int i=index; i < size() - 1; i++) { + NodeArray.this.nodes[fixedLength + i] = NodeArray.this.nodes[fixedLength + i + 1]; + } + NodeArray.this.nodes[fixedLength + size() - 1] = Node.Null; + variableLength--; + assert variableLength >= 0; + return n; + } + }; + } + + private void ensureSize() { + if (size() > nodes.length) { + nodes = Arrays.copyOf(nodes, (nodes.length + 1)*2); + } + } + + public void setOrExpand(int index, Node node) { + if (index < 0) { + throw new IndexOutOfBoundsException(); + } + + while (index >= size()) { + variablePart().add(Node.Null); + } + + set(index, node); + } @Override public Node set(int index, Node node) { assert !self().isDeleted() : "trying to set input/successor of deleted node: " + self().shortName(); assert node == Node.Null || node.graph == self().graph : "node is from different graph: (this=" + self() + ") and (node=" + node + ")"; assert node == Node.Null || node.id() != Node.DeletedID : "inserted node must not be deleted"; - Node old = nodes[index]; - + assert node != self() || node.getClass().toString().contains("Phi") : "No direct circles allowed in the graph! " + node; + + Node old = get(index); if (old != node) { silentSet(index, node); if (self().inputs == this) { @@ -72,15 +145,14 @@ if (old != null) { for (int i = 0; i < old.predecessors.size(); ++i) { Node cur = old.predecessors.get(i); - if (cur == self() && old.predecessorsIndex.get(i) == index) { + if (cur == self()) { old.predecessors.remove(i); - old.predecessorsIndex.remove(i); + break; } } } if (node != null) { node.predecessors.add(self()); - node.predecessorsIndex.add(index); } } } @@ -94,19 +166,26 @@ set(i, other.get(i)); } } + + private void checkIndex(int index) { + if (index < 0 || index >= size()) { + throw new IndexOutOfBoundsException(); + } + } @Override public Node get(int index) { + checkIndex(index); return nodes[index]; } @Override public Node[] toArray() { - return Arrays.copyOf(nodes, nodes.length); + return Arrays.copyOf(nodes, size()); } boolean replaceFirstOccurrence(Node toReplace, Node replacement) { - for (int i = 0; i < nodes.length; i++) { + for (int i = 0; i < size(); i++) { if (nodes[i] == toReplace) { nodes[i] = replacement; return true; @@ -121,7 +200,7 @@ public int replace(Node toReplace, Node replacement) { int result = 0; - for (int i = 0; i < nodes.length; i++) { + for (int i = 0; i < size(); i++) { if (nodes[i] == toReplace) { set(i, replacement); result++; @@ -136,7 +215,7 @@ int silentReplace(Node toReplace, Node replacement) { int result = 0; - for (int i = 0; i < nodes.length; i++) { + for (int i = 0; i < size(); i++) { if (nodes[i] == toReplace) { silentSet(i, replacement); result++; @@ -145,32 +224,13 @@ return result; } - public void setAndClear(int index, Node clearedNode, int clearedIndex) { - assert !self().isDeleted() : "trying to setAndClear successor of deleted node: " + self().shortName(); - 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); - return; - } - } - assert false; - } - @Override public int size() { - return nodes.length; + return fixedLength + variableLength; } public void clearAll() { - for (int i = 0; i < nodes.length; i++) { + for (int i = 0; i < size(); i++) { set(i, Node.Null); } }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeBitMap.java Thu Jun 16 10:59:27 2011 +0200 @@ -77,6 +77,7 @@ private void check(Node node) { assert node.graph == graph : "this node is not part of the graph"; assert !isNew(node) : "this node (" + node.id() + ") was added to the graph after creating the node bitmap (" + bitMap.length() + ")"; + assert !node.isDeleted() : "node " + node + " is deleted!"; } @Override
--- a/graal/com.oracle.max.graal.graphviz/.checkstyle Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.graphviz/.checkstyle Thu Jun 16 10:59:27 2011 +0200 @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false"> - <local-check-config name="C1X Checkstyle checks" location="/GraalCompiler/.checkstyle_checks.xml" type="project" description=""> + <local-check-config name="C1X Checkstyle checks" location="/com.oracle.max.graal.compiler/.checkstyle_checks.xml" type="project" description=""> <additional-data name="protect-config-file" value="false"/> </local-check-config> <fileset name="all" enabled="true" check-config-name="C1X Checkstyle checks" local="true">
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java Thu Jun 16 10:59:27 2011 +0200 @@ -23,11 +23,13 @@ package com.oracle.max.graal.runtime; import com.oracle.max.graal.compiler.*; +import com.sun.cri.ri.*; public interface Compiler { VMEntries getVMEntries(); VMExits getVMExits(); GraalCompiler getCompiler(); + RiType lookupType(String returnType, HotSpotTypeResolved accessingClass); }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java Thu Jun 16 10:59:27 2011 +0200 @@ -155,4 +155,42 @@ return vmExits; } + @Override + public RiType lookupType(String returnType, HotSpotTypeResolved accessingClass) { + if (returnType.length() == 1 && vmExits instanceof VMExitsNative) { + VMExitsNative exitsNative = (VMExitsNative) vmExits; + CiKind kind = CiKind.fromPrimitiveOrVoidTypeChar(returnType.charAt(0)); + switch(kind) { + case Boolean: + return exitsNative.typeBoolean; + case Byte: + return exitsNative.typeByte; + case Char: + return exitsNative.typeChar; + case Double: + return exitsNative.typeDouble; + case Float: + return exitsNative.typeFloat; + case Illegal: + break; + case Int: + return exitsNative.typeInt; + case Jsr: + break; + case Long: + return exitsNative.typeLong; + case Object: + break; + case Short: + return exitsNative.typeShort; + case Void: + return exitsNative.typeVoid; + case Word: + break; + + } + } + return vmEntries.RiSignature_lookupType(returnType, accessingClass); + } + }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotSignature.java Wed Jun 15 16:49:46 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotSignature.java Thu Jun 16 10:59:27 2011 +0200 @@ -117,7 +117,7 @@ } RiType type = argumentTypes[index]; if (type == null) { - type = compiler.getVMEntries().RiSignature_lookupType(arguments.get(index), (HotSpotTypeResolved) accessingClass); + type = compiler.lookupType(arguments.get(index), (HotSpotTypeResolved) accessingClass); argumentTypes[index] = type; } return type; @@ -136,7 +136,7 @@ @Override public RiType returnType(RiType accessingClass) { if (returnTypeCache == null) { - returnTypeCache = compiler.getVMEntries().RiSignature_lookupType(returnType, (HotSpotTypeResolved) accessingClass); + returnTypeCache = compiler.lookupType(returnType, (HotSpotTypeResolved) accessingClass); } return returnTypeCache; }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml Thu Jun 16 10:59:27 2011 +0200 @@ -5,7 +5,6 @@ <Toolbar name="Edit" position="1" visible="false"/> <Toolbar name="File" position="1" visible="false" /> <Toolbar name="Memory" position="1" visible="false" /> - <Toolbar name="QuickSearch" position="1" visible="true" /> </Row> <Row> <Toolbar name="WorkspaceSwitcher" />
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml Thu Jun 16 10:59:27 2011 +0200 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd"> +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd"> <filesystem> <attr name="Actions\Edit\com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance\position" intvalue="200"/> <attr name="Actions\Edit\org-netbeans-core-ui-sysopen-SystemOpenAction.instance\position" intvalue="100"/> @@ -96,19 +96,16 @@ <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/> </file> </folder> - </folder> - <folder name="Toolbars"> - <folder name="QuickSearch"> - <attr name="SystemFileSystem.localizingBundle" stringvalue="com.sun.hotspot.igv.coordinator.Bundle"/> + <file name="Spacer.instance"> + <attr name="instanceCreate" methodvalue="javax.swing.Box.createHorizontalGlue"/> + <attr name="position" intvalue="9980"/> + </file> <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow"> - <attr name="originalFile" - stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/> + <attr name="displayName" bundlevalue="com.sun.hotspot.igv.coordinator.Bundle#Toolbars/QuickSearch"/> + <attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/> </file> </folder> - <!--<file name="Standard.xml" url="StandardConfiguration.xml"/>--> - - </folder> <folder name="Windows2"> <folder name="Components"> <file name="OutlineTopComponent.settings" url="OutlineTopComponentSettings.xml"/>
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java Thu Jun 16 10:59:27 2011 +0200 @@ -183,8 +183,12 @@ private String name; private Pattern valuePattern; + + public RegexpPropertyMatcher(String name, String value) { + this(name, value, 0); + } - public RegexpPropertyMatcher(String name, String value) { + public RegexpPropertyMatcher(String name, String value, int flags) { if (name == null) { throw new IllegalArgumentException("Property name must not be null!"); @@ -197,7 +201,7 @@ this.name = name; try { - valuePattern = Pattern.compile(value); + valuePattern = Pattern.compile(value, flags); } catch (PatternSyntaxException e) { throw new IllegalArgumentException("Bad pattern: " + value); }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java Thu Jun 16 10:59:27 2011 +0200 @@ -71,4 +71,10 @@ public int compareTo(Cluster o) { return toString().compareTo(o.toString()); } + + @Override + public String toString() { + return inputBlock.getName(); + } } +
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Thu Jun 16 10:59:27 2011 +0200 @@ -249,7 +249,6 @@ index++; } } - this.setColors(colors); } setColors(colors); viewChangedEvent.fire();
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewer.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewer.java Thu Jun 16 10:59:27 2011 +0200 @@ -27,6 +27,7 @@ import com.sun.hotspot.igv.graph.Figure; import java.awt.Component; import java.awt.Graphics2D; +import java.util.Collection; import java.util.List; import javax.swing.JComponent; import org.openide.awt.UndoRedo; @@ -57,6 +58,8 @@ public void componentShowing(); public void initialize(); + + public void setSelection(Collection<Figure> list); public void centerFigures(List<Figure> list);
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Thu Jun 16 10:59:27 2011 +0200 @@ -46,7 +46,6 @@ import com.sun.hotspot.igv.data.services.InputGraphProvider; import com.sun.hotspot.igv.filter.FilterChainProvider; import com.sun.hotspot.igv.graph.services.DiagramProvider; -import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator; import com.sun.hotspot.igv.util.RangeSlider; import com.sun.hotspot.igv.svg.BatikSVG; import com.sun.hotspot.igv.util.LookupHistory; @@ -54,7 +53,6 @@ import java.awt.CardLayout; import java.awt.Color; import java.awt.Graphics2D; -import java.awt.Point; import java.awt.event.HierarchyBoundsListener; import java.awt.event.HierarchyEvent; import java.awt.event.KeyEvent; @@ -436,7 +434,7 @@ } public void setSelectedFigures(List<Figure> list) { - getModel().setSelectedFigures(list); + scene.setSelection(list); scene.centerFigures(list); }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java Wed Jun 15 16:49:46 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java Thu Jun 16 10:59:27 2011 +0200 @@ -33,11 +33,13 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.regex.Pattern; import org.netbeans.spi.quicksearch.SearchProvider; import org.netbeans.spi.quicksearch.SearchRequest; import org.netbeans.spi.quicksearch.SearchResponse; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; +import org.openide.NotifyDescriptor.Message; /** * @@ -45,6 +47,8 @@ */ public class NodeQuickSearch implements SearchProvider { + private static final String DEFAULT_PROPERTY = "name"; + /** * Method is called by infrastructure when search operation was requested. * Implementors should evaluate given request and fill response object with @@ -54,51 +58,67 @@ * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned. */ public void evaluate(SearchRequest request, SearchResponse response) { - - final String[] parts = request.getText().split("="); - if (parts.length == 0) { + String query = request.getText(); + if (query.trim().isEmpty()) { return; } - String tmpName = parts[0]; + final String[] parts = query.split("=", 2); + + String name; + String value; - String value = null; - if (parts.length == 2) { + if (parts.length == 1) { + name = DEFAULT_PROPERTY; + value = ".*" + Pattern.quote(parts[0]) + ".*"; + } else { + name = parts[0]; value = parts[1]; } - if (parts.length == 1 && request.getText().endsWith("=")) { + if (value.isEmpty()) { value = ".*"; } - final String name = tmpName; + final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); + if (p != null && p.getGraph() != null) { + List<InputNode> matches = null; + try { + RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE); + Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(p.getGraph().getNodes()); - if (value != null) { - final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class); - if (p != null) { - final InputGraph graph = p.getGraph(); - if (graph != null) { - final RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value); - final Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes()); - final List<InputNode> list = selector.selectMultiple(matcher); - final Set<InputNode> set = new HashSet<InputNode>(list); + matches = selector.selectMultiple(matcher); + } catch (Exception e) { + final String msg = e.getMessage(); + response.addResult(new Runnable() { + public void run() { + Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " + + "perhaps due to a malformed query string:\n" + msg, + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(desc); + } + }, + "(Error during search)" + ); + } - response.addResult(new Runnable() { - + if (matches != null) { + final Set<InputNode> set = new HashSet<InputNode>(matches); + response.addResult(new Runnable() { public void run() { - final EditorTopComponent comp = EditorTopComponent.getActive(); if (comp != null) { comp.setSelectedNodes(set); comp.requestActive(); } } - }, "All " + list.size() + " matching nodes (" + name + "=" + value + ")"); - for (final InputNode n : list) { + }, + "All " + matches.size() + " matching nodes (" + name + "=" + value + ")" + ); - - response.addResult(new Runnable() { - + // Single matches + for (final InputNode n : matches) { + response.addResult(new Runnable() { public void run() { final EditorTopComponent comp = EditorTopComponent.getActive(); if (comp != null) { @@ -108,65 +128,13 @@ comp.requestActive(); } } - }, n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"); - } - } - - } else { - System.out.println("no input graph provider!"); - } - - } else if (parts.length == 1) { - - final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class); - - if (p != null) { - - final InputGraph graph = p.getGraph(); - if (p != null && graph != null) { - - Set<String> properties = new HashSet<String>(); - for (InputNode n : p.getGraph().getNodes()) { - for (Property property : n.getProperties()) { - properties.add(property.getName()); - } - } - - for (final String propertyName : properties) { - - if (propertyName.startsWith(name)) { - - response.addResult(new Runnable() { - - public void run() { - - NotifyDescriptor.InputLine d = - new NotifyDescriptor.InputLine("Value of the property?", "Property Value Input"); - if (DialogDisplayer.getDefault().notify(d) == NotifyDescriptor.OK_OPTION) { - String value = d.getInputText(); - final RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(propertyName, value); - final Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes()); - final List<InputNode> list = selector.selectMultiple(matcher); - final Set<InputNode> set = new HashSet<InputNode>(list); - - final EditorTopComponent comp = EditorTopComponent.getActive(); - if (comp != null) { - comp.setSelectedNodes(set); - comp.requestActive(); - } - - } - - - } - }, propertyName + "="); - } - } - - } else { - System.out.println("no input graph provider!"); + }, + n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")" + ); } } + } else { + System.out.println("no input graph provider!"); } } }