1 //===- SIAnnotateControlFlow.cpp ------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// Annotates the control flow with hardware specific intrinsics.
12 //===----------------------------------------------------------------------===//
15 #include "GCNSubtarget.h"
16 #include "llvm/Analysis/LegacyDivergenceAnalysis.h"
17 #include "llvm/Analysis/LoopInfo.h"
18 #include "llvm/CodeGen/TargetPassConfig.h"
19 #include "llvm/IR/BasicBlock.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/Dominators.h"
22 #include "llvm/IR/IntrinsicsAMDGPU.h"
23 #include "llvm/InitializePasses.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
26 #include "llvm/Transforms/Utils/Local.h"
30 #define DEBUG_TYPE "si-annotate-control-flow"
34 // Complex types used in this pass
35 using StackEntry
= std::pair
<BasicBlock
*, Value
*>;
36 using StackVector
= SmallVector
<StackEntry
, 16>;
38 class SIAnnotateControlFlow
: public FunctionPass
{
39 LegacyDivergenceAnalysis
*DA
;
46 ConstantInt
*BoolTrue
;
47 ConstantInt
*BoolFalse
;
48 UndefValue
*BoolUndef
;
49 Constant
*IntMaskZero
;
62 void initialize(Module
&M
, const GCNSubtarget
&ST
);
64 bool isUniform(BranchInst
*T
);
66 bool isTopOfStack(BasicBlock
*BB
);
70 void push(BasicBlock
*BB
, Value
*Saved
);
72 bool isElse(PHINode
*Phi
);
74 bool hasKill(const BasicBlock
*BB
);
76 void eraseIfUnused(PHINode
*Phi
);
78 void openIf(BranchInst
*Term
);
80 void insertElse(BranchInst
*Term
);
83 handleLoopCondition(Value
*Cond
, PHINode
*Broken
, llvm::Loop
*L
,
86 void handleLoop(BranchInst
*Term
);
88 void closeControlFlow(BasicBlock
*BB
);
93 SIAnnotateControlFlow() : FunctionPass(ID
) {}
95 bool runOnFunction(Function
&F
) override
;
97 StringRef
getPassName() const override
{ return "SI annotate control flow"; }
99 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
100 AU
.addRequired
<LoopInfoWrapperPass
>();
101 AU
.addRequired
<DominatorTreeWrapperPass
>();
102 AU
.addRequired
<LegacyDivergenceAnalysis
>();
103 AU
.addPreserved
<LoopInfoWrapperPass
>();
104 AU
.addPreserved
<DominatorTreeWrapperPass
>();
105 AU
.addRequired
<TargetPassConfig
>();
106 FunctionPass::getAnalysisUsage(AU
);
110 } // end anonymous namespace
112 INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow
, DEBUG_TYPE
,
113 "Annotate SI Control Flow", false, false)
114 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
115 INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis
)
116 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig
)
117 INITIALIZE_PASS_END(SIAnnotateControlFlow
, DEBUG_TYPE
,
118 "Annotate SI Control Flow", false, false)
120 char SIAnnotateControlFlow::ID
= 0;
122 /// Initialize all the types and constants used in the pass
123 void SIAnnotateControlFlow::initialize(Module
&M
, const GCNSubtarget
&ST
) {
124 LLVMContext
&Context
= M
.getContext();
126 Void
= Type::getVoidTy(Context
);
127 Boolean
= Type::getInt1Ty(Context
);
128 IntMask
= ST
.isWave32() ? Type::getInt32Ty(Context
)
129 : Type::getInt64Ty(Context
);
130 ReturnStruct
= StructType::get(Boolean
, IntMask
);
132 BoolTrue
= ConstantInt::getTrue(Context
);
133 BoolFalse
= ConstantInt::getFalse(Context
);
134 BoolUndef
= UndefValue::get(Boolean
);
135 IntMaskZero
= ConstantInt::get(IntMask
, 0);
137 If
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_if
, { IntMask
});
138 Else
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_else
,
139 { IntMask
, IntMask
});
140 IfBreak
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_if_break
,
142 Loop
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_loop
, { IntMask
});
143 EndCf
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_end_cf
, { IntMask
});
146 /// Is the branch condition uniform or did the StructurizeCFG pass
147 /// consider it as such?
148 bool SIAnnotateControlFlow::isUniform(BranchInst
*T
) {
149 return DA
->isUniform(T
) ||
150 T
->getMetadata("structurizecfg.uniform") != nullptr;
153 /// Is BB the last block saved on the stack ?
154 bool SIAnnotateControlFlow::isTopOfStack(BasicBlock
*BB
) {
155 return !Stack
.empty() && Stack
.back().first
== BB
;
158 /// Pop the last saved value from the control flow stack
159 Value
*SIAnnotateControlFlow::popSaved() {
160 return Stack
.pop_back_val().second
;
163 /// Push a BB and saved value to the control flow stack
164 void SIAnnotateControlFlow::push(BasicBlock
*BB
, Value
*Saved
) {
165 Stack
.push_back(std::make_pair(BB
, Saved
));
168 /// Can the condition represented by this PHI node treated like
170 bool SIAnnotateControlFlow::isElse(PHINode
*Phi
) {
171 BasicBlock
*IDom
= DT
->getNode(Phi
->getParent())->getIDom()->getBlock();
172 for (unsigned i
= 0, e
= Phi
->getNumIncomingValues(); i
!= e
; ++i
) {
173 if (Phi
->getIncomingBlock(i
) == IDom
) {
175 if (Phi
->getIncomingValue(i
) != BoolTrue
)
179 if (Phi
->getIncomingValue(i
) != BoolFalse
)
187 bool SIAnnotateControlFlow::hasKill(const BasicBlock
*BB
) {
188 for (const Instruction
&I
: *BB
) {
189 if (const CallInst
*CI
= dyn_cast
<CallInst
>(&I
))
190 if (CI
->getIntrinsicID() == Intrinsic::amdgcn_kill
)
196 // Erase "Phi" if it is not used any more
197 void SIAnnotateControlFlow::eraseIfUnused(PHINode
*Phi
) {
198 if (RecursivelyDeleteDeadPHINode(Phi
)) {
199 LLVM_DEBUG(dbgs() << "Erased unused condition phi\n");
203 /// Open a new "If" block
204 void SIAnnotateControlFlow::openIf(BranchInst
*Term
) {
208 Value
*Ret
= CallInst::Create(If
, Term
->getCondition(), "", Term
);
209 Term
->setCondition(ExtractValueInst::Create(Ret
, 0, "", Term
));
210 push(Term
->getSuccessor(1), ExtractValueInst::Create(Ret
, 1, "", Term
));
213 /// Close the last "If" block and open a new "Else" block
214 void SIAnnotateControlFlow::insertElse(BranchInst
*Term
) {
215 if (isUniform(Term
)) {
218 Value
*Ret
= CallInst::Create(Else
, popSaved(), "", Term
);
219 Term
->setCondition(ExtractValueInst::Create(Ret
, 0, "", Term
));
220 push(Term
->getSuccessor(1), ExtractValueInst::Create(Ret
, 1, "", Term
));
223 /// Recursively handle the condition leading to a loop
224 Value
*SIAnnotateControlFlow::handleLoopCondition(
225 Value
*Cond
, PHINode
*Broken
, llvm::Loop
*L
, BranchInst
*Term
) {
226 if (Instruction
*Inst
= dyn_cast
<Instruction
>(Cond
)) {
227 BasicBlock
*Parent
= Inst
->getParent();
229 if (L
->contains(Inst
)) {
230 Insert
= Parent
->getTerminator();
232 Insert
= L
->getHeader()->getFirstNonPHIOrDbgOrLifetime();
235 Value
*Args
[] = { Cond
, Broken
};
236 return CallInst::Create(IfBreak
, Args
, "", Insert
);
239 // Insert IfBreak in the loop header TERM for constant COND other than true.
240 if (isa
<Constant
>(Cond
)) {
241 Instruction
*Insert
= Cond
== BoolTrue
?
242 Term
: L
->getHeader()->getTerminator();
244 Value
*Args
[] = { Cond
, Broken
};
245 return CallInst::Create(IfBreak
, Args
, "", Insert
);
248 llvm_unreachable("Unhandled loop condition!");
251 /// Handle a back edge (loop)
252 void SIAnnotateControlFlow::handleLoop(BranchInst
*Term
) {
256 BasicBlock
*BB
= Term
->getParent();
257 llvm::Loop
*L
= LI
->getLoopFor(BB
);
261 BasicBlock
*Target
= Term
->getSuccessor(1);
262 PHINode
*Broken
= PHINode::Create(IntMask
, 0, "phi.broken", &Target
->front());
264 Value
*Cond
= Term
->getCondition();
265 Term
->setCondition(BoolTrue
);
266 Value
*Arg
= handleLoopCondition(Cond
, Broken
, L
, Term
);
268 for (BasicBlock
*Pred
: predecessors(Target
)) {
269 Value
*PHIValue
= IntMaskZero
;
270 if (Pred
== BB
) // Remember the value of the previous iteration.
272 // If the backedge from Pred to Target could be executed before the exit
273 // of the loop at BB, it should not reset or change "Broken", which keeps
274 // track of the number of threads exited the loop at BB.
275 else if (L
->contains(Pred
) && DT
->dominates(Pred
, BB
))
277 Broken
->addIncoming(PHIValue
, Pred
);
280 Term
->setCondition(CallInst::Create(Loop
, Arg
, "", Term
));
282 push(Term
->getSuccessor(0), Arg
);
285 /// Close the last opened control flow
286 void SIAnnotateControlFlow::closeControlFlow(BasicBlock
*BB
) {
287 llvm::Loop
*L
= LI
->getLoopFor(BB
);
289 assert(Stack
.back().first
== BB
);
291 if (L
&& L
->getHeader() == BB
) {
292 // We can't insert an EndCF call into a loop header, because it will
293 // get executed on every iteration of the loop, when it should be
294 // executed only once before the loop.
295 SmallVector
<BasicBlock
*, 8> Latches
;
296 L
->getLoopLatches(Latches
);
298 SmallVector
<BasicBlock
*, 2> Preds
;
299 for (BasicBlock
*Pred
: predecessors(BB
)) {
300 if (!is_contained(Latches
, Pred
))
301 Preds
.push_back(Pred
);
304 BB
= SplitBlockPredecessors(BB
, Preds
, "endcf.split", DT
, LI
, nullptr,
308 Value
*Exec
= popSaved();
309 Instruction
*FirstInsertionPt
= &*BB
->getFirstInsertionPt();
310 if (!isa
<UndefValue
>(Exec
) && !isa
<UnreachableInst
>(FirstInsertionPt
)) {
311 Instruction
*ExecDef
= cast
<Instruction
>(Exec
);
312 BasicBlock
*DefBB
= ExecDef
->getParent();
313 if (!DT
->dominates(DefBB
, BB
)) {
314 // Split edge to make Def dominate Use
315 FirstInsertionPt
= &*SplitEdge(DefBB
, BB
, DT
, LI
)->getFirstInsertionPt();
317 CallInst::Create(EndCf
, Exec
, "", FirstInsertionPt
);
321 /// Annotate the control flow with intrinsics so the backend can
322 /// recognize if/then/else and loops.
323 bool SIAnnotateControlFlow::runOnFunction(Function
&F
) {
324 DT
= &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
325 LI
= &getAnalysis
<LoopInfoWrapperPass
>().getLoopInfo();
326 DA
= &getAnalysis
<LegacyDivergenceAnalysis
>();
327 TargetPassConfig
&TPC
= getAnalysis
<TargetPassConfig
>();
328 const TargetMachine
&TM
= TPC
.getTM
<TargetMachine
>();
330 initialize(*F
.getParent(), TM
.getSubtarget
<GCNSubtarget
>(F
));
331 for (df_iterator
<BasicBlock
*> I
= df_begin(&F
.getEntryBlock()),
332 E
= df_end(&F
.getEntryBlock()); I
!= E
; ++I
) {
334 BranchInst
*Term
= dyn_cast
<BranchInst
>(BB
->getTerminator());
336 if (!Term
|| Term
->isUnconditional()) {
337 if (isTopOfStack(BB
))
338 closeControlFlow(BB
);
343 if (I
.nodeVisited(Term
->getSuccessor(1))) {
344 if (isTopOfStack(BB
))
345 closeControlFlow(BB
);
347 if (DT
->dominates(Term
->getSuccessor(1), BB
))
352 if (isTopOfStack(BB
)) {
353 PHINode
*Phi
= dyn_cast
<PHINode
>(Term
->getCondition());
354 if (Phi
&& Phi
->getParent() == BB
&& isElse(Phi
) && !hasKill(BB
)) {
360 closeControlFlow(BB
);
366 if (!Stack
.empty()) {
367 // CFG was probably not structured.
368 report_fatal_error("failed to annotate CFG");
374 /// Create the annotation pass
375 FunctionPass
*llvm::createSIAnnotateControlFlowPass() {
376 return new SIAnnotateControlFlow();