/// Take one node from the order vector and wire it up void StructurizeCFG::wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd) { RegionNode *Node = Order.pop_back_val(); Visited.insert(Node->getEntry()); if (isPredictableTrue(Node)) { // Just a linear flow if (PrevNode) { changeExit(PrevNode, Node->getEntry(), true); } PrevNode = Node; } else { // Insert extra prefix node (or reuse last one) BasicBlock *Flow = needPrefix(false); // Insert extra postfix node (or use exit instead) BasicBlock *Entry = Node->getEntry(); BasicBlock *Next = needPostfix(Flow, ExitUseAllowed); // let it point to entry and next block Conditions.push_back(BranchInst::Create(Entry, Next, BoolUndef, Flow)); addPhiValues(Flow, Entry); DT->changeImmediateDominator(Entry, Flow); PrevNode = Node; while (!Order.empty() && !Visited.count(LoopEnd) && dominatesPredicates(Entry, Order.back())) { handleLoops(false, LoopEnd); } changeExit(PrevNode, Next, false); setPrevNode(Next); } }
void StructurizeCFG::handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd) { RegionNode *Node = Order.front(); BasicBlock *LoopStart = Node->getEntry(); if (!Loops.count(LoopStart)) { wireFlow(ExitUseAllowed, LoopEnd); return; } if (!isPredictableTrue(Node)) LoopStart = needPrefix(true); LoopEnd = Loops[Node->getEntry()]; wireFlow(false, LoopEnd); while (!Visited.count(LoopEnd)) { handleLoops(false, LoopEnd); } // If the start of the loop is the entry block, we can't branch to it so // insert a new dummy entry block. Function *LoopFunc = LoopStart->getParent(); if (LoopStart == &LoopFunc->getEntryBlock()) { LoopStart->setName("entry.orig"); BasicBlock *NewEntry = BasicBlock::Create(LoopStart->getContext(), "entry", LoopFunc, LoopStart); BranchInst::Create(LoopStart, NewEntry); DT->setNewRoot(NewEntry); } // Create an extra loop end node LoopEnd = needPrefix(false); BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed); LoopConds.push_back(BranchInst::Create(Next, LoopStart, BoolUndef, LoopEnd)); addPhiValues(LoopEnd, LoopStart); setPrevNode(Next); }