*/
public static final Comparator<SsaBasicBlock> LABEL_COMPARATOR =
new LabelComparator();
-
+
/** {@code non-null;} insn list associated with this instance */
private ArrayList<SsaInsn> insns;
/** list of dom children */
private final ArrayList<SsaBasicBlock> domChildren;
- /**
- * The number of moves added to the end of the block during the
+ /**
+ * the number of moves added to the end of the block during the
* phi-removal process. Retained for subsequent move scheduling.
*/
private int movesFromPhisAtEnd = 0;
- /**
- * The number of moves added to the beginning of the block during the
+ /**
+ * the number of moves added to the beginning of the block during the
* phi-removal process. Retained for subsequent move scheduling.
*/
private int movesFromPhisAtBeginning = 0;
/**
* Creates a new empty basic block.
- *
+ *
* @param basicBlockIndex index this block will have
* @param ropLabel original rop-form label
* @param parent method of this block
*
* @param rmeth original method
* @param basicBlockIndex index this block will have
- * @param parent method of this block
- * predecessor set will be updated.
+ * @param parent method of this block predecessor set will be
+ * updated
* @return new instance
*/
public static SsaBasicBlock newFromRop(RopMethod rmeth,
*
* @param child {@code non-null;} new dom child
*/
- void addDomChild(SsaBasicBlock child) {
+ public void addDomChild(SsaBasicBlock child) {
domChildren.add(child);
}
*
* @return {@code non-null;} list of dom children
*/
- ArrayList<SsaBasicBlock> getDomChildren() {
+ public ArrayList<SsaBasicBlock> getDomChildren() {
return domChildren;
}
*
* @param reg {@code >=0;} result reg
*/
- void addPhiInsnForReg(int reg) {
+ public void addPhiInsnForReg(int reg) {
insns.add(0, new PhiInsn(reg, this));
}
*
* @param resultSpec {@code non-null;} reg
*/
- void addPhiInsnForReg(RegisterSpec resultSpec) {
+ public void addPhiInsnForReg(RegisterSpec resultSpec) {
insns.add(0, new PhiInsn(resultSpec, this));
}
*
* @param insn {@code non-null;} rop-form insn to add
*/
- void addInsnToHead(Insn insn) {
+ public void addInsnToHead(Insn insn) {
SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);
insns.add(getCountPhiInsns(), newInsn);
parent.onInsnAdded(newInsn);
*
* @param insn {@code non-null;} rop-form insn to add, which must branch.
*/
- void replaceLastInsn(Insn insn) {
+ public void replaceLastInsn(Insn insn) {
if (insn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {
throw new IllegalArgumentException("last insn must branch");
}
/**
* Visits each phi insn.
- *
+ *
* @param v {@code non-null;} the callback
*/
public void forEachPhiInsn(PhiInsn.Visitor v) {
-
int sz = insns.size();
+
for (int i = 0; i < sz; i++) {
SsaInsn insn = insns.get(i);
if (insn instanceof PhiInsn) {
public void removeAllPhiInsns() {
/*
* Presently we assume PhiInsn's are in a continuous
- * block at the top of the list
+ * block at the top of the list.
*/
insns.subList(0, getCountPhiInsns()).clear();
/**
* Gets the number of phi insns at the top of this basic block.
+ *
* @return count of phi insns
*/
private int getCountPhiInsns() {
/**
* @return {@code non-null;} the (mutable) instruction list for this block,
- * with phi insns at the beginning.
+ * with phi insns at the beginning
*/
public ArrayList<SsaInsn> getInsns() {
return insns;
/**
* @return {@code >= -1;} block index of primary successor or
- * {@code -1} if no primary successor.
+ * {@code -1} if no primary successor
*/
public int getPrimarySuccessorIndex() {
return primarySuccessor;
public SsaBasicBlock insertNewPredecessor() {
SsaBasicBlock newPred = parent.makeNewGotoBlock();
- // Update the new block
+ // Update the new block.
newPred.predecessors = predecessors;
newPred.successors.set(index) ;
newPred.successorList.add(index);
newPred.primarySuccessor = index;
- // Update us
+ // Update us.
predecessors = new BitSet(parent.getBlocks().size());
predecessors.set(newPred.index);
- // Update our (soon-to-be) old predecessors
+ // Update our (soon-to-be) old predecessors.
for (int i = newPred.predecessors.nextSetBit(0); i >= 0;
i = newPred.predecessors.nextSetBit(i + 1)) {
+ " not successor of " + getRopLabelString());
}
- // Update the new block
+ // Update the new block.
newSucc.predecessors.set(this.index);
newSucc.successors.set(other.index) ;
newSucc.successorList.add(other.index);
newSucc.primarySuccessor = other.index;
- // Update us
+ // Update us.
for (int i = successorList.size() - 1 ; i >= 0; i--) {
if (successorList.get(i) == other.index) {
successorList.set(i, newSucc.index);
successors.clear(other.index);
successors.set(newSucc.index);
- // Update "other"
+ // Update "other".
other.predecessors.set(newSucc.index);
other.predecessors.set(index, successors.get(other.index));
/**
* Replaces an old successor with a new successor. This will throw
* RuntimeException if {@code oldIndex} was not a successor.
- *
+ *
* @param oldIndex index of old successor block
- * @param newIndex index of new successor block.
+ * @param newIndex index of new successor block
*/
public void replaceSuccessor(int oldIndex, int newIndex) {
if (oldIndex == newIndex) {
* before the last instruction. If the result of the final instruction
* is the source in question, then the move is placed at the beginning of
* the primary successor block. This is for unversioned registers.
- *
+ *
* @param result move destination
* @param source move source
*/
if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
/*
- * The final insn in this block has a source or result register,
- * and the moves we may need to place and schedule may interfere.
- * We need to insert this instruction at the
- * beginning of the primary successor block instead. We know
- * this is safe, because when we edge-split earlier, we ensured
- * that each successor has only us as a predecessor.
+ * The final insn in this block has a source or result
+ * register, and the moves we may need to place and
+ * schedule may interfere. We need to insert this
+ * instruction at the beginning of the primary successor
+ * block instead. We know this is safe, because when we
+ * edge-split earlier, we ensured that each successor has
+ * only us as a predecessor.
*/
for (int i = successors.nextSetBit(0)
}
} else {
/*
- * We can safely add a move to the end of the block
- * just before the last instruction because
- * the final insn does not assign to anything.
+ * We can safely add a move to the end of the block just
+ * before the last instruction, because the final insn does
+ * not assign to anything.
*/
-
- RegisterSpecList sources;
- sources = RegisterSpecList.make(source);
-
- NormalSsaInsn toAdd;
-
- toAdd = new NormalSsaInsn(
+ RegisterSpecList sources = RegisterSpecList.make(source);
+ NormalSsaInsn toAdd = new NormalSsaInsn(
new PlainInsn(Rops.opMove(result.getType()),
SourcePosition.NO_INFO, result, sources), this);
/**
* Adds a move instruction after the phi insn block.
- *
+ *
* @param result move destination
* @param source move source
*/
return;
}
- RegisterSpecList sources;
- sources = RegisterSpecList.make(source);
-
- NormalSsaInsn toAdd;
-
- toAdd = new NormalSsaInsn(
- new PlainInsn(Rops.opMove(result.getType()),
- SourcePosition.NO_INFO, result, sources), this);
+ RegisterSpecList sources = RegisterSpecList.make(source);
+ NormalSsaInsn toAdd = new NormalSsaInsn(
+ new PlainInsn(Rops.opMove(result.getType()),
+ SourcePosition.NO_INFO, result, sources), this);
insns.add(getCountPhiInsns(), toAdd);
- movesFromPhisAtBeginning++;
+ movesFromPhisAtBeginning++;
}
/**
private static void setRegsUsed (BitSet regsUsed, RegisterSpec rs) {
regsUsed.set(rs.getReg());
if (rs.getCategory() > 1) {
- regsUsed.set(rs.getReg() + 1);
+ regsUsed.set(rs.getReg() + 1);
}
}
* TODO: See Briggs, et al "Practical Improvements to the Construction and
* Destruction of Static Single Assignment Form" section 5. a) This can
* be done in three passes.
- *
+ *
* @param toSchedule List of instructions. Must consist only of moves.
*/
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
- // TODO get rid of this
+
+ // TODO: Get rid of this.
BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
int sz = toSchedule.size();
}
}
- // If we've made no progress in this iteration, there's a
- // circular dependency. Split it using the temp reg.
+ /*
+ * If we've made no progress in this iteration, there's a
+ * circular dependency. Split it using the temp reg.
+ */
if (oldInsertPlace == insertPlace) {
SsaInsn insnToSplit = null;
insn.getSources().get(0))) {
insnToSplit = insn;
- // We're going to split this insn--move it to the
- // front
+ /*
+ * We're going to split this insn; move it to the
+ * front.
+ */
Collections.swap(toSchedule, insertPlace, i);
break;
}
}
- // At least one insn will be set above
+ // At least one insn will be set above.
RegisterSpec result = insnToSplit.getResult();
RegisterSpec tempSpec = result.withReg(
parent.borrowSpareRegister(result.getCategory()));
- NormalSsaInsn toAdd;
-
- toAdd = new NormalSsaInsn(
- new PlainInsn(Rops.opMove(result.getType()),
- SourcePosition.NO_INFO,
- tempSpec,
- insnToSplit.getSources()), this);
+ NormalSsaInsn toAdd = new NormalSsaInsn(
+ new PlainInsn(Rops.opMove(result.getType()),
+ SourcePosition.NO_INFO,
+ tempSpec,
+ insnToSplit.getSources()), this);
toSchedule.add(insertPlace++, toAdd);
- NormalSsaInsn toReplace;
- RegisterSpecList newSources;
-
- newSources = RegisterSpecList.make(tempSpec);
+ RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
- toReplace = new NormalSsaInsn(
- new PlainInsn(Rops.opMove(result.getType()),
- SourcePosition.NO_INFO,
- result,
- newSources), this);
+ NormalSsaInsn toReplace = new NormalSsaInsn(
+ new PlainInsn(Rops.opMove(result.getType()),
+ SourcePosition.NO_INFO,
+ result,
+ newSources), this);
toSchedule.set(insertPlace, toReplace);
- // size has changed
+ // The size changed.
sz = toSchedule.size();
}
/**
* Adds {@code regV} to the live-out list for this block. This is called
* by the liveness analyzer.
- *
+ *
* @param regV register that is live-out for this block.
*/
public void addLiveOut (int regV) {
/**
* Adds {@code regV} to the live-in list for this block. This is
* called by the liveness analyzer.
- *
+ *
* @param regV register that is live-in for this block.
*/
public void addLiveIn (int regV) {
liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
}
- liveIn.add(regV);
+ liveIn.add(regV);
}
/**
/**
* Returns the set of live-out registers. Valid after register
* interference graph has been generated, otherwise empty.
- *
- * @return {@code non-null;} live-out register set.
+ *
+ * @return {@code non-null;} live-out register set
*/
public IntSet getLiveOutRegs() {
if (liveOut == null) {
* that it's either the start block or it has predecessors, which suffices
* for all current control flow transformations.
*
- * @return true if reachable
+ * @return {@code true} if reachable
*/
public boolean isReachable() {
return index == parent.getEntryBlockIndex()
|| predecessors.cardinality() > 0;
}
-
+
/**
* Sorts move instructions added via {@code addMoveToEnd} during
* phi removal so that results don't overwrite sources that are used.
SsaInsn firstNonPhiMoveInsn = insns.get(movesFromPhisAtBeginning);
- //TODO it's actually possible that this case never happens,
- //because a move-exception block, having only one predecessor
- //in SSA form, perhaps is never on a dominance frontier.
+ /*
+ * TODO: It's actually possible that this case never happens,
+ * because a move-exception block, having only one predecessor
+ * in SSA form, perhaps is never on a dominance frontier.
+ */
if (firstNonPhiMoveInsn.isMoveException()) {
if (true) {
/*
* We've yet to observe this case, and if it can
- * occur the code written to handle it probably
+ * occur the code written to handle it probably
* does not work.
*/
throw new RuntimeException(
"Unexpected: moves from "
+"phis before move-exception");
} else {
-
- // A move-exception insn must be placed first in this block
- // We need to move it there, and deal with possible
- // interference.
+ /*
+ * A move-exception insn must be placed first in this block
+ * We need to move it there, and deal with possible
+ * interference.
+ */
boolean moveExceptionInterferes = false;
int moveExceptionResult
= firstNonPhiMoveInsn.getResult().getReg();
- // Does the move-exception result reg interfere with the
- // phi moves?
+ /*
+ * Does the move-exception result reg interfere with the
+ * phi moves?
+ */
for (SsaInsn insn : toSchedule) {
if (insn.isResultReg(moveExceptionResult)
|| insn.isRegASource(moveExceptionResult)) {
insns.remove(movesFromPhisAtBeginning);
insns.add(0, firstNonPhiMoveInsn);
} else {
- // We need to move the result to a spare reg
- // and move it back.
-
- int spareRegister;
- RegisterSpec originalResultSpec;
-
- originalResultSpec = firstNonPhiMoveInsn.getResult();
- spareRegister = parent.borrowSpareRegister(
+ /*
+ * We need to move the result to a spare reg
+ * and move it back.
+ */
+ RegisterSpec originalResultSpec
+ = firstNonPhiMoveInsn.getResult();
+ int spareRegister = parent.borrowSpareRegister(
originalResultSpec.getCategory());
// We now move it to a spare register.
insns.add(0, firstNonPhiMoveInsn);
- // And here we move it back
-
- NormalSsaInsn toAdd;
+ // And here we move it back.
- toAdd = new NormalSsaInsn(
- new PlainInsn(Rops.opMove(
- tempSpec.getType()),
- SourcePosition.NO_INFO,
- originalResultSpec,
- RegisterSpecList.make(tempSpec)),
+ NormalSsaInsn toAdd = new NormalSsaInsn(
+ new PlainInsn(
+ Rops.opMove(tempSpec.getType()),
+ SourcePosition.NO_INFO,
+ originalResultSpec,
+ RegisterSpecList.make(tempSpec)),
this);
- // Place it immediately after the phi-moves,
- // overwriting the move-exception that was there.
+ /*
+ * Place it immediately after the phi-moves,
+ * overwriting the move-exception that was there.
+ */
insns.set(movesFromPhisAtBeginning + 1, toAdd);
}
}
}
}
+
if (movesFromPhisAtEnd > 1) {
scheduleUseBeforeAssigned(
insns.subList(insns.size() - movesFromPhisAtEnd - 1,
}
/**
- * Visit all insns in this block.
- *
+ * Visits all insns in this block.
+ *
* @param visitor {@code non-null;} callback interface
*/
public void forEachInsn(SsaInsn.Visitor visitor) {
public interface Visitor {
/**
* Indicates a block has been visited by an iterator method.
- *
+ *
* @param v {@code non-null;} block visited
* @param parent {@code null-ok;} parent node if applicable
*/
public static boolean DEBUG = false;
/**
- * returns an SSA representation, edge-split and with phi functions placed
+ * Returns an SSA representation, edge-split and with phi
+ * functions placed.
+ *
* @param rmeth input
* @param paramWidth the total width, in register-units, of the method's
* parameters
- * @param isStatic true if this method has no 'this'
+ * @param isStatic {@code true} if this method has no {@code this}
* pointer argument
* @return output in SSA form
*/
- public static SsaMethod convertToSsaMethod(RopMethod rmeth,
+ public static SsaMethod convertToSsaMethod(RopMethod rmeth,
int paramWidth, boolean isStatic) {
- SsaMethod result;
-
- result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
+ SsaMethod result
+ = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
edgeSplit(result);
new SsaRenamer(result).run();
/*
- * Exit block, added here, is not considered for edge splitting
+ * The exit block, added here, is not considered for edge splitting
* or phi placement since no actual control flows to it.
*/
result.makeExitBlock();
/**
* Returns an SSA represention with only the edge-splitter run.
+ *
* @param rmeth method to process
* @param paramWidth width of all arguments in the method
- * @param isStatic true if this method has no 'this' pointer argument
- * @return an SSA represention with only the edge-splitter run.
+ * @param isStatic {@code true} if this method has no {@code this}
+ * pointer argument
+ * @return an SSA represention with only the edge-splitter run
*/
public static SsaMethod testEdgeSplit (RopMethod rmeth, int paramWidth,
boolean isStatic) {
/**
* Returns an SSA represention with only the steps through the
* phi placement run.
+ *
* @param rmeth method to process
* @param paramWidth width of all arguments in the method
- * @param isStatic true if this method has no 'this' pointer argument
- * @return an SSA represention with only the edge-splitter run.
+ * @param isStatic {@code true} if this method has no {@code this}
+ * pointer argument
+ * @return an SSA represention with only the edge-splitter run
*/
public static SsaMethod testPhiPlacement (RopMethod rmeth, int paramWidth,
boolean isStatic) {
}
/**
- * See Appel section 19.1
+ * See Appel section 19.1:
+ *
* Converts CFG into "edge-split" form, such that each node either a
* unique successor or unique predecessor.<p>
*
* value to have a primary successor that has no other
* predecessor. This ensures move statements can always be
* inserted correctly when phi statements are removed.
- *
+ *
* @param result method to process
*/
private static void edgeSplit(SsaMethod result) {
-
edgeSplitPredecessors(result);
edgeSplitMoveExceptionsAndResults(result);
edgeSplitSuccessors(result);
/**
* Inserts Z nodes as new predecessors for every node that has multiple
* successors and multiple predecessors.
+ *
* @param result {@code non-null;} method to process
*/
private static void edgeSplitPredecessors(SsaMethod result) {
ArrayList<SsaBasicBlock> blocks = result.getBlocks();
-
- // New blocks are added to the end of the block list during
- // this iteration
+
+ /*
+ * New blocks are added to the end of the block list during
+ * this iteration.
+ */
for (int i = blocks.size() - 1; i >= 0; i-- ) {
SsaBasicBlock block = blocks.get(i);
if (nodeNeedsUniquePredecessor(block)) {
/**
* @param block {@code non-null;} block in question
- * @return true if this node needs to have a unique predecessor created for
- * it.
+ * @return {@code true} if this node needs to have a unique
+ * predecessor created for it
*/
private static boolean nodeNeedsUniquePredecessor(SsaBasicBlock block) {
-
/*
* Any block with that has both multiple successors and multiple
* predecessors needs a new predecessor node.
* We may need room to insert move insns later, so make sure to split
* any block that starts with a move-exception such that there is a
* unique move-exception block for each predecessor.
+ *
* @param ssaMeth method to process
*/
private static void edgeSplitMoveExceptionsAndResults(SsaMethod ssaMeth) {
ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
- // New blocks are added to the end of the block list during
- // this iteration
+ /*
+ * New blocks are added to the end of the block list during
+ * this iteration.
+ */
for (int i = blocks.size() - 1; i >= 0; i-- ) {
SsaBasicBlock block = blocks.get(i);
-
- // Any block that starts with a move-exception and has more than
- // one predecessor...
+
+ /*
+ * Any block that starts with a move-exception and has more than
+ * one predecessor...
+ */
if (!block.isExitBlock()
- && block.getPredecessors().cardinality() > 1
+ && block.getPredecessors().cardinality() > 1
&& block.getInsns().get(0).isMoveException()) {
- // block.getPredecessors() is changed in the loop below
+ // block.getPredecessors() is changed in the loop below.
BitSet preds = (BitSet)block.getPredecessors().clone();
for (int j = preds.nextSetBit(0); j >= 0;
- j = preds.nextSetBit(j + 1)) {
-
+ j = preds.nextSetBit(j + 1)) {
SsaBasicBlock predecessor = blocks.get(j);
+ SsaBasicBlock zNode
+ = predecessor.insertNewSuccessor(block);
- SsaBasicBlock zNode = predecessor.insertNewSuccessor(block);
-
- // Make sure to place the move-exception as the
- // first insn...
+ /*
+ * Make sure to place the move-exception as the
+ * first insn.
+ */
zNode.getInsns().add(0, block.getInsns().get(0).clone());
}
- // remove the move-exception from the original block...
+ // Remove the move-exception from the original block.
block.getInsns().remove(0);
}
}
}
/**
- * Inserts Z nodes for every node that needs a new
+ * Inserts Z nodes for every node that needs a new
* successor.
+ *
* @param result {@code non-null;} method to process
*/
private static void edgeSplitSuccessors(SsaMethod result) {
ArrayList<SsaBasicBlock> blocks = result.getBlocks();
- // New blocks are added to the end of the block list during
- // this iteration
+ /*
+ * New blocks are added to the end of the block list during
+ * this iteration.
+ */
for (int i = blocks.size() - 1; i >= 0; i-- ) {
SsaBasicBlock block = blocks.get(i);
- // successors list is modified in loop below
+ // Successors list is modified in loop below.
BitSet successors = (BitSet)block.getSuccessors().clone();
for (int j = successors.nextSetBit(0);
j >= 0; j = successors.nextSetBit(j+1)) {
}
/**
- * Returns true if block and successor need a Z-node between them.
- * Presently, this is true if the final instruction has any sources
- * or results and the current successor block has more than one
- * predecessor.
+ * Returns {@code true} if block and successor need a Z-node
+ * between them. Presently, this is {@code true} if the final
+ * instruction has any sources or results and the current
+ * successor block has more than one predecessor.
+ *
* @param block predecessor node
* @param succ successor node
- * @return true if a Z node is needed
+ * @return {@code true} if a Z node is needed
*/
private static boolean needsNewSuccessor(SsaBasicBlock block,
SsaBasicBlock succ) {
-
ArrayList<SsaInsn> insns = block.getInsns();
SsaInsn lastInsn = insns.get(insns.size() - 1);
}
/**
- * See Appel algorithm 19.6
+ * See Appel algorithm 19.6:
+ *
* Place Phi functions in appropriate locations.
*
- * @param ssaMeth {@code non-null;} method to process. Modifications made in-place
- * @param localInfo {@code non-null;} Local variable info, used when placing phis
+ * @param ssaMeth {@code non-null;} method to process.
+ * Modifications are made in-place.
+ * @param localInfo {@code non-null;} local variable info, used
+ * when placing phis
*/
private static void placePhiFunctions (SsaMethod ssaMeth,
LocalVariableInfo localInfo) {
for (int i = 0; i < regCount; i++) {
StringBuilder sb = new StringBuilder();
-
sb.append('v').append(i).append(": ");
-
sb.append(defsites[i].toString());
-
System.out.println(sb);
}
}
for (int reg = 0, s = ssaMeth.getRegCount() ; reg < s ; reg++ ) {
int workBlockIndex;
- /* Worklist set starts out with each node where reg is assigned */
+ /* Worklist set starts out with each node where reg is assigned. */
- worklist = (BitSet)(defsites[reg].clone());
+ worklist = (BitSet) (defsites[reg].clone());
while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {
worklist.clear(workBlockIndex);
IntIterator dfIterator
- = domInfos[workBlockIndex]
- .dominanceFrontiers.iterator();
+ = domInfos[workBlockIndex].dominanceFrontiers.iterator();
while (dfIterator.hasNext()) {
int dfBlockIndex = dfIterator.next();
for (int i = 0; i < regCount; i++) {
StringBuilder sb = new StringBuilder();
-
sb.append('v').append(i).append(": ");
-
sb.append(phisites[i].toString());
-
System.out.println(sb);
}
}
* current block has been processed, this mapping table is then copied
* and used as the initial state for child blocks.<p>
*/
-class SsaRenamer implements Runnable {
-
+public class SsaRenamer implements Runnable {
+ /** debug flag */
private static final boolean DEBUG = false;
- /** Method we're processing */
+ /** method we're processing */
private final SsaMethod ssaMeth;
/** next available SSA register */
private final int ropRegCount;
/**
- * Indexed by block index; register version state for each block start.
+ * indexed by block index; register version state for each block start.
* This list is updated by each dom parent for its children. The only
* sub-arrays that exist at any one time are the start states for blocks
* yet to be processed by a {@code BlockRenamer} instance.
private final ArrayList<LocalItem> ssaRegToLocalItems;
/**
- * Maps SSA registers back to the original rop number.
- * Used for debug only.
+ * maps SSA registers back to the original rop number. Used for
+ * debug only.
*/
private IntList ssaRegToRopReg;
* @param ssaMeth {@code non-null;} un-renamed SSA method that will
* be renamed.
*/
- SsaRenamer (final SsaMethod ssaMeth) {
+ public SsaRenamer(SsaMethod ssaMeth) {
ropRegCount = ssaMeth.getRegCount();
this.ssaMeth = ssaMeth;
+
/*
* Reserve the first N registers in the SSA register space for
- * "version 0" registers
+ * "version 0" registers.
*/
nextSsaReg = ropRegCount;
startsForBlocks = new RegisterSpec[ssaMeth.getBlocks().size()][];
* in-place.
*/
public void run() {
-
// Rename each block in dom-tree DFS order.
ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {
public void visitBlock (SsaBasicBlock block,
if (DEBUG) {
System.out.println("SSA\tRop");
- // We're going to compute the version of the rop register
- // by keeping a running total of how many times the rop register
- // has been mapped.
+ /*
+ * We're going to compute the version of the rop register
+ * by keeping a running total of how many times the rop
+ * register has been mapped.
+ */
int[] versions = new int[ropRegCount];
int sz = ssaRegToRopReg.size();
}
/**
- * Duplicates a RegisterSpec array
+ * Duplicates a RegisterSpec array.
+ *
* @param orig {@code non-null;} array to duplicate
* @return {@code non-null;} new instance
*/
}
/**
- * Returns true if a and b are equal or are both null
-
+ * Returns true if a and b are equal or are both null.
+ *
* @param a null-ok
* @param b null-ok
* @return Returns true if a and b are equal or are both null
private final SsaBasicBlock block;
/**
- * {@code non-null;} indexed by old register name. The current top of the
- * version stack as seen by this block. It's initialized from
- * the ending state of its dom parent, updated as the block's
- * instructions are processed, and then copied to each one of its
- * dom children.
+ * {@code non-null;} indexed by old register name. The current
+ * top of the version stack as seen by this block. It's
+ * initialized from the ending state of its dom parent,
+ * updated as the block's instructions are processed, and then
+ * copied to each one of its dom children.
*/
private final RegisterSpec[] currentMapping;
/**
- * Contains the set of moves we need to keep
- * to preserve local var info. All other moves will be deleted.
+ * contains the set of moves we need to keep to preserve local
+ * var info. All other moves will be deleted.
*/
private final HashSet<SsaInsn> movesToKeep;
/**
- * Maps the set of insns to replace after renaming is finished
+ * maps the set of insns to replace after renaming is finished
* on the block.
*/
private final HashMap<SsaInsn, SsaInsn> insnsToReplace;
* as the current block's instructions are processed.
*/
private class RenamingMapper extends RegisterMapper {
-
- RenamingMapper() {
+ public RenamingMapper() {
+ // This space intentionally left blank.
}
/** {@inheritDoc} */
int reg = registerSpec.getReg();
- // for debugging: assert that the mapped types are compatible
+ // For debugging: assert that the mapped types are compatible.
if (DEBUG) {
RegisterSpec newVersion = currentMapping[reg];
if (newVersion.getBasicType() != Type.BT_VOID
updateSuccessorPhis();
- // Delete all move insns in this block
+ // Delete all move insns in this block.
ArrayList<SsaInsn> insns = block.getInsns();
int szInsns = insns.size();
replaceInsn = insnsToReplace.get(insn);
if (replaceInsn != null) {
- insns.set(i, replaceInsn);
+ insns.set(i, replaceInsn);
} else if (insn.isNormalMoveInsn()
&& !movesToKeep.contains(insn)) {
insns.remove(i);
}
}
- // Store the start states for our dom children
+ // Store the start states for our dom children.
boolean first = true;
for (SsaBasicBlock child : block.getDomChildren()) {
if (child != block) {
- RegisterSpec[] childStart;
-
- // don't bother duplicating the array for the first child
- childStart = first ? currentMapping
- : dupArray(currentMapping);
+ // Don't bother duplicating the array for the first child.
+ RegisterSpec[] childStart = first ? currentMapping
+ : dupArray(currentMapping);
startsForBlocks[child.getIndex()] = childStart;
first = false;
}
}
- // currentMapping is owned by a child now
+ // currentMapping is owned by a child now.
}
/**
}
}
- // All further steps are for registers with local information
+ // All further steps are for registers with local information.
if (ssaRegLocal == null) {
return;
}
- // Record that this SSA reg has been associated with a local
+ // Record that this SSA reg has been associated with a local.
setNameForSsaReg(ssaReg);
- // Ensure that no other SSA regs are associated with this local
+ // Ensure that no other SSA regs are associated with this local.
for (int i = currentMapping.length - 1; i >= 0; i--) {
RegisterSpec cur = currentMapping[i];
* {@inheritDoc}
*
* Phi insns have their result registers renamed.
- * */
+ */
public void visitPhiInsn(PhiInsn phi) {
/* don't process sources for phi's */
processResultReg(phi);
*/
public void visitMoveInsn(NormalSsaInsn insn) {
/*
- * for moves: copy propogate the move if we can, but don't
+ * For moves: copy propogate the move if we can, but don't
* if we need to preserve local variable info and the
* result has a different name than the source.
*/
insn.mapSourceRegisters(mapper);
int ssaSourceReg = insn.getSources().get(0).getReg();
- LocalItem sourceLocal = currentMapping[ropSourceReg].getLocalItem();
+ LocalItem sourceLocal
+ = currentMapping[ropSourceReg].getLocalItem();
LocalItem resultLocal = ropResult.getLocalItem();
/*
*/
LocalItem newLocal
- = (resultLocal == null) ? sourceLocal : resultLocal;
-
+ = (resultLocal == null) ? sourceLocal : resultLocal;
LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);
- // If we take the new local, will only one local have ever
- // been associated with this SSA reg?
+ /*
+ * If we take the new local, will only one local have ever
+ * been associated with this SSA reg?
+ */
boolean onlyOneAssociatedLocal
= associatedLocal == null || newLocal == null
|| newLocal.equals(associatedLocal);
-
+
/*
- * If we're going to copy-propogate, then the ssa register spec
- * that's going to go into the mapping is made up of the
- * source register number mapped from above, the type
+ * If we're going to copy-propogate, then the ssa register
+ * spec that's going to go into the mapping is made up of
+ * the source register number mapped from above, the type
* of the result, and the name either from the result (if
* specified) or inherited from the existing mapping.
*
- * The move source has incomplete type information
- * in null object cases, so the result type is used.
+ * The move source has incomplete type information in null
+ * object cases, so the result type is used.
*/
RegisterSpec ssaReg
= RegisterSpec.makeLocalOptional(
addMapping(ropResultReg, ssaReg);
} else if (onlyOneAssociatedLocal && sourceLocal == null) {
-
/*
* The register was previously unnamed. This means that a
* local starts after it's first assignment in SSA form
*/
- RegisterSpecList ssaSources;
-
- ssaSources = RegisterSpecList.make(
+ RegisterSpecList ssaSources = RegisterSpecList.make(
RegisterSpec.make(ssaReg.getReg(),
ssaReg.getType(), newLocal));
insnsToReplace.put(insn, newInsn);
- // Just map as above
+ // Just map as above.
addMapping(ropResultReg, ssaReg);
} else {
/*
- * Do not copy-propogate, since the two registers
- * have two different local-variable names
+ * Do not copy-propogate, since the two registers have
+ * two different local-variable names.
*/
processResultReg(insn);
ropReg = insn.getRopResultReg();
/*
- * Never add a version 0 register as a phi operand.
- * Version 0 registers represent the initial register state,
- * and thus are never significant. Furthermore,
- * the register liveness algorithm doesn't properly
- * count them as "live in" at the beginning of the method.
+ * Never add a version 0 register as a phi
+ * operand. Version 0 registers represent the
+ * initial register state, and thus are never
+ * significant. Furthermore, the register liveness
+ * algorithm doesn't properly count them as "live
+ * in" at the beginning of the method.
*/
RegisterSpec stackTop = currentMapping[ropReg];
/** Register mapper which will be our result */
private final InterferenceRegisterMapper mapper;
- /** end of rop registers range (starting at 0) reserved for parameters. */
+ /** end of rop registers range (starting at 0) reserved for parameters */
private final int paramRangeEnd;
- /** set of Rop registers reserved for parameters or local variables. */
+ /** set of rop registers reserved for parameters or local variables */
private final BitSet reservedRopRegs;
- /** set of Rop registers that have been used by anything.*/
+ /** set of rop registers that have been used by anything */
private final BitSet usedRopRegs;
- /** true if converter should take steps to minimize rop-form registers*/
+ /** true if converter should take steps to minimize rop-form registers */
private final boolean minimizeRegisters;
/**
if (DEBUG) System.out.println("--->Mapping invoke-range");
handleInvokeRangeInsns();
-
+
if (DEBUG) {
System.out.println("--->Mapping local-associated non-params");
}
}
/**
- * Maps all local-associated parameters to Rop registers.
+ * Maps all local-associated parameters to rop registers.
*/
private void handleLocalAssociatedParams() {
for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
int paramIndex = -1;
int paramCategory = 0;
- // First, find out if this local variable is a parameter
+ // First, find out if this local variable is a parameter.
for (int i = 0; i < sz; i++) {
RegisterSpec ssaSpec = ssaRegs.get(i);
int ssaReg = ssaSpec.getReg();
}
if (paramIndex < 0) {
- // this local wasn't a parameter
+ // This local wasn't a parameter.
continue;
}
- // Any remaining local-associated registers will be mapped later
+ // Any remaining local-associated registers will be mapped later.
tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
}
}
/**
* Gets the parameter index for SSA registers that are method parameters.
- * -1 is returned for non-parameter registers.
+ * {@code -1} is returned for non-parameter registers.
*
* @param ssaReg {@code >=0;} SSA register to look up
- * @return parameter index or -1 if not a parameter
+ * @return parameter index or {@code -1} if not a parameter
*/
private int getParameterIndexForReg(int ssaReg) {
SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);
if (defInsn == null) {
return -1;
}
-
+
Rop opcode = defInsn.getOpcode();
- // opcode == null for phi insns
+ // opcode == null for phi insns.
if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {
CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();
return ((CstInteger) origInsn.getConstant()).getValue();
}
/**
- * Maps all local-associated registers that are not parameters.
+ * Maps all local-associated registers that are not parameters.
* Tries to find an unreserved range that's wide enough for all of
* the SSA registers, and then tries to map them all to that
* range. If not all fit, a new range is tried until all registers
do {
int maxCategory = 1;
- // compute max category for remaining unmapped registers
+ // Compute max category for remaining unmapped registers.
int sz = specs.size();
for (int i = 0; i < sz; i++) {
RegisterSpec ssaSpec = specs.get(i);
done = tryMapRegs(specs, ropReg, maxCategory, true);
- // Increment for next call to findNext
+ // Increment for next call to findNext.
ropReg++;
} while (!done);
}
*
* @param specs {@code non-null;} SSA registers to attempt to map
* @param ropReg {@code >=0;} rop register to map to
- * @param maxAllowedCategory 1 or 2, maximum category allowed in mapping.
- * @param markReserved do so if true
- * @return true if all registers wew mapped, false if some remain unmapped.
+ * @param maxAllowedCategory {@code 1..2;} maximum category
+ * allowed in mapping.
+ * @param markReserved do so if {@code true}
+ * @return {@code true} if all registers were mapped, {@code false}
+ * if some remain unmapped
*/
private boolean tryMapRegs(
ArrayList<RegisterSpec> specs, int ropReg,
*
* @param ssaSpec {@code non-null;} SSA register
* @param ropReg {@code >=0;} rop register
- * @param maxAllowedCategory 1 or 2, the maximum category that the SSA
- * register is allowed to be.
- * @return true if map succeeded, false if not.
+ * @param maxAllowedCategory {@code 1..2;} the maximum category
+ * that the SSA register is allowed to be
+ * @return {@code true} if map succeeded, {@code false} if not
*/
private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,
int maxAllowedCategory) {
}
/**
- * Marks a range of Rop registers as "reserved for a local variable"
+ * Marks a range of rop registers as "reserved for a local variable."
*
* @param ropReg {@code >= 0;} rop register to reserve
* @param category {@code > 0;} width to reserve
}
/**
- * Checks to see if any Rop registers in the specified range are reserved
- * for local variables or parameters
+ * Checks to see if any rop registers in the specified range are reserved
+ * for local variables or parameters.
*
- * @param ropRangeStart {@code >= 0;} lowest Rop register
- * @param width {@code > 0;} number of Rop registers in range.
- * @return true if any register in range is marked reserved
+ * @param ropRangeStart {@code >= 0;} lowest rop register
+ * @param width {@code > 0;} number of rop registers in range.
+ * @return {@code true} if any register in range is marked reserved
*/
private boolean rangeContainsReserved(int ropRangeStart, int width) {
for (int i = ropRangeStart; i < (ropRangeStart + width); i++) {
}
/**
- * Returns true if given rop register represents the "this" pointer
- * for a non-static method
+ * Returns true if given rop register represents the {@code this} pointer
+ * for a non-static method.
*
* @param startReg rop register
* @return true if the "this" pointer is located here.
*/
private boolean isThisPointerReg(int startReg) {
- // "this" is always the first parameter
+ // "this" is always the first parameter.
return startReg == 0 && !ssaMeth.isStatic();
}
/**
- * Finds a range of unreserved Rop registers.
+ * Finds a range of unreserved rop registers.
*
- * @param startReg {@code >= 0;} a Rop register to start the search at
+ * @param startReg {@code >= 0;} a rop register to start the search at
* @param width {@code > 0;} the width, in registers, required.
* @return {@code >= 0;} start of available register range.
*/
/**
* Finds a range of rop regs that can be used for local variables.
- * If {@code MIX_LOCALS_AND_OTHER} is false, this means any
+ * If {@code MIX_LOCALS_AND_OTHER} is {@code false}, this means any
* rop register that has not yet been used.
*
- * @param startReg {@code >= 0;} a Rop register to start the search at
+ * @param startReg {@code >= 0;} a rop register to start the search at
* @param width {@code > 0;} the width, in registers, required.
* @return {@code >= 0;} start of available register range.
*/
RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);
if (paramIndex >= 0) {
addMapping(ssaSpec, paramIndex);
- }
+ }
}
}
}
/**
- * Handles check cast results to reuse the same source register if possible
+ * Handles check cast results to reuse the same source register if
+ * possible.
*/
private void handleCheckCastResults() {
for (NormalSsaInsn insn : moveResultPseudoInsns) {
}
/**
- * Maps all non-parameter, non-local variable
- * registers.
+ * Maps all non-parameter, non-local variable registers.
*/
private void handleNormalUnassociated() {
int szSsaRegs = ssaMeth.getRegCount();
*
* @param ssaSpec {@code non-null;} SSA spec
* @param ropReg prosepctive new-namespace reg
- * @return true if mapping is possible
+ * @return {@code true} if mapping is possible
*/
private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {
int category = ssaSpec.getCategory();
return !(spansParamRange(ropReg, category)
|| mapper.interferes(ssaSpec, ropReg));
}
-
+
/**
- * Returns true if the specified Rop register + category
+ * Returns true if the specified rop register + category
* will cross the boundry between the lower {@code paramWidth}
* registers reserved for method params and the upper registers. We cannot
* allocate a register that spans the param block and the normal block,
* because we will be moving the param block to high registers later.
- *
+ *
* @param ssaReg register in new namespace
* @param category width that the register will have
- * @return true in the case noted above.
+ * @return {@code true} in the case noted above
*/
private boolean spansParamRange(int ssaReg, int category) {
return ((ssaReg < paramRangeEnd)
/**
* This method collects three types of instructions:
+ *
* 1) Adds a local variable assignment to the
* {@code localVariables} map.
* 2) Add move-result-pseudo to the
}
/**
- * Adds a mapping from an SSA register to a Rop register.
+ * Adds a mapping from an SSA register to a rop register.
* {@link #canMapReg} should have already been called.
*
* @param ssaSpec {@code non-null;} SSA register to map from
- * @param ropReg {@code >=0;} Rop register to map to
+ * @param ropReg {@code >=0;} rop register to map to
*/
private void addMapping(RegisterSpec ssaSpec, int ropReg) {
int ssaReg = ssaSpec.getReg();
- // An assertion
+ // An assertion.
if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) {
throw new RuntimeException(
"attempt to add invalid register mapping");
/**
* Maps the source registers of the specified instruction such that they
- * will fall in a contiguous range in Rop form. Moves are inserted as
+ * will fall in a contiguous range in rop form. Moves are inserted as
* necessary to allow the range to be allocated.
*
* @param insn {@code non-null;} insn whos sources to process
int szSimilar = similarRegisters.size();
- // Try to map all SSA registers also associated with this local
+ /*
+ * Try to map all SSA registers also associated with
+ * this local.
+ */
for (int j = 0; j < szSimilar; j++) {
RegisterSpec similarSpec = similarRegisters.get(j);
int similarReg = similarSpec.getReg();
- // ...and don't map anything that's also a source...
+ // Don't map anything that's also a source.
if (-1 != sources.indexOfRegister(similarReg)) {
continue;
}
- // Registers left unmapped will get handled later
+ // Registers left unmapped will get handled later.
tryMapReg(similarSpec, curRopReg, category);
}
}
/**
* Find a contiguous rop register range that fits the specified
* instruction's sources. First, try to center the range around
- * sources that have already been mapped to Rop registers. If that fails,
+ * sources that have already been mapped to rop registers. If that fails,
* just find a new contiguous range that doesn't interfere.
- *
+ *
* @param insn {@code non-null;} the insn whose sources need to
* fit. Must be last insn in basic block.
* @return {@code >= 0;} rop register of start of range
rangeLength += categoriesForIndex[i];
}
- // The highest score of fits tried so far
+ // the highest score of fits tried so far
int maxScore = Integer.MIN_VALUE;
// the high scoring range's start
int resultRangeStart = -1;
/*
* First, go through each source that's already been mapped. Try
- * to center the range around the Rop register this source is mapped
+ * to center the range around the rop register this source is mapped
* to.
*/
int rangeStartOffset = 0;
}
/*
- * Now, insert any moves required
+ * Now, insert any moves required.
*/
for (int i = resultMovesRequired.nextSetBit(0); i >= 0;
* around an already-mapped source register;
*
* @param insn {@code non-null;} insn to build range for
- * @param rangeLength {@code >=0;} length required in register units.
+ * @param rangeLength {@code >=0;} length required in register units
* @param categoriesForIndex {@code non-null;} indexed by source index;
- * the category for each source.
+ * the category for each source
* @param outMovesRequired {@code non-null;} an output parameter indexed by
* source index that will contain the set of sources which need
- * moves inserted.
- * @return the rop register that starts the fitting range.
+ * moves inserted
+ * @return the rop register that starts the fitting range
*/
private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength,
int[] categoriesForIndex, BitSet outMovesRequired) {
* @param ropReg {@code >= 0;} rop reg that begins range
* @param insn {@code non-null;} insn to plan range for
* @param categoriesForIndex {@code non-null;} indexed by source index;
- * the category for each source.
+ * the category for each source
* @param outMovesRequired {@code non-null;} an output parameter indexed by
* source index that will contain the set of sources which need
- * moves inserted.
+ * moves inserted
* @return the width of the fit that that does not involve added moves or
- * -1 if "no fit possible"
+ * {@code -1} if "no fit possible"
*/
private int fitPlanForRange(int ropReg, NormalSsaInsn insn,
int[] categoriesForIndex, BitSet outMovesRequired) {
IntSet liveOut = insn.getBlock().getLiveOutRegs();
RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);
- // An SSA reg may only be mapped into a range once
+ // An SSA reg may only be mapped into a range once.
BitSet seen = new BitSet(ssaMeth.getRegCount());
for (int i = 0; i < szSources ; i++) {
if (ssaRegsMapped.get(ssaReg)
&& mapper.oldToNew(ssaReg) == ropReg) {
- // A register already mapped appropriately
+ // This is a register that is already mapped appropriately.
fitWidth += category;
} else if (rangeContainsReserved(ropReg, category)) {
fitWidth = -1;
} else if (!ssaRegsMapped.get(ssaReg)
&& canMapReg(ssaSpec, ropReg)
&& !seen.get(ssaReg)) {
- // A register that can be mapped appropriately
+ // This is a register that can be mapped appropriately.
fitWidth += category;
} else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category)
&& !mapper.areAnyPinned(sources, ropReg, category)) {
/*
- * A source that can be moved
- * We can insert a move as long as:
+ * This is a source that can be moved. We can insert a
+ * move as long as:
+ *
+ * * no SSA register pinned to the desired rop reg
+ * is live out on the block
*
- * - no SSA register pinned to the desired rop reg
- * is live out on the block
- * - no SSA register pinned to desired rop reg is
- * a source of this insn (since this may require
- * overlapping moves, which we can't presently handle)
+ * * no SSA register pinned to desired rop reg is
+ * a source of this insn (since this may require
+ * overlapping moves, which we can't presently handle)
*/
outMovesRequired.set(i);
while (iter.hasNext()) {
result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
}
-
+
return result;
}
/**
- * Gets a local item associated with an ssa register, if one exists
+ * Gets a local item associated with an ssa register, if one exists.
*
* @param ssaReg {@code >= 0;} SSA register
* @return {@code null-ok;} associated local item or null
private final InterferenceGraph interference;
/** block "n" in Appel 19.17 */
- SsaBasicBlock blockN;
+ private SsaBasicBlock blockN;
- /** index of statement {@code s} in {@code blockN}*/
+ /** index of statement {@code s} in {@code blockN} */
private int statementIndex;
- /** the next function to call. one of the four constants below */
- private int nextFunction;
+ /** the next function to call */
+ private NextFunction nextFunction;
- /** constants for nextFunction */
- static final int LIVE_IN_AT_STATEMENT = 1;
- static final int LIVE_OUT_AT_STATEMENT = 2;
- static final int LIVE_OUT_AT_BLOCK = 3;
- static final int DONE = 4;
+ /** constants for {@link #nextFunction} */
+ private static enum NextFunction {
+ LIVE_IN_AT_STATEMENT,
+ LIVE_OUT_AT_STATEMENT,
+ LIVE_OUT_AT_BLOCK,
+ DONE;
+ }
/**
* Runs register liveness algorithm for a method, updating the
* live in/out information in {@code SsaBasicBlock} instances and
* returning an interference graph.
*
- * @param ssaMeth {@code non-null;} Method to process.
+ * @param ssaMeth {@code non-null;} method to process
* @return {@code non-null;} interference graph indexed by SSA
- * registers in both directions.
+ * registers in both directions
*/
public static InterferenceGraph constructInterferenceGraph(
SsaMethod ssaMeth) {
int szRegs = ssaMeth.getRegCount();
-
InterferenceGraph interference = new InterferenceGraph(szRegs);
for (int i = 0; i < szRegs; i++) {
*/
private LivenessAnalyzer(SsaMethod ssaMeth, int reg,
InterferenceGraph interference) {
+ int blocksSz = ssaMeth.getBlocks().size();
+
this.ssaMeth = ssaMeth;
this.regV = reg;
- visitedBlocks = new BitSet(ssaMeth.getBlocks().size());
- liveOutBlocks = new BitSet(ssaMeth.getBlocks().size());
+ visitedBlocks = new BitSet(blocksSz);
+ liveOutBlocks = new BitSet(blocksSz);
this.interference = interference;
}
* serves as the dispatcher instead.
*/
private void handleTailRecursion() {
- while (nextFunction != DONE) {
+ while (nextFunction != NextFunction.DONE) {
switch (nextFunction) {
case LIVE_IN_AT_STATEMENT:
- nextFunction = DONE;
+ nextFunction = NextFunction.DONE;
liveInAtStatement();
break;
case LIVE_OUT_AT_STATEMENT:
- nextFunction = DONE;
+ nextFunction = NextFunction.DONE;
liveOutAtStatement();
break;
case LIVE_OUT_AT_BLOCK:
- nextFunction = DONE;
+ nextFunction = NextFunction.DONE;
liveOutAtBlock();
break;
List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);
for (SsaInsn insn : useList) {
- nextFunction = DONE;
+ nextFunction = NextFunction.DONE;
if (insn instanceof PhiInsn) {
// If s is a phi-function with V as it's ith argument.
phi.predBlocksForReg(regV, ssaMeth)) {
blockN = pred;
- nextFunction = LIVE_OUT_AT_BLOCK;
+ nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
handleTailRecursion();
}
} else {
"insn not found in it's own block");
}
- nextFunction = LIVE_IN_AT_STATEMENT;
+ nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
handleTailRecursion();
}
}
while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {
blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);
liveOutBlocks.clear(nextLiveOutBlock);
- nextFunction = LIVE_OUT_AT_BLOCK;
+ nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
handleTailRecursion();
}
}
// Live out at last statement in blockN
statementIndex = insns.size() - 1;
- nextFunction = LIVE_OUT_AT_STATEMENT;
+ nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
}
}
} else {
// Let s' be the statement preceeding s
statementIndex -= 1;
- nextFunction = LIVE_OUT_AT_STATEMENT;
+ nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
}
}
if (rs != null) {
interference.add(regV, rs.getReg());
}
- nextFunction = LIVE_IN_AT_STATEMENT;
+ nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
}
}