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_DOMINANCEFRONTIER_H
0018 #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
0019
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/ADT/GraphTraits.h"
0022 #include "llvm/ADT/SetVector.h"
0023 #include "llvm/IR/PassManager.h"
0024 #include "llvm/Pass.h"
0025 #include "llvm/Support/GenericDomTree.h"
0026 #include <cassert>
0027 #include <utility>
0028
0029 namespace llvm {
0030
0031 class BasicBlock;
0032 class Function;
0033 class raw_ostream;
0034
0035
0036
0037
0038
0039 template <class BlockT, bool IsPostDom>
0040 class DominanceFrontierBase {
0041 public:
0042
0043
0044 using DomSetType = SetVector<BlockT *>;
0045 using DomSetMapType = DenseMap<BlockT *, DomSetType>;
0046
0047 protected:
0048 using BlockTraits = GraphTraits<BlockT *>;
0049
0050 DomSetMapType Frontiers;
0051
0052 SmallVector<BlockT *, IsPostDom ? 4 : 1> Roots;
0053 static constexpr bool IsPostDominators = IsPostDom;
0054
0055 public:
0056 DominanceFrontierBase() = default;
0057
0058
0059
0060
0061 const SmallVectorImpl<BlockT *> &getRoots() const { return Roots; }
0062
0063 BlockT *getRoot() const {
0064 assert(Roots.size() == 1 && "Should always have entry node!");
0065 return Roots[0];
0066 }
0067
0068
0069 bool isPostDominator() const {
0070 return IsPostDominators;
0071 }
0072
0073 void releaseMemory() {
0074 Frontiers.clear();
0075 }
0076
0077
0078 using iterator = typename DomSetMapType::iterator;
0079 using const_iterator = typename DomSetMapType::const_iterator;
0080
0081 iterator begin() { return Frontiers.begin(); }
0082 const_iterator begin() const { return Frontiers.begin(); }
0083 iterator end() { return Frontiers.end(); }
0084 const_iterator end() const { return Frontiers.end(); }
0085 iterator find(BlockT *B) { return Frontiers.find(B); }
0086 const_iterator find(BlockT *B) const { return Frontiers.find(B); }
0087
0088
0089
0090 void print(raw_ostream &OS) const;
0091
0092
0093 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0094 void dump() const;
0095 #endif
0096 };
0097
0098
0099
0100
0101
0102 template <class BlockT>
0103 class ForwardDominanceFrontierBase
0104 : public DominanceFrontierBase<BlockT, false> {
0105 private:
0106 using BlockTraits = GraphTraits<BlockT *>;
0107
0108 public:
0109 using DomTreeT = DomTreeBase<BlockT>;
0110 using DomTreeNodeT = DomTreeNodeBase<BlockT>;
0111 using DomSetType = typename DominanceFrontierBase<BlockT, false>::DomSetType;
0112
0113 void analyze(DomTreeT &DT) {
0114 assert(DT.root_size() == 1 &&
0115 "Only one entry block for forward domfronts!");
0116 this->Roots = {DT.getRoot()};
0117 calculate(DT, DT[this->Roots[0]]);
0118 }
0119
0120 const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
0121 };
0122
0123 class DominanceFrontier : public ForwardDominanceFrontierBase<BasicBlock> {
0124 public:
0125 using DomTreeT = DomTreeBase<BasicBlock>;
0126 using DomTreeNodeT = DomTreeNodeBase<BasicBlock>;
0127 using DomSetType = DominanceFrontierBase<BasicBlock, false>::DomSetType;
0128 using iterator = DominanceFrontierBase<BasicBlock, false>::iterator;
0129 using const_iterator =
0130 DominanceFrontierBase<BasicBlock, false>::const_iterator;
0131
0132
0133 bool invalidate(Function &F, const PreservedAnalyses &PA,
0134 FunctionAnalysisManager::Invalidator &);
0135 };
0136
0137 class DominanceFrontierWrapperPass : public FunctionPass {
0138 DominanceFrontier DF;
0139
0140 public:
0141 static char ID;
0142
0143 DominanceFrontierWrapperPass();
0144
0145 DominanceFrontier &getDominanceFrontier() { return DF; }
0146 const DominanceFrontier &getDominanceFrontier() const { return DF; }
0147
0148 void releaseMemory() override;
0149
0150 bool runOnFunction(Function &) override;
0151
0152 void getAnalysisUsage(AnalysisUsage &AU) const override;
0153
0154 void print(raw_ostream &OS, const Module * = nullptr) const override;
0155
0156 void dump() const;
0157 };
0158
0159 extern template class DominanceFrontierBase<BasicBlock, false>;
0160 extern template class DominanceFrontierBase<BasicBlock, true>;
0161 extern template class ForwardDominanceFrontierBase<BasicBlock>;
0162
0163
0164 class DominanceFrontierAnalysis
0165 : public AnalysisInfoMixin<DominanceFrontierAnalysis> {
0166 friend AnalysisInfoMixin<DominanceFrontierAnalysis>;
0167
0168 static AnalysisKey Key;
0169
0170 public:
0171
0172 using Result = DominanceFrontier;
0173
0174
0175 DominanceFrontier run(Function &F, FunctionAnalysisManager &AM);
0176 };
0177
0178
0179 class DominanceFrontierPrinterPass
0180 : public PassInfoMixin<DominanceFrontierPrinterPass> {
0181 raw_ostream &OS;
0182
0183 public:
0184 explicit DominanceFrontierPrinterPass(raw_ostream &OS);
0185
0186 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0187
0188 static bool isRequired() { return true; }
0189 };
0190
0191 }
0192
0193 #endif