| //===- IteratedDominanceFrontier.cpp - Compute IDF ------------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // Compute iterated dominance frontiers using a linear time algorithm. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Analysis/IteratedDominanceFrontier.h" | |
| #include "llvm/IR/CFG.h" | |
| #include "llvm/IR/Dominators.h" | |
| #include <queue> | |
| namespace llvm { | |
| template <class NodeTy, bool IsPostDom> | |
| void IDFCalculator<NodeTy, IsPostDom>::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. We also augment | |
| // the level with a DFS number to ensure that the blocks are ordered in a | |
| // deterministic way. | |
| typedef std::pair<DomTreeNode *, std::pair<unsigned, unsigned>> | |
| DomTreeNodePair; | |
| typedef std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>, | |
| less_second> IDFPriorityQueue; | |
| IDFPriorityQueue PQ; | |
| DT.updateDFSNumbers(); | |
| for (BasicBlock *BB : *DefBlocks) { | |
| if (DomTreeNode *Node = DT.getNode(BB)) | |
| PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())}); | |
| } | |
| 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.first; | |
| // 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, std::make_pair(SuccLevel, SuccNode->getDFSNumIn()))); | |
| } | |
| for (auto DomChild : *Node) { | |
| if (VisitedWorklist.insert(DomChild).second) | |
| Worklist.push_back(DomChild); | |
| } | |
| } | |
| } | |
| } | |
| template class IDFCalculator<BasicBlock *, false>; | |
| template class IDFCalculator<Inverse<BasicBlock *>, true>; | |
| } |