1 //===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the DominanceFrontier class, which calculate and holds the
10 // dominance frontier for a function.
12 // This should be considered deprecated, don't add any more uses of this data
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
18 #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
20 #include "llvm/ADT/GraphTraits.h"
21 #include "llvm/Config/llvm-config.h"
22 #include "llvm/IR/PassManager.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Support/GenericDomTree.h"
36 //===----------------------------------------------------------------------===//
37 /// DominanceFrontierBase - Common base class for computing forward and inverse
38 /// dominance frontiers for a function.
40 template <class BlockT
, bool IsPostDom
>
41 class DominanceFrontierBase
{
43 using DomSetType
= std::set
<BlockT
*>; // Dom set for a bb
44 using DomSetMapType
= std::map
<BlockT
*, DomSetType
>; // Dom set map
47 using BlockTraits
= GraphTraits
<BlockT
*>;
49 DomSetMapType Frontiers
;
50 // Postdominators can have multiple roots.
51 SmallVector
<BlockT
*, IsPostDom
? 4 : 1> Roots
;
52 static constexpr bool IsPostDominators
= IsPostDom
;
55 DominanceFrontierBase() = default;
57 /// getRoots - Return the root blocks of the current CFG. This may include
58 /// multiple blocks if we are computing post dominators. For forward
59 /// dominators, this will always be a single block (the entry node).
60 const SmallVectorImpl
<BlockT
*> &getRoots() const { return Roots
; }
62 BlockT
*getRoot() const {
63 assert(Roots
.size() == 1 && "Should always have entry node!");
67 /// isPostDominator - Returns true if analysis based of postdoms
68 bool isPostDominator() const {
69 return IsPostDominators
;
72 void releaseMemory() {
76 // Accessor interface:
77 using iterator
= typename
DomSetMapType::iterator
;
78 using const_iterator
= typename
DomSetMapType::const_iterator
;
80 iterator
begin() { return Frontiers
.begin(); }
81 const_iterator
begin() const { return Frontiers
.begin(); }
82 iterator
end() { return Frontiers
.end(); }
83 const_iterator
end() const { return Frontiers
.end(); }
84 iterator
find(BlockT
*B
) { return Frontiers
.find(B
); }
85 const_iterator
find(BlockT
*B
) const { return Frontiers
.find(B
); }
87 iterator
addBasicBlock(BlockT
*BB
, const DomSetType
&frontier
) {
88 assert(find(BB
) == end() && "Block already in DominanceFrontier!");
89 return Frontiers
.insert(std::make_pair(BB
, frontier
)).first
;
92 /// removeBlock - Remove basic block BB's frontier.
93 void removeBlock(BlockT
*BB
);
95 void addToFrontier(iterator I
, BlockT
*Node
);
97 void removeFromFrontier(iterator I
, BlockT
*Node
);
99 /// compareDomSet - Return false if two domsets match. Otherwise
101 bool compareDomSet(DomSetType
&DS1
, const DomSetType
&DS2
) const;
103 /// compare - Return true if the other dominance frontier base matches
104 /// this dominance frontier base. Otherwise return false.
105 bool compare(DominanceFrontierBase
&Other
) const;
107 /// print - Convert to human readable form
109 void print(raw_ostream
&OS
) const;
111 /// dump - Dump the dominance frontier to dbgs().
112 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
117 //===-------------------------------------
118 /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
119 /// used to compute a forward dominator frontiers.
121 template <class BlockT
>
122 class ForwardDominanceFrontierBase
123 : public DominanceFrontierBase
<BlockT
, false> {
125 using BlockTraits
= GraphTraits
<BlockT
*>;
128 using DomTreeT
= DomTreeBase
<BlockT
>;
129 using DomTreeNodeT
= DomTreeNodeBase
<BlockT
>;
130 using DomSetType
= typename DominanceFrontierBase
<BlockT
, false>::DomSetType
;
132 void analyze(DomTreeT
&DT
) {
133 assert(DT
.getRoots().size() == 1 &&
134 "Only one entry block for forward domfronts!");
135 this->Roots
= {DT
.getRoot()};
136 calculate(DT
, DT
[this->Roots
[0]]);
139 const DomSetType
&calculate(const DomTreeT
&DT
, const DomTreeNodeT
*Node
);
142 class DominanceFrontier
: public ForwardDominanceFrontierBase
<BasicBlock
> {
144 using DomTreeT
= DomTreeBase
<BasicBlock
>;
145 using DomTreeNodeT
= DomTreeNodeBase
<BasicBlock
>;
146 using DomSetType
= DominanceFrontierBase
<BasicBlock
, false>::DomSetType
;
147 using iterator
= DominanceFrontierBase
<BasicBlock
, false>::iterator
;
148 using const_iterator
=
149 DominanceFrontierBase
<BasicBlock
, false>::const_iterator
;
151 /// Handle invalidation explicitly.
152 bool invalidate(Function
&F
, const PreservedAnalyses
&PA
,
153 FunctionAnalysisManager::Invalidator
&);
156 class DominanceFrontierWrapperPass
: public FunctionPass
{
157 DominanceFrontier DF
;
160 static char ID
; // Pass ID, replacement for typeid
162 DominanceFrontierWrapperPass();
164 DominanceFrontier
&getDominanceFrontier() { return DF
; }
165 const DominanceFrontier
&getDominanceFrontier() const { return DF
; }
167 void releaseMemory() override
;
169 bool runOnFunction(Function
&) override
;
171 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
173 void print(raw_ostream
&OS
, const Module
* = nullptr) const override
;
178 extern template class DominanceFrontierBase
<BasicBlock
, false>;
179 extern template class DominanceFrontierBase
<BasicBlock
, true>;
180 extern template class ForwardDominanceFrontierBase
<BasicBlock
>;
182 /// Analysis pass which computes a \c DominanceFrontier.
183 class DominanceFrontierAnalysis
184 : public AnalysisInfoMixin
<DominanceFrontierAnalysis
> {
185 friend AnalysisInfoMixin
<DominanceFrontierAnalysis
>;
187 static AnalysisKey Key
;
190 /// Provide the result type for this analysis pass.
191 using Result
= DominanceFrontier
;
193 /// Run the analysis pass over a function and produce a dominator tree.
194 DominanceFrontier
run(Function
&F
, FunctionAnalysisManager
&AM
);
197 /// Printer pass for the \c DominanceFrontier.
198 class DominanceFrontierPrinterPass
199 : public PassInfoMixin
<DominanceFrontierPrinterPass
> {
203 explicit DominanceFrontierPrinterPass(raw_ostream
&OS
);
205 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&AM
);
208 } // end namespace llvm
210 #endif // LLVM_ANALYSIS_DOMINANCEFRONTIER_H