private Set<SSA> directBlockLive(Set<SSA> liveJoin, BasicBlock joinBlock, BasicBlock headBlock) { Set<SSA> liveDirectLast = new HashSet<SSA>(); liveDirectLast.addAll(liveJoin); liveDirectLast.addAll(joinBlock.getPhiManager().getPhiDirects()); return buildIGRecursive(headBlock.getDirectSuccessor(), liveDirectLast); }
public Set<SSA> buildIGRecursive(BasicBlock curBB, Set<SSA> liveLast) { if (curBB.getJoinSuccessor() != null && curBB.getDirectSuccessor() != null) { // liveness before the join block BasicBlock joinBlock = curBB.getJoinSuccessor(); Set<SSA> liveJoin = buildIGRecursive(curBB.getJoinSuccessor(), liveLast); this.connectPhiFuncs(liveJoin, joinBlock); // liveness before the else block Set<SSA> liveElseInitial = this.elseBlockLive(liveJoin, joinBlock, curBB); // liveness before the if block Set<SSA> liveDirectInitial = this.directBlockLive(liveJoin, joinBlock, curBB); // merge liveDirect and liveELse liveDirectInitial.addAll(liveElseInitial); // build IG from initial block Set<SSA> liveInitial = buildIGFromBlock(curBB, liveDirectInitial); return liveInitial; } else if (curBB.getDirectSuccessor() != null && curBB.getDirectSuccessor().isLoop()) { BasicBlock loopHead = curBB.getDirectSuccessor(); // liveness before the follow block BasicBlock followBlock = loopHead.getElseSuccessor(); Set<SSA> liveFollow = buildIGRecursive(followBlock, liveLast); // liveness before the loop head Set<SSA> liveLoopHead = buildIGFromBlock(loopHead, new HashSet<SSA>(liveFollow)); this.connectPhiFuncs(liveLoopHead, loopHead); // liveness at the end of loop body Set<SSA> liveLoopBodyInitial = this.loopBodyLive(liveLoopHead, loopHead); // merge liveDirect and liveELse liveLoopBodyInitial.addAll(liveFollow); // liveness before the loop head again Set<SSA> liveLoopHeadNew = buildIGFromBlock(loopHead, liveLoopBodyInitial); this.connectPhiFuncs(liveLoopHeadNew, loopHead); // the block before the loop head Set<SSA> liveBeforeLoop = liveLoopHeadNew; liveBeforeLoop.addAll(loopHead.getPhiManager().getPhiElses()); Set<SSA> liveInitial = buildIGFromBlock(curBB, liveBeforeLoop); return liveInitial; } else { // if recursion reaches a normal block Set<SSA> liveInitial = buildIGFromBlock(curBB, liveLast); return liveInitial; } }
private Set<SSA> elseBlockLive(Set<SSA> liveJoin, BasicBlock joinBlock, BasicBlock headBlock) { if (headBlock.getElseSuccessor() != headBlock.getJoinSuccessor()) { Set<SSA> liveElseLast = new HashSet<SSA>(); liveElseLast.addAll(liveJoin); liveElseLast.addAll(joinBlock.getPhiManager().getPhiElses()); return buildIGRecursive(headBlock.getElseSuccessor(), liveElseLast); } return new HashSet<SSA>(); }
private void connectPhiFuncs(Set<SSA> liveJoin, BasicBlock joinBlock) { for (SSA result : joinBlock.getPhiManager().getPhiResults()) { liveJoin.remove(result); Cluster resultCluster = this.getCluster(result); for (SSA x : liveJoin) { Cluster xCluster = this.getCluster(x); // add edge i <-> x xCluster.connectWith(resultCluster); } } }
private Set<SSA> buildIGFromBlock(BasicBlock curBB, Set<SSA> live) { List<Instruction> instList = curBB.getInstructions(); for (int i = instList.size() - 1; i >= 0; i--) { Instruction inst = instList.get(i); // ignore phi function if (inst.getOperator() == Instruction.phi) { return live; } if (inst.getOperator() == Instruction.subroutine) { live = this.buildIGRecursive(inst.getOperand2().block, live); continue; } List<SSA> results = VariableManager.getSSAsByVersion(inst.getId()); // live = live - {i} live.removeAll(results); live.remove(null); // for all x belong to live do for (SSA result : results) { Cluster resultCluster = this.getCluster(result); for (SSA x : live) { Cluster xCluster = this.getCluster(x); // add edge i <-> x xCluster.connectWith(resultCluster); } } // live = live + {j, k} if (inst.getOperand1() != null) { SSA j = inst.getOperand1().ssa; if (j != null) { live.add(j); } } if (inst.getOperand2() != null) { SSA k = inst.getOperand2().ssa; if (k != null) { live.add(k); } } } return live; }
private void insertSpillCode(Cluster x) { for (int i = 0; i < x.getSSAList().size(); i++) { Instruction assignInst = ControlFlowGraph.getInstruction(x.getSSAList().get(i).getVersion()); BasicBlock blockOfAssign = ControlFlowGraph.findBlockOf(assignInst); Operand storeAddr = Operand.makeConst(spillMemory); if (assignInst.getOperand1().kind == Operand.constant) { Operand temp = Operand.makeReg(25); Instruction store = Instruction.noUseInstruction(Instruction.store, temp, storeAddr); store.setId(assignInst.getId()); blockOfAssign.replaceInst(assignInst, store); Instruction move = Instruction.noUseInstruction(Instruction.move, assignInst.getOperand1(), temp); move.setId(store.getId() - 1); blockOfAssign.insertBefore(store, move); } else { Instruction store = Instruction.noUseInstruction(Instruction.store, assignInst.getOperand1(), storeAddr); store.setId(assignInst.getId()); blockOfAssign.replaceInst(assignInst, store); } for (Operand use : x.getSSAList().get(i).getUseChain()) { Instruction useInst = ControlFlowGraph.getInstruction(use.inst); if (useInst != null && use.inst != x.getSSAList().get(i).getVersion()) { BasicBlock blockOfUse = ControlFlowGraph.findBlockOf(useInst); Operand loadAddr = Operand.makeConst(spillMemory); Operand loadTemp = Operand.makeReg(26); Instruction load = Instruction.noUseInstruction(Instruction.load, loadAddr, loadTemp); blockOfUse.insertBefore(useInst, load); if (useInst.getOperand1() != null && useInst.getOperand1().ssa == x.getSSAList().get(i)) { useInst.setOperand1(loadTemp); } if (useInst.getOperand2() != null && useInst.getOperand2().ssa == x.getSSAList().get(i)) { useInst.setOperand2(loadTemp); } } } } }
private Set<SSA> loopBodyLive(Set<SSA> liveLoopBodyLast, BasicBlock loopHead) { liveLoopBodyLast.addAll(loopHead.getPhiManager().getPhiDirects()); return buildIGRecursive(loopHead.getDirectSuccessor(), liveLoopBodyLast); }