OpenJDK / graal / graal-jvmci-8
changeset 2981:42681ed31c4d
Some LoopCounter work
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Wed Jun 15 11:20:26 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 Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jun 15 11:20:26 2011 +0200 @@ -248,6 +248,8 @@ } if (!(instr instanceof Merge) && instr != instr.graph().start()) { walkState(instr, stateAfter); + } + if (instr instanceof Value) { doRoot((Value) instr); } if (stateAfter != null) { @@ -275,7 +277,7 @@ } private static boolean jumpsToNextBlock(Node node) { - return node instanceof BlockEnd || node instanceof Anchor; + return node instanceof BlockEnd || node instanceof Anchor || node instanceof LoopEnd; } @Override @@ -1183,7 +1185,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) { @@ -1444,6 +1446,29 @@ } } resolver.dispose(); + + //TODO (gd) remove that later + Node suxFirstInstr = sux.firstInstruction(); + if (suxFirstInstr instanceof LoopBegin) { + for (Node n : suxFirstInstr.usages()) { + if (n instanceof LoopCounter) { + LoopCounter counter = (LoopCounter) n; + if (counter.operand().isIllegal()) { + createResultVariable(counter); + } + if (predIndex == 0) { + 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())); + } + } + } + } + } } } } @@ -1465,7 +1490,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); } @@ -1477,8 +1502,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 Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jun 15 11:20:26 2011 +0200 @@ -69,14 +69,14 @@ */ public void build() { new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph); - printGraph("After GraphBuilding", compilation.graph); + //printGraph("After GraphBuilding", compilation.graph); //new DuplicationPhase().apply(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) { @@ -88,9 +88,11 @@ if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase().apply(graph); new DeadCodeEliminationPhase().apply(compilation.graph); - printGraph("After Canonicalization", graph); + //printGraph("After Canonicalization", graph); } + new LoopPhase().apply(graph); + new LoweringPhase().apply(graph); new SplitCriticalEdgesPhase().apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Wed Jun 15 11:20:26 2011 +0200 @@ -109,7 +109,7 @@ @Override public String shortName() { - return "If " + compare().condition.operator; + return "If"; } @Override
--- /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 Wed Jun 15 11:20:26 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/Phi.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Wed Jun 15 11:20:26 2011 +0200 @@ -30,7 +30,7 @@ * The {@code Phi} instruction represents the merging of dataflow * in the instruction graph. It refers to a join block and a variable. */ -public final class Phi extends FloatingNode { +public class Phi extends FloatingNode { private static final int DEFAULT_MAX_VALUES = 2; @@ -92,8 +92,8 @@ return (Value) inputs().get(INPUT_COUNT + i); } - public Node setValueAt(int i, Node x) { - return inputs().set(INPUT_COUNT + i, x); + public Value setValueAt(int i, Value x) { + return (Value) inputs().set(INPUT_COUNT + i, x); } /** @@ -144,7 +144,7 @@ return "Phi: (" + str + ")"; } - public Phi addInput(Node y) { + public Phi addInput(Value y) { assert !this.isDeleted() && !y.isDeleted(); Phi phi = this; if (usedInputCount == maxValues) { @@ -162,11 +162,11 @@ public void removeInput(int index) { assert index < valueCount() : "index: " + index + ", valueCount: " + valueCount() + "@phi " + id(); - setValueAt(index, Node.Null); + setValueAt(index, null); for (int i = index + 1; i < valueCount(); ++i) { setValueAt(i - 1, valueAt(i)); } - setValueAt(valueCount() - 1, Node.Null); + setValueAt(valueCount() - 1, null); usedInputCount--; }
--- /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 Wed Jun 15 11:20:26 2011 +0200 @@ -0,0 +1,120 @@ +/* + * 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.*; + + +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) { + LoopEnd loopEnd = loopBegin.loopEnd(); + NodeBitMap loopNodes = computeLoopNodes(loopBegin); + List<Node> usages = new ArrayList<Node>(loopBegin.usages()); + for (Node usage : usages) { + if (usage instanceof Phi) { + Phi phi = (Phi) usage; + if (phi.valueCount() == 2) { // TODO (gd) remove predecessor order assumptions + Value backEdge = phi.valueAt(1); //assumes backEdge with pred index 1 + Value init = phi.valueAt(0); + Value stride = null; + boolean createAfterAddCounter = false; + if (!loopNodes.isMarked(init) && backEdge instanceof IntegerAdd && loopNodes.isMarked(backEdge)) { + IntegerAdd add = (IntegerAdd) backEdge; + int addUsageCount = 0; + System.out.println("BackEdge usages :"); + for (Node u : add.usages()) { + if (u != loopEnd.stateBefore()) { + System.out.println(" - " + u); + addUsageCount++; + } + } + if (add.x() == phi) { + stride = add.y(); + } else if (add.y() == phi) { + stride = add.x(); + } + if (addUsageCount > 1) { + createAfterAddCounter = true; + } + } + if (stride != null && !loopNodes.isMarked(stride)) { + Graph graph = loopBegin.graph(); + LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph); + phi.replace(counter); + loopEnd.stateBefore().inputs().replace(backEdge, counter); + if (createAfterAddCounter) { + 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(); + } + } + } + } + } + } + + 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); + } + } + 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/Phase.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Wed Jun 15 11:20:26 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/schedule/IdentifyBlocksPhase.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Wed Jun 15 11:20:26 2011 +0200 @@ -159,7 +159,7 @@ if (n instanceof Merge) { for (Node usage : n.usages()) { - if (usage instanceof Phi) { + if (usage instanceof Phi || usage instanceof LoopCounter) { nodeToBlock.set(usage, block); } } @@ -221,7 +221,7 @@ } } else { Block dominatorBlock = b.getPredecessors().get(0); - for (int i=1; i<b.getPredecessors().size(); ++i) { + for (int i = 1; i < b.getPredecessors().size(); ++i) { dominatorBlock = getCommonDominator(dominatorBlock, b.getPredecessors().get(i)); } CiBitMap blockMap = new CiBitMap(blocks.size()); @@ -300,6 +300,13 @@ 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.getPredecessors().get(0)); // TODO (gd) nasty 0 constant + } } else { block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); } @@ -353,7 +360,7 @@ } 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; }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Tue Jun 14 10:32:29 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Wed Jun 15 11:20:26 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()); } } @@ -496,10 +496,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())); }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java Tue Jun 14 10:32:29 2011 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java Wed Jun 15 11:20:26 2011 +0200 @@ -71,4 +71,10 @@ public int compareTo(Cluster o) { return toString().compareTo(o.toString()); } + + @Override + public String toString() { + return inputBlock.getName(); + } } +