File indexing completed on 2026-05-10 08:44:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_IR_DOMINATORS_H
0015 #define LLVM_IR_DOMINATORS_H
0016
0017 #include "llvm/ADT/APInt.h"
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/ADT/DenseMapInfo.h"
0020 #include "llvm/ADT/DepthFirstIterator.h"
0021 #include "llvm/ADT/Hashing.h"
0022 #include "llvm/ADT/PointerIntPair.h"
0023 #include "llvm/ADT/SmallVector.h"
0024 #include "llvm/ADT/Twine.h"
0025 #include "llvm/ADT/ilist_iterator.h"
0026 #include "llvm/IR/BasicBlock.h"
0027 #include "llvm/IR/CFG.h"
0028 #include "llvm/IR/PassManager.h"
0029 #include "llvm/IR/Use.h"
0030 #include "llvm/Pass.h"
0031 #include "llvm/Support/CFGDiff.h"
0032 #include "llvm/Support/CFGUpdate.h"
0033 #include "llvm/Support/GenericDomTree.h"
0034 #include <algorithm>
0035 #include <utility>
0036
0037 namespace llvm {
0038
0039 class Function;
0040 class Instruction;
0041 class Module;
0042 class Value;
0043 class raw_ostream;
0044 template <class GraphType> struct GraphTraits;
0045
0046 extern template class DomTreeNodeBase<BasicBlock>;
0047 extern template class DominatorTreeBase<BasicBlock, false>;
0048 extern template class DominatorTreeBase<BasicBlock, true>;
0049
0050 extern template class cfg::Update<BasicBlock *>;
0051
0052 namespace DomTreeBuilder {
0053 using BBDomTree = DomTreeBase<BasicBlock>;
0054 using BBPostDomTree = PostDomTreeBase<BasicBlock>;
0055
0056 using BBUpdates = ArrayRef<llvm::cfg::Update<BasicBlock *>>;
0057
0058 using BBDomTreeGraphDiff = GraphDiff<BasicBlock *, false>;
0059 using BBPostDomTreeGraphDiff = GraphDiff<BasicBlock *, true>;
0060
0061 extern template void Calculate<BBDomTree>(BBDomTree &DT);
0062 extern template void CalculateWithUpdates<BBDomTree>(BBDomTree &DT,
0063 BBUpdates U);
0064
0065 extern template void Calculate<BBPostDomTree>(BBPostDomTree &DT);
0066
0067 extern template void InsertEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From,
0068 BasicBlock *To);
0069 extern template void InsertEdge<BBPostDomTree>(BBPostDomTree &DT,
0070 BasicBlock *From,
0071 BasicBlock *To);
0072
0073 extern template void DeleteEdge<BBDomTree>(BBDomTree &DT, BasicBlock *From,
0074 BasicBlock *To);
0075 extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
0076 BasicBlock *From,
0077 BasicBlock *To);
0078
0079 extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
0080 BBDomTreeGraphDiff &,
0081 BBDomTreeGraphDiff *);
0082 extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
0083 BBPostDomTreeGraphDiff &,
0084 BBPostDomTreeGraphDiff *);
0085
0086 extern template bool Verify<BBDomTree>(const BBDomTree &DT,
0087 BBDomTree::VerificationLevel VL);
0088 extern template bool Verify<BBPostDomTree>(const BBPostDomTree &DT,
0089 BBPostDomTree::VerificationLevel VL);
0090 }
0091
0092 using DomTreeNode = DomTreeNodeBase<BasicBlock>;
0093
0094 class BasicBlockEdge {
0095 const BasicBlock *Start;
0096 const BasicBlock *End;
0097
0098 public:
0099 BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
0100 Start(Start_), End(End_) {}
0101
0102 BasicBlockEdge(const std::pair<BasicBlock *, BasicBlock *> &Pair)
0103 : Start(Pair.first), End(Pair.second) {}
0104
0105 BasicBlockEdge(const std::pair<const BasicBlock *, const BasicBlock *> &Pair)
0106 : Start(Pair.first), End(Pair.second) {}
0107
0108 const BasicBlock *getStart() const {
0109 return Start;
0110 }
0111
0112 const BasicBlock *getEnd() const {
0113 return End;
0114 }
0115
0116
0117 bool isSingleEdge() const;
0118 };
0119
0120 template <> struct DenseMapInfo<BasicBlockEdge> {
0121 using BBInfo = DenseMapInfo<const BasicBlock *>;
0122
0123 static unsigned getHashValue(const BasicBlockEdge *V);
0124
0125 static inline BasicBlockEdge getEmptyKey() {
0126 return BasicBlockEdge(BBInfo::getEmptyKey(), BBInfo::getEmptyKey());
0127 }
0128
0129 static inline BasicBlockEdge getTombstoneKey() {
0130 return BasicBlockEdge(BBInfo::getTombstoneKey(), BBInfo::getTombstoneKey());
0131 }
0132
0133 static unsigned getHashValue(const BasicBlockEdge &Edge) {
0134 return hash_combine(BBInfo::getHashValue(Edge.getStart()),
0135 BBInfo::getHashValue(Edge.getEnd()));
0136 }
0137
0138 static bool isEqual(const BasicBlockEdge &LHS, const BasicBlockEdge &RHS) {
0139 return BBInfo::isEqual(LHS.getStart(), RHS.getStart()) &&
0140 BBInfo::isEqual(LHS.getEnd(), RHS.getEnd());
0141 }
0142 };
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
0163 public:
0164 using Base = DominatorTreeBase<BasicBlock, false>;
0165
0166 DominatorTree() = default;
0167 explicit DominatorTree(Function &F) { recalculate(F); }
0168 explicit DominatorTree(DominatorTree &DT, DomTreeBuilder::BBUpdates U) {
0169 recalculate(*DT.Parent, U);
0170 }
0171
0172
0173 bool invalidate(Function &F, const PreservedAnalyses &PA,
0174 FunctionAnalysisManager::Invalidator &);
0175
0176
0177 using Base::dominates;
0178
0179
0180 bool dominates(const BasicBlock *BB, const Use &U) const;
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 bool dominates(const Value *Def, const Use &U) const;
0192
0193
0194
0195 bool dominates(const Value *Def, const Instruction *User) const;
0196 bool dominates(const Value *Def, BasicBlock::iterator User) const {
0197 return dominates(Def, &*User);
0198 }
0199
0200
0201
0202
0203
0204
0205 bool dominates(const Instruction *Def, const BasicBlock *BB) const;
0206
0207
0208
0209
0210
0211 bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
0212 bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
0213
0214 bool dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const;
0215
0216
0217 using Base::isReachableFromEntry;
0218
0219
0220 bool isReachableFromEntry(const Use &U) const;
0221
0222
0223 using Base::findNearestCommonDominator;
0224
0225
0226
0227 Instruction *findNearestCommonDominator(Instruction *I1,
0228 Instruction *I2) const;
0229
0230
0231 void viewGraph(const Twine &Name, const Twine &Title);
0232 void viewGraph();
0233 };
0234
0235
0236
0237
0238
0239 template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase {
0240 using NodeRef = Node *;
0241 using ChildIteratorType = ChildIterator;
0242 using nodes_iterator = df_iterator<Node *, df_iterator_default_set<Node*>>;
0243
0244 static NodeRef getEntryNode(NodeRef N) { return N; }
0245 static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
0246 static ChildIteratorType child_end(NodeRef N) { return N->end(); }
0247
0248 static nodes_iterator nodes_begin(NodeRef N) {
0249 return df_begin(getEntryNode(N));
0250 }
0251
0252 static nodes_iterator nodes_end(NodeRef N) { return df_end(getEntryNode(N)); }
0253 };
0254
0255 template <>
0256 struct GraphTraits<DomTreeNode *>
0257 : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::const_iterator> {
0258 };
0259
0260 template <>
0261 struct GraphTraits<const DomTreeNode *>
0262 : public DomTreeGraphTraitsBase<const DomTreeNode,
0263 DomTreeNode::const_iterator> {};
0264
0265 template <> struct GraphTraits<DominatorTree*>
0266 : public GraphTraits<DomTreeNode*> {
0267 static NodeRef getEntryNode(DominatorTree *DT) { return DT->getRootNode(); }
0268
0269 static nodes_iterator nodes_begin(DominatorTree *N) {
0270 return df_begin(getEntryNode(N));
0271 }
0272
0273 static nodes_iterator nodes_end(DominatorTree *N) {
0274 return df_end(getEntryNode(N));
0275 }
0276 };
0277
0278
0279 class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> {
0280 friend AnalysisInfoMixin<DominatorTreeAnalysis>;
0281 static AnalysisKey Key;
0282
0283 public:
0284
0285 using Result = DominatorTree;
0286
0287
0288 DominatorTree run(Function &F, FunctionAnalysisManager &);
0289 };
0290
0291
0292 class DominatorTreePrinterPass
0293 : public PassInfoMixin<DominatorTreePrinterPass> {
0294 raw_ostream &OS;
0295
0296 public:
0297 explicit DominatorTreePrinterPass(raw_ostream &OS);
0298
0299 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0300
0301 static bool isRequired() { return true; }
0302 };
0303
0304
0305 struct DominatorTreeVerifierPass : PassInfoMixin<DominatorTreeVerifierPass> {
0306 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0307 static bool isRequired() { return true; }
0308 };
0309
0310
0311
0312
0313
0314 extern bool VerifyDomInfo;
0315
0316
0317 class DominatorTreeWrapperPass : public FunctionPass {
0318 DominatorTree DT;
0319
0320 public:
0321 static char ID;
0322
0323 DominatorTreeWrapperPass();
0324
0325 DominatorTree &getDomTree() { return DT; }
0326 const DominatorTree &getDomTree() const { return DT; }
0327
0328 bool runOnFunction(Function &F) override;
0329
0330 void verifyAnalysis() const override;
0331
0332 void getAnalysisUsage(AnalysisUsage &AU) const override {
0333 AU.setPreservesAll();
0334 }
0335
0336 void releaseMemory() override { DT.reset(); }
0337
0338 void print(raw_ostream &OS, const Module *M = nullptr) const override;
0339 };
0340 }
0341
0342 #endif