/// At this point, we're committed to promoting the alloca using IDF's, and the /// standard SSA construction algorithm. Determine which blocks need phi nodes /// and see if we can optimize out some work by avoiding insertion of dead phi /// nodes. void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum, AllocaInfo &Info) { // Unique the set of defining blocks for efficient lookup. SmallPtrSet<BasicBlock *, 32> DefBlocks; DefBlocks.insert(Info.DefiningBlocks.begin(), Info.DefiningBlocks.end()); // Determine which blocks the value is live in. These are blocks which lead // to uses. SmallPtrSet<BasicBlock *, 32> LiveInBlocks; ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks); // Use a priority queue keyed on dominator tree level so that inserted nodes // are handled from the bottom of the dominator tree upwards. typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>, DomTreeNodeCompare> IDFPriorityQueue; IDFPriorityQueue PQ; for (SmallPtrSet<BasicBlock *, 32>::const_iterator I = DefBlocks.begin(), E = DefBlocks.end(); I != E; ++I) { if (DomTreeNode *Node = DT.getNode(*I)) PQ.push(std::make_pair(Node, DomLevels[Node])); } SmallVector<std::pair<unsigned, BasicBlock *>, 32> DFBlocks; SmallPtrSet<DomTreeNode *, 32> Visited; SmallVector<DomTreeNode *, 32> Worklist; while (!PQ.empty()) { DomTreeNodePair RootPair = PQ.top(); PQ.pop(); DomTreeNode *Root = RootPair.first; unsigned RootLevel = RootPair.second; // Walk all dominator tree children of Root, inspecting their CFG edges with // targets elsewhere on the dominator tree. Only targets whose level is at // most Root's level are added to the iterated dominance frontier of the // definition set. Worklist.clear(); Worklist.push_back(Root); while (!Worklist.empty()) { DomTreeNode *Node = Worklist.pop_back_val(); BasicBlock *BB = Node->getBlock(); for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) { DomTreeNode *SuccNode = DT.getNode(*SI); // Quickly skip all CFG edges that are also dominator tree edges instead // of catching them below. if (SuccNode->getIDom() == Node) continue; unsigned SuccLevel = DomLevels[SuccNode]; if (SuccLevel > RootLevel) continue; if (!Visited.insert(SuccNode)) continue; BasicBlock *SuccBB = SuccNode->getBlock(); if (!LiveInBlocks.count(SuccBB)) continue; DFBlocks.push_back(std::make_pair(BBNumbers[SuccBB], SuccBB)); if (!DefBlocks.count(SuccBB)) PQ.push(std::make_pair(SuccNode, SuccLevel)); } for (DomTreeNode::iterator CI = Node->begin(), CE = Node->end(); CI != CE; ++CI) { if (!Visited.count(*CI)) Worklist.push_back(*CI); } } } if (DFBlocks.size() > 1) std::sort(DFBlocks.begin(), DFBlocks.end()); unsigned CurrentVersion = 0; for (unsigned i = 0, e = DFBlocks.size(); i != e; ++i) QueuePhiNode(DFBlocks[i].second, AllocaNum, CurrentVersion); }
void IDFCalculator<NodeTy>::calculate( SmallVectorImpl<BasicBlock *> &PHIBlocks) { // Use a priority queue keyed on dominator tree level so that inserted nodes // are handled from the bottom of the dominator tree upwards. typedef std::pair<DomTreeNode *, unsigned> DomTreeNodePair; typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>, less_second> IDFPriorityQueue; IDFPriorityQueue PQ; for (BasicBlock *BB : *DefBlocks) { if (DomTreeNode *Node = DT.getNode(BB)) PQ.push({Node, Node->getLevel()}); } SmallVector<DomTreeNode *, 32> Worklist; SmallPtrSet<DomTreeNode *, 32> VisitedPQ; SmallPtrSet<DomTreeNode *, 32> VisitedWorklist; while (!PQ.empty()) { DomTreeNodePair RootPair = PQ.top(); PQ.pop(); DomTreeNode *Root = RootPair.first; unsigned RootLevel = RootPair.second; // Walk all dominator tree children of Root, inspecting their CFG edges with // targets elsewhere on the dominator tree. Only targets whose level is at // most Root's level are added to the iterated dominance frontier of the // definition set. Worklist.clear(); Worklist.push_back(Root); VisitedWorklist.insert(Root); while (!Worklist.empty()) { DomTreeNode *Node = Worklist.pop_back_val(); BasicBlock *BB = Node->getBlock(); // Succ is the successor in the direction we are calculating IDF, so it is // successor for IDF, and predecessor for Reverse IDF. for (auto *Succ : children<NodeTy>(BB)) { DomTreeNode *SuccNode = DT.getNode(Succ); // Quickly skip all CFG edges that are also dominator tree edges instead // of catching them below. if (SuccNode->getIDom() == Node) continue; const unsigned SuccLevel = SuccNode->getLevel(); if (SuccLevel > RootLevel) continue; if (!VisitedPQ.insert(SuccNode).second) continue; BasicBlock *SuccBB = SuccNode->getBlock(); if (useLiveIn && !LiveInBlocks->count(SuccBB)) continue; PHIBlocks.emplace_back(SuccBB); if (!DefBlocks->count(SuccBB)) PQ.push(std::make_pair(SuccNode, SuccLevel)); } for (auto DomChild : *Node) { if (VisitedWorklist.insert(DomChild).second) Worklist.push_back(DomChild); } } } }