File indexing completed on 2026-05-10 08:43:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
0018 #define LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
0019
0020 #include "llvm/ADT/SmallPtrSet.h"
0021 #include "llvm/Analysis/DominanceFrontier.h"
0022 #include "llvm/Config/llvm-config.h"
0023 #include "llvm/Support/Debug.h"
0024 #include "llvm/Support/GenericDomTree.h"
0025 #include "llvm/Support/raw_ostream.h"
0026 #include <cassert>
0027 #include <set>
0028 #include <utility>
0029 #include <vector>
0030
0031 namespace llvm {
0032
0033 template <class BlockT>
0034 class DFCalculateWorkObject {
0035 public:
0036 using DomTreeNodeT = DomTreeNodeBase<BlockT>;
0037
0038 DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
0039 const DomTreeNodeT *PN)
0040 : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
0041
0042 BlockT *currentBB;
0043 BlockT *parentBB;
0044 const DomTreeNodeT *Node;
0045 const DomTreeNodeT *parentNode;
0046 };
0047
0048 template <class BlockT, bool IsPostDom>
0049 void DominanceFrontierBase<BlockT, IsPostDom>::print(raw_ostream &OS) const {
0050 for (const_iterator I = begin(), E = end(); I != E; ++I) {
0051 OS << " DomFrontier for BB ";
0052 if (I->first)
0053 I->first->printAsOperand(OS, false);
0054 else
0055 OS << " <<exit node>>";
0056 OS << " is:\t";
0057
0058 const SetVector<BlockT *> &BBs = I->second;
0059
0060 for (const BlockT *BB : BBs) {
0061 OS << ' ';
0062 if (BB)
0063 BB->printAsOperand(OS, false);
0064 else
0065 OS << "<<exit node>>";
0066 }
0067 OS << '\n';
0068 }
0069 }
0070
0071 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0072 template <class BlockT, bool IsPostDom>
0073 void DominanceFrontierBase<BlockT, IsPostDom>::dump() const {
0074 print(dbgs());
0075 }
0076 #endif
0077
0078 template <class BlockT>
0079 const typename ForwardDominanceFrontierBase<BlockT>::DomSetType &
0080 ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT,
0081 const DomTreeNodeT *Node) {
0082 BlockT *BB = Node->getBlock();
0083 DomSetType *Result = nullptr;
0084
0085 std::vector<DFCalculateWorkObject<BlockT>> workList;
0086 SmallPtrSet<BlockT *, 32> visited;
0087
0088 workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr));
0089 do {
0090 DFCalculateWorkObject<BlockT> *currentW = &workList.back();
0091 assert(currentW && "Missing work object.");
0092
0093 BlockT *currentBB = currentW->currentBB;
0094 BlockT *parentBB = currentW->parentBB;
0095 const DomTreeNodeT *currentNode = currentW->Node;
0096 const DomTreeNodeT *parentNode = currentW->parentNode;
0097 assert(currentBB && "Invalid work object. Missing current Basic Block");
0098 assert(currentNode && "Invalid work object. Missing current Node");
0099 DomSetType &S = this->Frontiers[currentBB];
0100
0101
0102 if (visited.insert(currentBB).second) {
0103
0104 for (const auto Succ : children<BlockT *>(currentBB)) {
0105
0106 if (DT[Succ]->getIDom() != currentNode)
0107 S.insert(Succ);
0108 }
0109 }
0110
0111
0112
0113
0114 bool visitChild = false;
0115 for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
0116 NE = currentNode->end();
0117 NI != NE; ++NI) {
0118 DomTreeNodeT *IDominee = *NI;
0119 BlockT *childBB = IDominee->getBlock();
0120 if (visited.count(childBB) == 0) {
0121 workList.push_back(DFCalculateWorkObject<BlockT>(
0122 childBB, currentBB, IDominee, currentNode));
0123 visitChild = true;
0124 }
0125 }
0126
0127
0128
0129 if (!visitChild) {
0130 if (!parentBB) {
0131 Result = &S;
0132 break;
0133 }
0134
0135 typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
0136 DomSetType &parentSet = this->Frontiers[parentBB];
0137 for (; CDFI != CDFE; ++CDFI) {
0138 if (!DT.properlyDominates(parentNode, DT[*CDFI]))
0139 parentSet.insert(*CDFI);
0140 }
0141 workList.pop_back();
0142 }
0143
0144 } while (!workList.empty());
0145
0146 return *Result;
0147 }
0148
0149 }
0150
0151 #endif