| //===- 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>; |
| } |