30
30
31
31
namespace llvm {
32
32
33
-
34
- // / This pass should run after reduction variables have been converted to phi nodes,
35
- // / otherwise floating-point reductions might not be recognized as such and
36
- // / prevent SIMDization.
37
- struct LowerSIMDLoop : public ModulePass {
38
- static char ID;
39
- LowerSIMDLoop () : ModulePass(ID)
40
- {
41
- }
42
-
43
- protected:
44
- void getAnalysisUsage (AnalysisUsage &AU) const override
45
- {
46
- ModulePass::getAnalysisUsage (AU);
47
- AU.addRequired <LoopInfoWrapperPass>();
48
- AU.addPreserved <LoopInfoWrapperPass>();
49
- AU.setPreservesCFG ();
50
- }
51
-
52
- private:
53
- bool runOnModule (Module &M) override ;
54
-
55
- bool markLoopInfo (Module &M, Function *marker);
56
-
57
- // / If Phi is part of a reduction cycle of FAdd, FSub, FMul or FDiv,
58
- // / mark the ops as permitting reassociation/commuting.
59
- // / As of LLVM 4.0, FDiv is not handled by the loop vectorizer
60
- void enableUnsafeAlgebraIfReduction (PHINode *Phi, Loop *L) const ;
61
- };
33
+ namespace {
62
34
63
35
static unsigned getReduceOpcode (Instruction *J, Instruction *operand)
64
36
{
@@ -80,7 +52,10 @@ static unsigned getReduceOpcode(Instruction *J, Instruction *operand)
80
52
}
81
53
}
82
54
83
- void LowerSIMDLoop::enableUnsafeAlgebraIfReduction (PHINode *Phi, Loop *L) const
55
+ // / If Phi is part of a reduction cycle of FAdd, FSub, FMul or FDiv,
56
+ // / mark the ops as permitting reassociation/commuting.
57
+ // / As of LLVM 4.0, FDiv is not handled by the loop vectorizer
58
+ static void enableUnsafeAlgebraIfReduction (PHINode *Phi, Loop *L)
84
59
{
85
60
typedef SmallVector<Instruction*, 8 > chainVector;
86
61
chainVector chain;
@@ -130,26 +105,15 @@ void LowerSIMDLoop::enableUnsafeAlgebraIfReduction(PHINode *Phi, Loop *L) const
130
105
}
131
106
}
132
107
133
- bool LowerSIMDLoop::runOnModule (Module &M)
134
- {
135
- Function *loopinfo_marker = M.getFunction (" julia.loopinfo_marker" );
136
-
137
- bool Changed = false ;
138
- if (loopinfo_marker)
139
- Changed |= markLoopInfo (M, loopinfo_marker);
140
-
141
- return Changed;
142
- }
143
-
144
- bool LowerSIMDLoop::markLoopInfo (Module &M, Function *marker)
108
+ static bool markLoopInfo (Module &M, Function *marker, function_ref<LoopInfo &(Function &)> GetLI)
145
109
{
146
110
bool Changed = false ;
147
111
std::vector<Instruction*> ToDelete;
148
112
for (User *U : marker->users ()) {
149
113
Instruction *I = cast<Instruction>(U);
150
114
ToDelete.push_back (I);
151
115
152
- LoopInfo &LI = getAnalysis<LoopInfoWrapperPass> (*I->getParent ()->getParent ()). getLoopInfo ( );
116
+ LoopInfo &LI = GetLI (*I->getParent ()->getParent ());
153
117
Loop *L = LI.getLoopFor (I->getParent ());
154
118
I->removeFromParent ();
155
119
if (!L)
@@ -243,15 +207,81 @@ bool LowerSIMDLoop::markLoopInfo(Module &M, Function *marker)
243
207
return Changed;
244
208
}
245
209
246
- char LowerSIMDLoop::ID = 0 ;
210
+ } // end anonymous namespace
211
+
212
+
213
+ // / This pass should run after reduction variables have been converted to phi nodes,
214
+ // / otherwise floating-point reductions might not be recognized as such and
215
+ // / prevent SIMDization.
216
+ struct LowerSIMDLoop : PassInfoMixin<LowerSIMDLoop> {
217
+ PreservedAnalyses run (Module &M, ModuleAnalysisManager &AM);
218
+ };
219
+
220
+
221
+ PreservedAnalyses LowerSIMDLoop::run (Module &M, ModuleAnalysisManager &AM)
222
+ {
223
+ Function *loopinfo_marker = M.getFunction (" julia.loopinfo_marker" );
224
+
225
+ if (!loopinfo_marker)
226
+ return PreservedAnalyses::all ();
227
+
228
+ FunctionAnalysisManager &FAM =
229
+ AM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
230
+
231
+ auto GetLI = [&FAM](Function &F) -> LoopInfo & {
232
+ return FAM.getResult <LoopAnalysis>(F);
233
+ };
234
+
235
+ markLoopInfo (M, loopinfo_marker, GetLI);
236
+
237
+ return PreservedAnalyses::all ();
238
+ }
239
+
240
+ namespace {
241
+ class LowerSIMDLoopLegacy : public ModulePass {
242
+ LowerSIMDLoop Impl;
243
+
244
+ public:
245
+ static char ID;
246
+
247
+ LowerSIMDLoopLegacy () : ModulePass(ID) {
248
+ }
249
+
250
+ bool runOnModule (Module &M) override {
251
+ bool Changed = false ;
252
+
253
+ Function *loopinfo_marker = M.getFunction (" julia.loopinfo_marker" );
254
+
255
+ auto GetLI = [this ](Function &F) -> LoopInfo & {
256
+ return getAnalysis<LoopInfoWrapperPass>(F).getLoopInfo ();
257
+ };
258
+
259
+ if (loopinfo_marker)
260
+ Changed |= markLoopInfo (M, loopinfo_marker, GetLI);
261
+
262
+ return Changed;
263
+ }
264
+
265
+ void getAnalysisUsage (AnalysisUsage &AU) const override
266
+ {
267
+ ModulePass::getAnalysisUsage (AU);
268
+ AU.addRequired <LoopInfoWrapperPass>();
269
+ AU.addPreserved <LoopInfoWrapperPass>();
270
+ AU.setPreservesCFG ();
271
+ }
272
+ };
273
+
274
+ } // end anonymous namespace
275
+
276
+ char LowerSIMDLoopLegacy::ID = 0 ;
247
277
248
- static RegisterPass<LowerSIMDLoop > X (" LowerSIMDLoop" , " LowerSIMDLoop Pass" ,
278
+ static RegisterPass<LowerSIMDLoopLegacy > X (" LowerSIMDLoop" , " LowerSIMDLoop Pass" ,
249
279
false /* Only looks at CFG */ ,
250
280
false /* Analysis Pass */ );
251
281
252
282
JL_DLLEXPORT Pass *createLowerSimdLoopPass ()
253
283
{
254
- return new LowerSIMDLoop ();
284
+ return new LowerSIMDLoopLegacy ();
255
285
}
256
286
257
287
extern " C" JL_DLLEXPORT void LLVMExtraAddLowerSimdLoopPass (LLVMPassManagerRef PM)
0 commit comments