@@ -38,6 +38,7 @@ using StackVector = SmallVector<StackEntry, 16>;
3838
3939class SIAnnotateControlFlow {
4040private:
41+ Function *F;
4142 UniformityInfo *UA;
4243
4344 Type *Boolean;
@@ -50,18 +51,18 @@ class SIAnnotateControlFlow {
5051 UndefValue *BoolUndef;
5152 Constant *IntMaskZero;
5253
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 ;
5859
5960 DominatorTree *DT;
6061 StackVector Stack;
6162
6263 LoopInfo *LI;
6364
64- void initialize (Module &M, const GCNSubtarget &ST);
65+ void initialize (const GCNSubtarget &ST);
6566
6667 bool isUniform (BranchInst *T);
6768
@@ -89,21 +90,27 @@ class SIAnnotateControlFlow {
8990
9091 bool closeControlFlow (BasicBlock *BB);
9192
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+
9299public:
93- SIAnnotateControlFlow (Module &M , const GCNSubtarget &ST, DominatorTree &DT,
100+ SIAnnotateControlFlow (Function &F , const GCNSubtarget &ST, DominatorTree &DT,
94101 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);
97104 }
98105
99- bool run (Function &F );
106+ bool run ();
100107};
101108
102109} // end anonymous namespace
103110
104111// / 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 ();
107114
108115 Void = Type::getVoidTy (Context);
109116 Boolean = Type::getInt1Ty (Context);
@@ -115,16 +122,6 @@ void SIAnnotateControlFlow::initialize(Module &M, const GCNSubtarget &ST) {
115122 BoolFalse = ConstantInt::getFalse (Context);
116123 BoolUndef = PoisonValue::get (Boolean);
117124 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});
128125}
129126
130127// / Is the branch condition uniform or did the StructurizeCFG pass
@@ -190,7 +187,8 @@ bool SIAnnotateControlFlow::openIf(BranchInst *Term) {
190187 return false ;
191188
192189 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 ()});
194192 Value *Cond = IRB.CreateExtractValue (IfCall, {0 });
195193 Value *Mask = IRB.CreateExtractValue (IfCall, {1 });
196194 Term->setCondition (Cond);
@@ -205,7 +203,8 @@ bool SIAnnotateControlFlow::insertElse(BranchInst *Term) {
205203 }
206204
207205 IRBuilder<> IRB (Term);
208- Value *ElseCall = IRB.CreateCall (Else, {popSaved ()});
206+ Value *ElseCall = IRB.CreateCall (
207+ getDecl (Else, Intrinsic::amdgcn_else, {IntMask, IntMask}), {popSaved ()});
209208 Value *Cond = IRB.CreateExtractValue (ElseCall, {0 });
210209 Value *Mask = IRB.CreateExtractValue (ElseCall, {1 });
211210 Term->setCondition (Cond);
@@ -218,7 +217,8 @@ Value *SIAnnotateControlFlow::handleLoopCondition(
218217 Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term) {
219218
220219 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});
222222 };
223223
224224 if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
@@ -279,7 +279,8 @@ bool SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
279279 Broken->addIncoming (PHIValue, Pred);
280280 }
281281
282- CallInst *LoopCall = IRBuilder<>(Term).CreateCall (Loop, {Arg});
282+ CallInst *LoopCall = IRBuilder<>(Term).CreateCall (
283+ getDecl (Loop, Intrinsic::amdgcn_loop, IntMask), {Arg});
283284 Term->setCondition (LoopCall);
284285
285286 push (Term->getSuccessor (0 ), Arg);
@@ -324,19 +325,20 @@ bool SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
324325 // condition, for now just avoid copying these DebugLocs so that stepping
325326 // out of the then/else block in a debugger doesn't step to the condition.
326327 IRB.SetCurrentDebugLocation (DebugLoc ());
327- IRB.CreateCall (EndCf, {Exec});
328+ IRB.CreateCall (getDecl ( EndCf, Intrinsic::amdgcn_end_cf, IntMask) , {Exec});
328329 }
329330
330331 return true ;
331332}
332333
333334// / Annotate the control flow with intrinsics so the backend can
334335// / recognize if/then/else and loops.
335- bool SIAnnotateControlFlow::run (Function &F ) {
336+ bool SIAnnotateControlFlow::run () {
336337 bool Changed = false ;
337338
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) {
340342 BasicBlock *BB = *I;
341343 BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator ());
342344
@@ -386,10 +388,9 @@ PreservedAnalyses SIAnnotateControlFlowPass::run(Function &F,
386388 UniformityInfo &UI = FAM.getResult <UniformityInfoAnalysis>(F);
387389 LoopInfo &LI = FAM.getResult <LoopAnalysis>(F);
388390
389- SIAnnotateControlFlow Impl (*F. getParent () , ST, DT, LI, UI);
391+ SIAnnotateControlFlow Impl (F , ST, DT, LI, UI);
390392
391- // FIXME: We introduce dead declarations of intrinsics even if never used.
392- bool Changed = Impl.run (F);
393+ bool Changed = Impl.run ();
393394 if (!Changed)
394395 return PreservedAnalyses::all ();
395396
@@ -426,8 +427,8 @@ class SIAnnotateControlFlowLegacy : public FunctionPass {
426427 const TargetMachine &TM = TPC.getTM <TargetMachine>();
427428 const GCNSubtarget &ST = TM.getSubtarget <GCNSubtarget>(F);
428429
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 ();
431432 }
432433};
433434
0 commit comments