File indexing completed on 2026-05-10 08:44:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #ifndef LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
0024 #define LLVM_SUPPORT_GENERICITERATEDDOMINANCEFRONTIER_H
0025
0026 #include "llvm/ADT/SmallPtrSet.h"
0027 #include "llvm/ADT/SmallVector.h"
0028 #include "llvm/ADT/iterator_range.h"
0029 #include "llvm/Support/GenericDomTree.h"
0030 #include <queue>
0031
0032 namespace llvm {
0033
0034 namespace IDFCalculatorDetail {
0035
0036
0037
0038
0039 template <class NodeTy, bool IsPostDom> struct ChildrenGetterTy {
0040 using NodeRef = typename GraphTraits<NodeTy *>::NodeRef;
0041 using ChildIteratorType = typename GraphTraits<NodeTy *>::ChildIteratorType;
0042 using range = iterator_range<ChildIteratorType>;
0043
0044 range get(const NodeRef &N);
0045 };
0046
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template <class NodeTy, bool IsPostDom> class IDFCalculatorBase {
0059 public:
0060 using OrderedNodeTy =
0061 std::conditional_t<IsPostDom, Inverse<NodeTy *>, NodeTy *>;
0062 using ChildrenGetterTy =
0063 IDFCalculatorDetail::ChildrenGetterTy<NodeTy, IsPostDom>;
0064
0065 IDFCalculatorBase(DominatorTreeBase<NodeTy, IsPostDom> &DT) : DT(DT) {}
0066
0067 IDFCalculatorBase(DominatorTreeBase<NodeTy, IsPostDom> &DT,
0068 const ChildrenGetterTy &C)
0069 : DT(DT), ChildrenGetter(C) {}
0070
0071
0072
0073
0074
0075
0076 void setDefiningBlocks(const SmallPtrSetImpl<NodeTy *> &Blocks) {
0077 DefBlocks = &Blocks;
0078 }
0079
0080
0081
0082
0083
0084
0085 void setLiveInBlocks(const SmallPtrSetImpl<NodeTy *> &Blocks) {
0086 LiveInBlocks = &Blocks;
0087 useLiveIn = true;
0088 }
0089
0090
0091
0092 void resetLiveInBlocks() {
0093 LiveInBlocks = nullptr;
0094 useLiveIn = false;
0095 }
0096
0097
0098
0099
0100
0101
0102
0103 void calculate(SmallVectorImpl<NodeTy *> &IDFBlocks);
0104
0105 private:
0106 DominatorTreeBase<NodeTy, IsPostDom> &DT;
0107 ChildrenGetterTy ChildrenGetter;
0108 bool useLiveIn = false;
0109 const SmallPtrSetImpl<NodeTy *> *LiveInBlocks;
0110 const SmallPtrSetImpl<NodeTy *> *DefBlocks;
0111 };
0112
0113
0114
0115
0116
0117 namespace IDFCalculatorDetail {
0118
0119 template <class NodeTy, bool IsPostDom>
0120 typename ChildrenGetterTy<NodeTy, IsPostDom>::range
0121 ChildrenGetterTy<NodeTy, IsPostDom>::get(const NodeRef &N) {
0122 using OrderedNodeTy =
0123 typename IDFCalculatorBase<NodeTy, IsPostDom>::OrderedNodeTy;
0124
0125 return children<OrderedNodeTy>(N);
0126 }
0127
0128 }
0129
0130 template <class NodeTy, bool IsPostDom>
0131 void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
0132 SmallVectorImpl<NodeTy *> &IDFBlocks) {
0133
0134
0135
0136
0137 using DomTreeNodePair =
0138 std::pair<DomTreeNodeBase<NodeTy> *, std::pair<unsigned, unsigned>>;
0139 using IDFPriorityQueue =
0140 std::priority_queue<DomTreeNodePair, SmallVector<DomTreeNodePair, 32>,
0141 less_second>;
0142
0143 IDFPriorityQueue PQ;
0144
0145 DT.updateDFSNumbers();
0146
0147 SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
0148 SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedPQ;
0149 SmallPtrSet<DomTreeNodeBase<NodeTy> *, 16> VisitedWorklist;
0150 if (useLiveIn) {
0151 VisitedPQ.reserve(LiveInBlocks->size());
0152 VisitedWorklist.reserve(LiveInBlocks->size());
0153 }
0154
0155 for (NodeTy *BB : *DefBlocks)
0156 if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
0157 PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
0158 VisitedWorklist.insert(Node);
0159 }
0160
0161 while (!PQ.empty()) {
0162 DomTreeNodePair RootPair = PQ.top();
0163 PQ.pop();
0164 DomTreeNodeBase<NodeTy> *Root = RootPair.first;
0165 unsigned RootLevel = RootPair.second.first;
0166
0167
0168
0169
0170
0171
0172 assert(Worklist.empty());
0173 Worklist.push_back(Root);
0174
0175 while (!Worklist.empty()) {
0176 DomTreeNodeBase<NodeTy> *Node = Worklist.pop_back_val();
0177 NodeTy *BB = Node->getBlock();
0178
0179
0180 auto DoWork = [&](NodeTy *Succ) {
0181 DomTreeNodeBase<NodeTy> *SuccNode = DT.getNode(Succ);
0182
0183 const unsigned SuccLevel = SuccNode->getLevel();
0184 if (SuccLevel > RootLevel)
0185 return;
0186
0187 if (!VisitedPQ.insert(SuccNode).second)
0188 return;
0189
0190 NodeTy *SuccBB = SuccNode->getBlock();
0191 if (useLiveIn && !LiveInBlocks->count(SuccBB))
0192 return;
0193
0194 IDFBlocks.emplace_back(SuccBB);
0195 if (!DefBlocks->count(SuccBB))
0196 PQ.push(std::make_pair(
0197 SuccNode, std::make_pair(SuccLevel, SuccNode->getDFSNumIn())));
0198 };
0199
0200 for (auto *Succ : ChildrenGetter.get(BB))
0201 DoWork(Succ);
0202
0203 for (auto DomChild : *Node) {
0204 if (VisitedWorklist.insert(DomChild).second)
0205 Worklist.push_back(DomChild);
0206 }
0207 }
0208 }
0209 }
0210
0211 }
0212
0213 #endif