@@ -38,6 +38,7 @@ using StackVector = SmallVector<StackEntry, 16>;
38
38
39
39
class SIAnnotateControlFlow {
40
40
private:
41
+ Function *F;
41
42
UniformityInfo *UA;
42
43
43
44
Type *Boolean ;
@@ -50,18 +51,18 @@ class SIAnnotateControlFlow {
50
51
UndefValue *BoolUndef;
51
52
Constant *IntMaskZero;
52
53
53
- Function *If;
54
- Function *Else;
55
- Function *IfBreak;
56
- Function *Loop;
57
- Function *EndCf;
54
+ Function *If = nullptr ;
55
+ Function *Else = nullptr ;
56
+ Function *IfBreak = nullptr ;
57
+ Function *Loop = nullptr ;
58
+ Function *EndCf = nullptr ;
58
59
59
60
DominatorTree *DT;
60
61
StackVector Stack;
61
62
62
63
LoopInfo *LI;
63
64
64
- void initialize (Module &M, const GCNSubtarget &ST);
65
+ void initialize (const GCNSubtarget &ST);
65
66
66
67
bool isUniform (BranchInst *T);
67
68
@@ -89,21 +90,27 @@ class SIAnnotateControlFlow {
89
90
90
91
bool closeControlFlow (BasicBlock *BB);
91
92
93
+ Function *getDecl (Function *&Cache, Intrinsic::ID ID, ArrayRef<Type *> Tys) {
94
+ if (!Cache)
95
+ Cache = Intrinsic::getOrInsertDeclaration (F->getParent (), ID, Tys);
96
+ return Cache;
97
+ }
98
+
92
99
public:
93
- SIAnnotateControlFlow (Module &M , const GCNSubtarget &ST, DominatorTree &DT,
100
+ SIAnnotateControlFlow (Function &F , const GCNSubtarget &ST, DominatorTree &DT,
94
101
LoopInfo &LI, UniformityInfo &UA)
95
- : UA(&UA), DT(&DT), LI(&LI) {
96
- initialize (M, ST);
102
+ : F(&F), UA(&UA), DT(&DT), LI(&LI) {
103
+ initialize (ST);
97
104
}
98
105
99
- bool run (Function &F );
106
+ bool run ();
100
107
};
101
108
102
109
} // end anonymous namespace
103
110
104
111
// / Initialize all the types and constants used in the pass
105
- void SIAnnotateControlFlow::initialize (Module &M, const GCNSubtarget &ST) {
106
- LLVMContext &Context = M. getContext ();
112
+ void SIAnnotateControlFlow::initialize (const GCNSubtarget &ST) {
113
+ LLVMContext &Context = F-> getContext ();
107
114
108
115
Void = Type::getVoidTy (Context);
109
116
Boolean = Type::getInt1Ty (Context);
@@ -115,16 +122,6 @@ void SIAnnotateControlFlow::initialize(Module &M, const GCNSubtarget &ST) {
115
122
BoolFalse = ConstantInt::getFalse (Context);
116
123
BoolUndef = PoisonValue::get (Boolean );
117
124
IntMaskZero = ConstantInt::get (IntMask, 0 );
118
-
119
- If = Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_if, {IntMask});
120
- Else = Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_else,
121
- {IntMask, IntMask});
122
- IfBreak = Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_if_break,
123
- {IntMask});
124
- Loop =
125
- Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_loop, {IntMask});
126
- EndCf = Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_end_cf,
127
- {IntMask});
128
125
}
129
126
130
127
// / Is the branch condition uniform or did the StructurizeCFG pass
@@ -190,7 +187,8 @@ bool SIAnnotateControlFlow::openIf(BranchInst *Term) {
190
187
return false ;
191
188
192
189
IRBuilder<> IRB (Term);
193
- Value *IfCall = IRB.CreateCall (If, {Term->getCondition ()});
190
+ Value *IfCall = IRB.CreateCall (getDecl (If, Intrinsic::amdgcn_if, IntMask),
191
+ {Term->getCondition ()});
194
192
Value *Cond = IRB.CreateExtractValue (IfCall, {0 });
195
193
Value *Mask = IRB.CreateExtractValue (IfCall, {1 });
196
194
Term->setCondition (Cond);
@@ -205,7 +203,8 @@ bool SIAnnotateControlFlow::insertElse(BranchInst *Term) {
205
203
}
206
204
207
205
IRBuilder<> IRB (Term);
208
- Value *ElseCall = IRB.CreateCall (Else, {popSaved ()});
206
+ Value *ElseCall = IRB.CreateCall (
207
+ getDecl (Else, Intrinsic::amdgcn_else, {IntMask, IntMask}), {popSaved ()});
209
208
Value *Cond = IRB.CreateExtractValue (ElseCall, {0 });
210
209
Value *Mask = IRB.CreateExtractValue (ElseCall, {1 });
211
210
Term->setCondition (Cond);
@@ -218,7 +217,8 @@ Value *SIAnnotateControlFlow::handleLoopCondition(
218
217
Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) {
219
218
220
219
auto CreateBreak = [this , Cond, Broken](Instruction *I) -> CallInst * {
221
- return IRBuilder<>(I).CreateCall (IfBreak, {Cond, Broken});
220
+ return IRBuilder<>(I).CreateCall (
221
+ getDecl (IfBreak, Intrinsic::amdgcn_if_break, IntMask), {Cond, Broken});
222
222
};
223
223
224
224
if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
@@ -279,7 +279,8 @@ bool SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
279
279
Broken->addIncoming (PHIValue, Pred);
280
280
}
281
281
282
- CallInst *LoopCall = IRBuilder<>(Term).CreateCall (Loop, {Arg});
282
+ CallInst *LoopCall = IRBuilder<>(Term).CreateCall (
283
+ getDecl (Loop, Intrinsic::amdgcn_loop, IntMask), {Arg});
283
284
Term->setCondition (LoopCall);
284
285
285
286
push (Term->getSuccessor (0 ), Arg);
@@ -324,19 +325,20 @@ bool SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
324
325
// condition, for now just avoid copying these DebugLocs so that stepping
325
326
// out of the then/else block in a debugger doesn't step to the condition.
326
327
IRB.SetCurrentDebugLocation (DebugLoc ());
327
- IRB.CreateCall (EndCf, {Exec});
328
+ IRB.CreateCall (getDecl ( EndCf, Intrinsic::amdgcn_end_cf, IntMask) , {Exec});
328
329
}
329
330
330
331
return true ;
331
332
}
332
333
333
334
// / Annotate the control flow with intrinsics so the backend can
334
335
// / recognize if/then/else and loops.
335
- bool SIAnnotateControlFlow::run (Function &F ) {
336
+ bool SIAnnotateControlFlow::run () {
336
337
bool Changed = false ;
337
338
338
- for (df_iterator<BasicBlock *> I = df_begin (&F.getEntryBlock ()),
339
- E = df_end (&F.getEntryBlock ()); I != E; ++I) {
339
+ for (df_iterator<BasicBlock *> I = df_begin (&F->getEntryBlock ()),
340
+ E = df_end (&F->getEntryBlock ());
341
+ I != E; ++I) {
340
342
BasicBlock *BB = *I;
341
343
BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator ());
342
344
@@ -386,10 +388,9 @@ PreservedAnalyses SIAnnotateControlFlowPass::run(Function &F,
386
388
UniformityInfo &UI = FAM.getResult <UniformityInfoAnalysis>(F);
387
389
LoopInfo &LI = FAM.getResult <LoopAnalysis>(F);
388
390
389
- SIAnnotateControlFlow Impl (*F. getParent () , ST, DT, LI, UI);
391
+ SIAnnotateControlFlow Impl (F , ST, DT, LI, UI);
390
392
391
- // FIXME: We introduce dead declarations of intrinsics even if never used.
392
- bool Changed = Impl.run (F);
393
+ bool Changed = Impl.run ();
393
394
if (!Changed)
394
395
return PreservedAnalyses::all ();
395
396
@@ -426,8 +427,8 @@ class SIAnnotateControlFlowLegacy : public FunctionPass {
426
427
const TargetMachine &TM = TPC.getTM <TargetMachine>();
427
428
const GCNSubtarget &ST = TM.getSubtarget <GCNSubtarget>(F);
428
429
429
- SIAnnotateControlFlow Impl (*F. getParent () , ST, DT, LI, UI);
430
- return Impl.run (F );
430
+ SIAnnotateControlFlow Impl (F , ST, DT, LI, UI);
431
+ return Impl.run ();
431
432
}
432
433
};
433
434
0 commit comments