Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===- Dominators.h - Dominator Info Calculation ----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the DominatorTree class, which provides fast and efficient
0010 // dominance queries.
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>; // DomTree
0048 extern template class DominatorTreeBase<BasicBlock, true>; // PostDomTree
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 }  // namespace DomTreeBuilder
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   /// Check if this is the only edge between Start and End.
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 /// Concrete subclass of DominatorTreeBase that is used to compute a
0145 /// normal dominator tree.
0146 ///
0147 /// Definition: A block is said to be forward statically reachable if there is
0148 /// a path from the entry of the function to the block.  A statically reachable
0149 /// block may become statically unreachable during optimization.
0150 ///
0151 /// A forward unreachable block may appear in the dominator tree, or it may
0152 /// not.  If it does, dominance queries will return results as if all reachable
0153 /// blocks dominate it.  When asking for a Node corresponding to a potentially
0154 /// unreachable block, calling code must handle the case where the block was
0155 /// unreachable and the result of getNode() is nullptr.
0156 ///
0157 /// Generally, a block known to be unreachable when the dominator tree is
0158 /// constructed will not be in the tree.  One which becomes unreachable after
0159 /// the dominator tree is initially constructed may still exist in the tree,
0160 /// even if the tree is properly updated. Calling code should not rely on the
0161 /// preceding statements; this is stated only to assist human understanding.
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   /// Handle invalidation explicitly.
0173   bool invalidate(Function &F, const PreservedAnalyses &PA,
0174                   FunctionAnalysisManager::Invalidator &);
0175 
0176   // Ensure base-class overloads are visible.
0177   using Base::dominates;
0178 
0179   /// Return true if the (end of the) basic block BB dominates the use U.
0180   bool dominates(const BasicBlock *BB, const Use &U) const;
0181 
0182   /// Return true if value Def dominates use U, in the sense that Def is
0183   /// available at U, and could be substituted as the used value without
0184   /// violating the SSA dominance requirement.
0185   ///
0186   /// In particular, it is worth noting that:
0187   ///  * Non-instruction Defs dominate everything.
0188   ///  * Def does not dominate a use in Def itself (outside of degenerate cases
0189   ///    like unreachable code or trivial phi cycles).
0190   ///  * Invoke Defs only dominate uses in their default destination.
0191   bool dominates(const Value *Def, const Use &U) const;
0192 
0193   /// Return true if value Def dominates all possible uses inside instruction
0194   /// User. Same comments as for the Use-based API apply.
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   /// Returns true if Def would dominate a use in any instruction in BB.
0201   /// If Def is an instruction in BB, then Def does not dominate BB.
0202   ///
0203   /// Does not accept Value to avoid ambiguity with dominance checks between
0204   /// two basic blocks.
0205   bool dominates(const Instruction *Def, const BasicBlock *BB) const;
0206 
0207   /// Return true if an edge dominates a use.
0208   ///
0209   /// If BBE is not a unique edge between start and end of the edge, it can
0210   /// never dominate the use.
0211   bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
0212   bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
0213   /// Returns true if edge \p BBE1 dominates edge \p BBE2.
0214   bool dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const;
0215 
0216   // Ensure base class overloads are visible.
0217   using Base::isReachableFromEntry;
0218 
0219   /// Provide an overload for a Use.
0220   bool isReachableFromEntry(const Use &U) const;
0221 
0222   // Ensure base class overloads are visible.
0223   using Base::findNearestCommonDominator;
0224 
0225   /// Find the nearest instruction I that dominates both I1 and I2, in the sense
0226   /// that a result produced before I will be available at both I1 and I2.
0227   Instruction *findNearestCommonDominator(Instruction *I1,
0228                                           Instruction *I2) const;
0229 
0230   // Pop up a GraphViz/gv window with the Dominator Tree rendered using `dot`.
0231   void viewGraph(const Twine &Name, const Twine &Title);
0232   void viewGraph();
0233 };
0234 
0235 //===-------------------------------------
0236 // DominatorTree GraphTraits specializations so the DominatorTree can be
0237 // iterable by generic graph iterators.
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 /// Analysis pass which computes a \c DominatorTree.
0279 class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> {
0280   friend AnalysisInfoMixin<DominatorTreeAnalysis>;
0281   static AnalysisKey Key;
0282 
0283 public:
0284   /// Provide the result typedef for this analysis pass.
0285   using Result = DominatorTree;
0286 
0287   /// Run the analysis pass over a function and produce a dominator tree.
0288   DominatorTree run(Function &F, FunctionAnalysisManager &);
0289 };
0290 
0291 /// Printer pass for the \c DominatorTree.
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 /// Verifier pass for the \c DominatorTree.
0305 struct DominatorTreeVerifierPass : PassInfoMixin<DominatorTreeVerifierPass> {
0306   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0307   static bool isRequired() { return true; }
0308 };
0309 
0310 /// Enables verification of dominator trees.
0311 ///
0312 /// This check is expensive and is disabled by default.  `-verify-dom-info`
0313 /// allows selectively enabling the check without needing to recompile.
0314 extern bool VerifyDomInfo;
0315 
0316 /// Legacy analysis pass which computes a \c DominatorTree.
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 } // end namespace llvm
0341 
0342 #endif // LLVM_IR_DOMINATORS_H