Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- PredicateInfo.h - Build PredicateInfo ----------------------*-C++-*-===// |
2 | // |
||
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 |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | /// |
||
9 | /// \file |
||
10 | /// This file implements the PredicateInfo analysis, which creates an Extended |
||
11 | /// SSA form for operations used in branch comparisons and llvm.assume |
||
12 | /// comparisons. |
||
13 | /// |
||
14 | /// Copies of these operations are inserted into the true/false edge (and after |
||
15 | /// assumes), and information attached to the copies. All uses of the original |
||
16 | /// operation in blocks dominated by the true/false edge (and assume), are |
||
17 | /// replaced with uses of the copies. This enables passes to easily and sparsely |
||
18 | /// propagate condition based info into the operations that may be affected. |
||
19 | /// |
||
20 | /// Example: |
||
21 | /// %cmp = icmp eq i32 %x, 50 |
||
22 | /// br i1 %cmp, label %true, label %false |
||
23 | /// true: |
||
24 | /// ret i32 %x |
||
25 | /// false: |
||
26 | /// ret i32 1 |
||
27 | /// |
||
28 | /// will become |
||
29 | /// |
||
30 | /// %cmp = icmp eq i32, %x, 50 |
||
31 | /// br i1 %cmp, label %true, label %false |
||
32 | /// true: |
||
33 | /// %x.0 = call \@llvm.ssa_copy.i32(i32 %x) |
||
34 | /// ret i32 %x.0 |
||
35 | /// false: |
||
36 | /// ret i32 1 |
||
37 | /// |
||
38 | /// Using getPredicateInfoFor on x.0 will give you the comparison it is |
||
39 | /// dominated by (the icmp), and that you are located in the true edge of that |
||
40 | /// comparison, which tells you x.0 is 50. |
||
41 | /// |
||
42 | /// In order to reduce the number of copies inserted, predicateinfo is only |
||
43 | /// inserted where it would actually be live. This means if there are no uses of |
||
44 | /// an operation dominated by the branch edges, or by an assume, the associated |
||
45 | /// predicate info is never inserted. |
||
46 | /// |
||
47 | /// |
||
48 | //===----------------------------------------------------------------------===// |
||
49 | |||
50 | #ifndef LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H |
||
51 | #define LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H |
||
52 | |||
53 | #include "llvm/ADT/DenseMap.h" |
||
54 | #include "llvm/ADT/SmallSet.h" |
||
55 | #include "llvm/ADT/ilist.h" |
||
56 | #include "llvm/ADT/ilist_node.h" |
||
57 | #include "llvm/IR/Instructions.h" |
||
58 | #include "llvm/IR/PassManager.h" |
||
59 | #include "llvm/IR/ValueHandle.h" |
||
60 | #include "llvm/Pass.h" |
||
61 | |||
62 | namespace llvm { |
||
63 | |||
64 | class AssumptionCache; |
||
65 | class DominatorTree; |
||
66 | class Function; |
||
67 | class Value; |
||
68 | class IntrinsicInst; |
||
69 | class raw_ostream; |
||
70 | |||
71 | enum PredicateType { PT_Branch, PT_Assume, PT_Switch }; |
||
72 | |||
73 | /// Constraint for a predicate of the form "cmp Pred Op, OtherOp", where Op |
||
74 | /// is the value the constraint applies to (the ssa.copy result). |
||
75 | struct PredicateConstraint { |
||
76 | CmpInst::Predicate Predicate; |
||
77 | Value *OtherOp; |
||
78 | }; |
||
79 | |||
80 | // Base class for all predicate information we provide. |
||
81 | // All of our predicate information has at least a comparison. |
||
82 | class PredicateBase : public ilist_node<PredicateBase> { |
||
83 | public: |
||
84 | PredicateType Type; |
||
85 | // The original operand before we renamed it. |
||
86 | // This can be use by passes, when destroying predicateinfo, to know |
||
87 | // whether they can just drop the intrinsic, or have to merge metadata. |
||
88 | Value *OriginalOp; |
||
89 | // The renamed operand in the condition used for this predicate. For nested |
||
90 | // predicates, this is different to OriginalOp which refers to the initial |
||
91 | // operand. |
||
92 | Value *RenamedOp; |
||
93 | // The condition associated with this predicate. |
||
94 | Value *Condition; |
||
95 | |||
96 | PredicateBase(const PredicateBase &) = delete; |
||
97 | PredicateBase &operator=(const PredicateBase &) = delete; |
||
98 | PredicateBase() = delete; |
||
99 | virtual ~PredicateBase() = default; |
||
100 | static bool classof(const PredicateBase *PB) { |
||
101 | return PB->Type == PT_Assume || PB->Type == PT_Branch || |
||
102 | PB->Type == PT_Switch; |
||
103 | } |
||
104 | |||
105 | /// Fetch condition in the form of PredicateConstraint, if possible. |
||
106 | std::optional<PredicateConstraint> getConstraint() const; |
||
107 | |||
108 | protected: |
||
109 | PredicateBase(PredicateType PT, Value *Op, Value *Condition) |
||
110 | : Type(PT), OriginalOp(Op), Condition(Condition) {} |
||
111 | }; |
||
112 | |||
113 | // Provides predicate information for assumes. Since assumes are always true, |
||
114 | // we simply provide the assume instruction, so you can tell your relative |
||
115 | // position to it. |
||
116 | class PredicateAssume : public PredicateBase { |
||
117 | public: |
||
118 | IntrinsicInst *AssumeInst; |
||
119 | PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, Value *Condition) |
||
120 | : PredicateBase(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {} |
||
121 | PredicateAssume() = delete; |
||
122 | static bool classof(const PredicateBase *PB) { |
||
123 | return PB->Type == PT_Assume; |
||
124 | } |
||
125 | }; |
||
126 | |||
127 | // Mixin class for edge predicates. The FROM block is the block where the |
||
128 | // predicate originates, and the TO block is the block where the predicate is |
||
129 | // valid. |
||
130 | class PredicateWithEdge : public PredicateBase { |
||
131 | public: |
||
132 | BasicBlock *From; |
||
133 | BasicBlock *To; |
||
134 | PredicateWithEdge() = delete; |
||
135 | static bool classof(const PredicateBase *PB) { |
||
136 | return PB->Type == PT_Branch || PB->Type == PT_Switch; |
||
137 | } |
||
138 | |||
139 | protected: |
||
140 | PredicateWithEdge(PredicateType PType, Value *Op, BasicBlock *From, |
||
141 | BasicBlock *To, Value *Cond) |
||
142 | : PredicateBase(PType, Op, Cond), From(From), To(To) {} |
||
143 | }; |
||
144 | |||
145 | // Provides predicate information for branches. |
||
146 | class PredicateBranch : public PredicateWithEdge { |
||
147 | public: |
||
148 | // If true, SplitBB is the true successor, otherwise it's the false successor. |
||
149 | bool TrueEdge; |
||
150 | PredicateBranch(Value *Op, BasicBlock *BranchBB, BasicBlock *SplitBB, |
||
151 | Value *Condition, bool TakenEdge) |
||
152 | : PredicateWithEdge(PT_Branch, Op, BranchBB, SplitBB, Condition), |
||
153 | TrueEdge(TakenEdge) {} |
||
154 | PredicateBranch() = delete; |
||
155 | static bool classof(const PredicateBase *PB) { |
||
156 | return PB->Type == PT_Branch; |
||
157 | } |
||
158 | }; |
||
159 | |||
160 | class PredicateSwitch : public PredicateWithEdge { |
||
161 | public: |
||
162 | Value *CaseValue; |
||
163 | // This is the switch instruction. |
||
164 | SwitchInst *Switch; |
||
165 | PredicateSwitch(Value *Op, BasicBlock *SwitchBB, BasicBlock *TargetBB, |
||
166 | Value *CaseValue, SwitchInst *SI) |
||
167 | : PredicateWithEdge(PT_Switch, Op, SwitchBB, TargetBB, |
||
168 | SI->getCondition()), |
||
169 | CaseValue(CaseValue), Switch(SI) {} |
||
170 | PredicateSwitch() = delete; |
||
171 | static bool classof(const PredicateBase *PB) { |
||
172 | return PB->Type == PT_Switch; |
||
173 | } |
||
174 | }; |
||
175 | |||
176 | /// Encapsulates PredicateInfo, including all data associated with memory |
||
177 | /// accesses. |
||
178 | class PredicateInfo { |
||
179 | public: |
||
180 | PredicateInfo(Function &, DominatorTree &, AssumptionCache &); |
||
181 | ~PredicateInfo(); |
||
182 | |||
183 | void verifyPredicateInfo() const; |
||
184 | |||
185 | void dump() const; |
||
186 | void print(raw_ostream &) const; |
||
187 | |||
188 | const PredicateBase *getPredicateInfoFor(const Value *V) const { |
||
189 | return PredicateMap.lookup(V); |
||
190 | } |
||
191 | |||
192 | protected: |
||
193 | // Used by PredicateInfo annotater, dumpers, and wrapper pass. |
||
194 | friend class PredicateInfoAnnotatedWriter; |
||
195 | friend class PredicateInfoPrinterLegacyPass; |
||
196 | friend class PredicateInfoBuilder; |
||
197 | |||
198 | private: |
||
199 | Function &F; |
||
200 | |||
201 | // This owns the all the predicate infos in the function, placed or not. |
||
202 | iplist<PredicateBase> AllInfos; |
||
203 | |||
204 | // This maps from copy operands to Predicate Info. Note that it does not own |
||
205 | // the Predicate Info, they belong to the ValueInfo structs in the ValueInfos |
||
206 | // vector. |
||
207 | DenseMap<const Value *, const PredicateBase *> PredicateMap; |
||
208 | // The set of ssa_copy declarations we created with our custom mangling. |
||
209 | SmallSet<AssertingVH<Function>, 20> CreatedDeclarations; |
||
210 | }; |
||
211 | |||
212 | // This pass does eager building and then printing of PredicateInfo. It is used |
||
213 | // by |
||
214 | // the tests to be able to build, dump, and verify PredicateInfo. |
||
215 | class PredicateInfoPrinterLegacyPass : public FunctionPass { |
||
216 | public: |
||
217 | PredicateInfoPrinterLegacyPass(); |
||
218 | |||
219 | static char ID; |
||
220 | bool runOnFunction(Function &) override; |
||
221 | void getAnalysisUsage(AnalysisUsage &AU) const override; |
||
222 | }; |
||
223 | |||
224 | /// Printer pass for \c PredicateInfo. |
||
225 | class PredicateInfoPrinterPass |
||
226 | : public PassInfoMixin<PredicateInfoPrinterPass> { |
||
227 | raw_ostream &OS; |
||
228 | |||
229 | public: |
||
230 | explicit PredicateInfoPrinterPass(raw_ostream &OS) : OS(OS) {} |
||
231 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); |
||
232 | }; |
||
233 | |||
234 | /// Verifier pass for \c PredicateInfo. |
||
235 | struct PredicateInfoVerifierPass : PassInfoMixin<PredicateInfoVerifierPass> { |
||
236 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); |
||
237 | }; |
||
238 | |||
239 | } // end namespace llvm |
||
240 | |||
241 | #endif // LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H |