# HG changeset patch # User Thomas Wuerthinger # Date 1306155078 -7200 # Node ID 5e8a69041cd768868a95875a7c2dac8714c30e49 # Parent ca31e84ff154ed25820fe03734bddf48d1538a70 Model phi inputs as direct inputs in the graph instead of referring to the framestates of the predecessors. diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Mon May 23 14:51:18 2011 +0200 @@ -270,6 +270,10 @@ private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) { + mergeOrClone(first, stateAfter, loopHeader, false); + } + + private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader, boolean blockAppended) { if (first instanceof BlockBegin) { BlockBegin block = (BlockBegin) first; FrameState existingState = block.stateBefore(); @@ -293,7 +297,7 @@ assert existingState.localsSize() == stateAfter.localsSize(); assert existingState.stackSize() == stateAfter.stackSize(); - existingState.merge(block, stateAfter); + existingState.merge(block, stateAfter, blockAppended); } } else { assert false; @@ -304,13 +308,16 @@ int stackSize = newState.stackSize(); for (int i = 0; i < stackSize; i++) { // always insert phis for the stack - newState.setupPhiForStack(merge, i); + Value x = newState.stackAt(i); + if (x != null) { + newState.setupPhiForStack(merge, i).addInput(x); + } } int localsSize = newState.localsSize(); for (int i = 0; i < localsSize; i++) { Value x = newState.localAt(i); if (x != null) { - newState.setupPhiForLocal(merge, i); + newState.setupPhiForLocal(merge, i).addInput(x); } } } @@ -438,7 +445,7 @@ if (oldState != null && dispatchEntry.predecessors().size() == 1) { dispatchEntry.setStateBefore(null); } - mergeOrClone(dispatchEntry, state, false); + mergeOrClone(dispatchEntry, state, false, true); FrameState mergedState = dispatchEntry.stateBefore(); if (dispatchEntry.next() instanceof ExceptionDispatch) { diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Mon May 23 14:51:18 2011 +0200 @@ -40,7 +40,7 @@ @Override protected int inputCount() { - return super.inputCount() + INPUT_COUNT; + return super.inputCount() + INPUT_COUNT + maxValues; } @Override @@ -56,11 +56,13 @@ return (BlockBegin) inputs().get(super.inputCount() + INPUT_BLOCK); } - public BlockBegin setBlock(Value n) { + public Value setBlock(Value n) { return (BlockBegin) inputs().set(super.inputCount() + INPUT_BLOCK, n); } private final int index; + private final int maxValues; + private int usedInputCount; /** * Create a new Phi for the specified join block and local variable (or operand stack) slot. @@ -70,7 +72,13 @@ * @param graph */ public Phi(CiKind kind, BlockBegin block, int index, Graph graph) { - super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + this(kind, block, index, 2, graph); + } + + public Phi(CiKind kind, BlockBegin block, int index, int maxValues, Graph graph) { + super(kind, INPUT_COUNT + maxValues, SUCCESSOR_COUNT, graph); + usedInputCount = 1; + this.maxValues = maxValues; this.index = index; setBlock(block); } @@ -116,7 +124,7 @@ * @return the instruction that produced the value in the i'th predecessor */ public Value inputAt(int i) { - return inputIn(block().blockPredecessors().get(i).stateAfter()); + return (Value) inputs().get(i + INPUT_COUNT); } /** @@ -137,7 +145,7 @@ * @return the number of inputs in this phi */ public int phiInputCount() { - return block().blockPredecessors().size(); + return usedInputCount - 1; } @Override @@ -163,5 +171,21 @@ return "Phi: " + index + " (" + phiInputCount() + ")"; } + public Phi addInput(Value y) { + assert !this.isDeleted() && !y.isDeleted(); + Phi phi = this; + if (usedInputCount == inputs().size()) { + phi = new Phi(kind, block(), index, maxValues * 2, graph()); + for (int i = 0; i < phiInputCount(); ++i) { + phi.addInput(inputAt(i)); + } + phi.addInput(y); + this.replace(phi); + } else { + phi.inputs().set(usedInputCount++, y); + } + return phi; + } + } diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRTableSwitch.java Mon May 23 14:51:18 2011 +0200 @@ -22,7 +22,6 @@ */ package com.sun.c1x.lir; -import com.sun.c1x.ir.*; import com.sun.cri.ci.*; /** diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Mon May 23 14:51:18 2011 +0200 @@ -256,17 +256,20 @@ * @param block the block begin for which we are creating the phi * @param i the index into the stack for which to create a phi */ - public void setupPhiForStack(BlockBegin block, int i) { + public Phi setupPhiForStack(BlockBegin block, int i) { Value p = stackAt(i); if (p != null) { if (p instanceof Phi) { Phi phi = (Phi) p; if (phi.block() == block && phi.isOnStack() && phi.stackIndex() == i) { - return; + return phi; } } - inputs().set(localsSize + i, new Phi(p.kind, block, -i - 1, graph())); + Phi phi = new Phi(p.kind, block, -i - 1, graph()); + inputs().set(localsSize + i, phi); + return phi; } + return null; } /** @@ -274,15 +277,17 @@ * @param block the block begin for which we are creating the phi * @param i the index of the local variable for which to create the phi */ - public void setupPhiForLocal(BlockBegin block, int i) { + public Phi setupPhiForLocal(BlockBegin block, int i) { Value p = localAt(i); if (p instanceof Phi) { Phi phi = (Phi) p; if (phi.block() == block && phi.isLocal() && phi.localIndex() == i) { - return; + return phi; } } - storeLocal(i, new Phi(p.kind, block, i, graph())); + Phi phi = new Phi(p.kind, block, i, graph()); + storeLocal(i, phi); + return phi; } /** @@ -312,28 +317,6 @@ return localsSize + stackSize; } - public void checkPhis(BlockBegin block, FrameState other) { - checkSize(other); - for (int i = 0; i < valuesSize(); i++) { - Value x = valueAt(i); - Value y = other.valueAt(i); - if (x != null && x != y) { - if (x instanceof Phi) { - Phi phi = (Phi) x; - if (phi.block() == block) { - for (int j = 0; j < phi.phiInputCount(); j++) { - if (phi.inputIn(other) == null) { - throw new CiBailout("phi " + phi + " has null operand at new predecessor"); - } - } - continue; - } - } - throw new CiBailout("instruction is not a phi or null at " + i); - } - } - } - private void checkSize(FrameStateAccess other) { if (other.stackSize() != stackSize()) { throw new CiBailout("stack sizes do not match"); @@ -342,7 +325,7 @@ } } - public void merge(BlockBegin block, FrameStateAccess other) { + public void merge(BlockBegin block, FrameStateAccess other, boolean blockAppended) { checkSize(other); for (int i = 0; i < valuesSize(); i++) { Value x = valueAt(i); @@ -359,12 +342,34 @@ inputs().set(i, null); continue; } + Phi phi = null; if (i < localsSize) { // this a local - setupPhiForLocal(block, i); + phi = setupPhiForLocal(block, i); } else { // this is a stack slot - setupPhiForStack(block, i - localsSize); + phi = setupPhiForStack(block, i - localsSize); + } + + Phi originalPhi = phi; + if (phi.phiInputCount() == 0) { + int size = block.predecessors().size(); + if (blockAppended) { + size--; + } + for (int j = 0; j < size; ++j) { + phi = phi.addInput(x); + } + phi = phi.addInput(y); + } else { + phi = phi.addInput(y); + } + if (originalPhi != phi) { + for (int j = 0; j < other.localsSize() + other.stackSize(); ++j) { + if (other.valueAt(j) == originalPhi) { + other.setValueAt(j, phi); + } + } } } } @@ -467,4 +472,9 @@ public void visitFrameState(FrameState i) { // nothing to do for now } + + @Override + public void setValueAt(int j, Value v) { + inputs().set(j, v); + } } diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java Mon May 23 14:51:18 2011 +0200 @@ -44,4 +44,6 @@ FrameState duplicateWithEmptyStack(int bci); + void setValueAt(int j, Value v); + } diff -r ca31e84ff154 -r 5e8a69041cd7 graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Sat May 21 17:56:11 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Mon May 23 14:51:18 2011 +0200 @@ -477,4 +477,15 @@ } } + @Override + public void setValueAt(int i, Value v) { + if (i < locals.length) { + locals[i] = v; + } else if (i < locals.length + stackIndex) { + stack[i - locals.length] = v; + } else { + locks.set(i - locals.length - stack.length, v); + } + } + }