/** * Creates an exit block and attaches it to the CFG if this method * exits. Methods that never exit will not have an exit block. This * is called after edge-splitting and phi insertion, since the edges * going into the exit block should not be considered in those steps. */ /*package*/ void makeExitBlock() { if (exitBlockIndex >= 0) { throw new RuntimeException("must be called at most once"); } exitBlockIndex = blocks.size(); SsaBasicBlock exitBlock = new SsaBasicBlock(exitBlockIndex, maxLabel++, this); blocks.add(exitBlock); for (SsaBasicBlock block : blocks) { block.exitBlockFixup(exitBlock); } if (exitBlock.getPredecessors().cardinality() == 0) { // In cases where there is no exit... blocks.remove(exitBlockIndex); exitBlockIndex = -1; maxLabel--; } }
/** * The dominators algorithm leaves us knowing who the immediate dominator * is for each node. This sweeps the node list and builds the proper * dominance tree. */ private void buildDomTree() { int szNodes = nodes.size(); for (int i = 0; i < szNodes; i++) { DomInfo info = domInfos[i]; if (info.idom == -1) continue; SsaBasicBlock domParent = nodes.get(info.idom); domParent.addDomChild(nodes.get(i)); } }
/** * "v is live-in at s." */ private void liveInAtStatement() { // if s is the first statement in block N if (statementIndex == 0) { // v is live-in at n blockN.addLiveIn(regV); BitSet preds = blockN.getPredecessors(); liveOutBlocks.or(preds); } else { // Let s' be the statement preceeding s statementIndex -= 1; nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT; } }
/** * "v is live-out at n." */ private void liveOutAtBlock() { if (! visitedBlocks.get(blockN.getIndex())) { visitedBlocks.set(blockN.getIndex()); blockN.addLiveOut(regV); ArrayList<SsaInsn> insns; insns = blockN.getInsns(); // Live out at last statement in blockN statementIndex = insns.size() - 1; nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT; } }
/** * Makes a new basic block for this method, which is empty besides * a single {@code GOTO}. Successors and predecessors are not yet * set. * * @return new block */ public SsaBasicBlock makeNewGotoBlock() { int newIndex = blocks.size(); SsaBasicBlock newBlock = new SsaBasicBlock(newIndex, maxLabel++, this); newBlock.getInsns().add(getGoto(newBlock)); blocks.add(newBlock); return newBlock; }
start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, = entryBlock.getPrimarySuccessor(); = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn);
setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0)); setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult()); if (!checkRegUsed(regsUsedAsSources, insn.getResult())) { Collections.swap(toSchedule, i, insertPlace++); if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
SsaBasicBlock b = ssaBlocks.get(bi); for (SsaInsn insn : b.getInsns()) { RegisterSpec rs = insn.getResult(); ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg); } else { ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);
public void visitPhiInsn(PhiInsn insn) { RegisterSpecList sources = insn.getSources(); RegisterSpec result = insn.getResult(); int sz = sources.size(); for (int i = 0; i < sz; i++) { RegisterSpec source = sources.get(i); SsaBasicBlock predBlock = blocks.get( insn.predBlockIndexForSourcesIndex(i)); predBlock.addMoveToEnd(result, source); } } }
BasicBlock bb = ropBlocks.get(basicBlockIndex); SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent); InsnList ropInsns = bb.getInsns();
succ.addMoveToBeginning(result, source);
start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, = entryBlock.getPrimarySuccessor(); = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn);
/** * "v is live-out at n." */ private void liveOutAtBlock() { if (! visitedBlocks.get(blockN.getIndex())) { visitedBlocks.set(blockN.getIndex()); blockN.addLiveOut(regV); ArrayList<SsaInsn> insns; insns = blockN.getInsns(); // Live out at last statement in blockN statementIndex = insns.size() - 1; nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT; } }
/** * Makes a new basic block for this method, which is empty besides * a single {@code GOTO}. Successors and predecessors are not yet * set. * * @return new block */ public SsaBasicBlock makeNewGotoBlock() { int newIndex = blocks.size(); SsaBasicBlock newBlock = new SsaBasicBlock(newIndex, maxLabel++, this); newBlock.getInsns().add(getGoto(newBlock)); blocks.add(newBlock); return newBlock; }
setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0)); setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult()); if (!checkRegUsed(regsUsedAsSources, insn.getResult())) { Collections.swap(toSchedule, i, insertPlace++); if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
SsaBasicBlock b = ssaBlocks.get(bi); for (SsaInsn insn : b.getInsns()) { RegisterSpec rs = insn.getResult(); ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg); } else { ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);
public void visitPhiInsn(PhiInsn insn) { RegisterSpecList sources = insn.getSources(); RegisterSpec result = insn.getResult(); int sz = sources.size(); for (int i = 0; i < sz; i++) { RegisterSpec source = sources.get(i); SsaBasicBlock predBlock = blocks.get( insn.predBlockIndexForSourcesIndex(i)); predBlock.addMoveToEnd(result, source); } } }
BasicBlock bb = ropBlocks.get(basicBlockIndex); SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent); InsnList ropInsns = bb.getInsns();
succ.addMoveToBeginning(result, source);
start.addInsnToHead( new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, = entryBlock.getPrimarySuccessor(); = entryBlock.insertNewSuccessor(successorBlock); constBlock.replaceLastInsn( new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, = constBlock.insertNewSuccessor(successorBlock); PlainInsn insn = new PlainInsn( result, RegisterSpecList.EMPTY); resultBlock.addInsnToHead(insn);