15
15
#ifndef LLVM_TRANSFORMS_SCALAR_SROA_H
16
16
#define LLVM_TRANSFORMS_SCALAR_SROA_H
17
17
18
- #include " llvm/ADT/MapVector.h"
19
- #include " llvm/ADT/PointerIntPair.h"
20
- #include " llvm/ADT/SetVector.h"
21
- #include " llvm/ADT/SmallVector.h"
22
18
#include " llvm/IR/PassManager.h"
23
- #include " llvm/IR/ValueHandle.h"
24
- #include < variant>
25
- #include < vector>
26
19
27
20
namespace llvm {
28
21
29
- class AllocaInst ;
30
- class LoadInst ;
31
- class StoreInst ;
32
- class AssumptionCache ;
33
- class DominatorTree ;
34
- class DomTreeUpdater ;
35
22
class Function ;
36
- class LLVMContext ;
37
- class PHINode ;
38
- class SelectInst ;
39
- class Use ;
40
-
41
- // / A private "module" namespace for types and utilities used by SROA. These
42
- // / are implementation details and should not be used by clients.
43
- namespace LLVM_LIBRARY_VISIBILITY sroa {
44
-
45
- class AllocaSliceRewriter ;
46
- class AllocaSlices ;
47
- class Partition ;
48
- class SROALegacyPass ;
49
-
50
- class SelectHandSpeculativity {
51
- unsigned char Storage = 0 ; // None are speculatable by default.
52
- using TrueVal = Bitfield::Element<bool , 0 , 1 >; // Low 0'th bit.
53
- using FalseVal = Bitfield::Element<bool , 1 , 1 >; // Low 1'th bit.
54
- public:
55
- SelectHandSpeculativity () = default ;
56
- SelectHandSpeculativity &setAsSpeculatable (bool isTrueVal);
57
- bool isSpeculatable (bool isTrueVal) const ;
58
- bool areAllSpeculatable () const ;
59
- bool areAnySpeculatable () const ;
60
- bool areNoneSpeculatable () const ;
61
- // For interop as int half of PointerIntPair.
62
- explicit operator intptr_t () const { return static_cast <intptr_t >(Storage); }
63
- explicit SelectHandSpeculativity (intptr_t Storage_) : Storage(Storage_) {}
64
- };
65
- static_assert (sizeof (SelectHandSpeculativity) == sizeof (unsigned char ));
66
-
67
- using PossiblySpeculatableLoad =
68
- PointerIntPair<LoadInst *, 2 , sroa::SelectHandSpeculativity>;
69
- using UnspeculatableStore = StoreInst *;
70
- using RewriteableMemOp =
71
- std::variant<PossiblySpeculatableLoad, UnspeculatableStore>;
72
- using RewriteableMemOps = SmallVector<RewriteableMemOp, 2 >;
73
-
74
- } // end namespace sroa
75
23
76
24
enum class SROAOptions : bool { ModifyCFG, PreserveCFG };
77
25
78
- // / An optimization pass providing Scalar Replacement of Aggregates.
79
- // /
80
- // / This pass takes allocations which can be completely analyzed (that is, they
81
- // / don't escape) and tries to turn them into scalar SSA values. There are
82
- // / a few steps to this process.
83
- // /
84
- // / 1) It takes allocations of aggregates and analyzes the ways in which they
85
- // / are used to try to split them into smaller allocations, ideally of
86
- // / a single scalar data type. It will split up memcpy and memset accesses
87
- // / as necessary and try to isolate individual scalar accesses.
88
- // / 2) It will transform accesses into forms which are suitable for SSA value
89
- // / promotion. This can be replacing a memset with a scalar store of an
90
- // / integer value, or it can involve speculating operations on a PHI or
91
- // / select to be a PHI or select of the results.
92
- // / 3) Finally, this will try to detect a pattern of accesses which map cleanly
93
- // / onto insert and extract operations on a vector value, and convert them to
94
- // / this form. By doing so, it will enable promotion of vector aggregates to
95
- // / SSA vector values.
96
26
class SROAPass : public PassInfoMixin <SROAPass> {
97
- LLVMContext *C = nullptr ;
98
- DomTreeUpdater *DTU = nullptr ;
99
- AssumptionCache *AC = nullptr ;
100
- const bool PreserveCFG;
101
-
102
- // / Worklist of alloca instructions to simplify.
103
- // /
104
- // / Each alloca in the function is added to this. Each new alloca formed gets
105
- // / added to it as well to recursively simplify unless that alloca can be
106
- // / directly promoted. Finally, each time we rewrite a use of an alloca other
107
- // / the one being actively rewritten, we add it back onto the list if not
108
- // / already present to ensure it is re-visited.
109
- SmallSetVector<AllocaInst *, 16 > Worklist;
110
-
111
- // / A collection of instructions to delete.
112
- // / We try to batch deletions to simplify code and make things a bit more
113
- // / efficient. We also make sure there is no dangling pointers.
114
- SmallVector<WeakVH, 8 > DeadInsts;
115
-
116
- // / Post-promotion worklist.
117
- // /
118
- // / Sometimes we discover an alloca which has a high probability of becoming
119
- // / viable for SROA after a round of promotion takes place. In those cases,
120
- // / the alloca is enqueued here for re-processing.
121
- // /
122
- // / Note that we have to be very careful to clear allocas out of this list in
123
- // / the event they are deleted.
124
- SmallSetVector<AllocaInst *, 16 > PostPromotionWorklist;
125
-
126
- // / A collection of alloca instructions we can directly promote.
127
- std::vector<AllocaInst *> PromotableAllocas;
128
-
129
- // / A worklist of PHIs to speculate prior to promoting allocas.
130
- // /
131
- // / All of these PHIs have been checked for the safety of speculation and by
132
- // / being speculated will allow promoting allocas currently in the promotable
133
- // / queue.
134
- SmallSetVector<PHINode *, 8 > SpeculatablePHIs;
135
-
136
- // / A worklist of select instructions to rewrite prior to promoting
137
- // / allocas.
138
- SmallMapVector<SelectInst *, sroa::RewriteableMemOps, 8 > SelectsToRewrite;
139
-
140
- // / Select instructions that use an alloca and are subsequently loaded can be
141
- // / rewritten to load both input pointers and then select between the result,
142
- // / allowing the load of the alloca to be promoted.
143
- // / From this:
144
- // / %P2 = select i1 %cond, ptr %Alloca, ptr %Other
145
- // / %V = load <type>, ptr %P2
146
- // / to:
147
- // / %V1 = load <type>, ptr %Alloca -> will be mem2reg'd
148
- // / %V2 = load <type>, ptr %Other
149
- // / %V = select i1 %cond, <type> %V1, <type> %V2
150
- // /
151
- // / We can do this to a select if its only uses are loads
152
- // / and if either the operand to the select can be loaded unconditionally,
153
- // / or if we are allowed to perform CFG modifications.
154
- // / If found an intervening bitcast with a single use of the load,
155
- // / allow the promotion.
156
- static std::optional<sroa::RewriteableMemOps>
157
- isSafeSelectToSpeculate (SelectInst &SI, bool PreserveCFG);
27
+ const SROAOptions PreserveCFG;
158
28
159
29
public:
160
30
// / If \p PreserveCFG is set, then the pass is not allowed to modify CFG
@@ -166,25 +36,6 @@ class SROAPass : public PassInfoMixin<SROAPass> {
166
36
167
37
void printPipeline (raw_ostream &OS,
168
38
function_ref<StringRef(StringRef)> MapClassName2PassName);
169
-
170
- private:
171
- friend class sroa ::AllocaSliceRewriter;
172
- friend class sroa ::SROALegacyPass;
173
-
174
- // / Helper used by both the public run method and by the legacy pass.
175
- PreservedAnalyses runImpl (Function &F, DomTreeUpdater &RunDTU,
176
- AssumptionCache &RunAC);
177
- PreservedAnalyses runImpl (Function &F, DominatorTree &RunDT,
178
- AssumptionCache &RunAC);
179
-
180
- bool presplitLoadsAndStores (AllocaInst &AI, sroa::AllocaSlices &AS);
181
- AllocaInst *rewritePartition (AllocaInst &AI, sroa::AllocaSlices &AS,
182
- sroa::Partition &P);
183
- bool splitAlloca (AllocaInst &AI, sroa::AllocaSlices &AS);
184
- std::pair<bool /* Changed*/ , bool /* CFGChanged*/ > runOnAlloca (AllocaInst &AI);
185
- void clobberUse (Use &U);
186
- bool deleteDeadInstructions (SmallPtrSetImpl<AllocaInst *> &DeletedAllocas);
187
- bool promoteAllocas (Function &F);
188
39
};
189
40
190
41
} // end namespace llvm
0 commit comments