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 "AMDGPUSubtarget.h"
16 #include "llvm/ADT/DepthFirstIterator.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Analysis/LegacyDivergenceAnalysis.h"
20 #include "llvm/Analysis/LoopInfo.h"
21 #include "llvm/CodeGen/TargetPassConfig.h"
22 #include "llvm/IR/BasicBlock.h"
23 #include "llvm/IR/CFG.h"
24 #include "llvm/IR/Constant.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/Dominators.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/Instruction.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/Module.h"
33 #include "llvm/IR/Type.h"
34 #include "llvm/IR/ValueHandle.h"
35 #include "llvm/Pass.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/Support/raw_ostream.h"
40 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
41 #include "llvm/Transforms/Utils/Local.h"
47 #define DEBUG_TYPE "si-annotate-control-flow"
51 // Complex types used in this pass
52 using StackEntry
= std::pair
<BasicBlock
*, Value
*>;
53 using StackVector
= SmallVector
<StackEntry
, 16>;
55 class SIAnnotateControlFlow
: public FunctionPass
{
56 LegacyDivergenceAnalysis
*DA
;
63 ConstantInt
*BoolTrue
;
64 ConstantInt
*BoolFalse
;
65 UndefValue
*BoolUndef
;
66 Constant
*IntMaskZero
;
79 void initialize(Module
&M
, const GCNSubtarget
&ST
);
81 bool isUniform(BranchInst
*T
);
83 bool isTopOfStack(BasicBlock
*BB
);
87 void push(BasicBlock
*BB
, Value
*Saved
);
89 bool isElse(PHINode
*Phi
);
91 void eraseIfUnused(PHINode
*Phi
);
93 void openIf(BranchInst
*Term
);
95 void insertElse(BranchInst
*Term
);
98 handleLoopCondition(Value
*Cond
, PHINode
*Broken
, llvm::Loop
*L
,
101 void handleLoop(BranchInst
*Term
);
103 void closeControlFlow(BasicBlock
*BB
);
108 SIAnnotateControlFlow() : FunctionPass(ID
) {}
110 bool runOnFunction(Function
&F
) override
;
112 StringRef
getPassName() const override
{ return "SI annotate control flow"; }
114 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
115 AU
.addRequired
<LoopInfoWrapperPass
>();
116 AU
.addRequired
<DominatorTreeWrapperPass
>();
117 AU
.addRequired
<LegacyDivergenceAnalysis
>();
118 AU
.addPreserved
<DominatorTreeWrapperPass
>();
119 AU
.addRequired
<TargetPassConfig
>();
120 FunctionPass::getAnalysisUsage(AU
);
124 } // end anonymous namespace
126 INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow
, DEBUG_TYPE
,
127 "Annotate SI Control Flow", false, false)
128 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass
)
129 INITIALIZE_PASS_DEPENDENCY(LegacyDivergenceAnalysis
)
130 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig
)
131 INITIALIZE_PASS_END(SIAnnotateControlFlow
, DEBUG_TYPE
,
132 "Annotate SI Control Flow", false, false)
134 char SIAnnotateControlFlow::ID
= 0;
136 /// Initialize all the types and constants used in the pass
137 void SIAnnotateControlFlow::initialize(Module
&M
, const GCNSubtarget
&ST
) {
138 LLVMContext
&Context
= M
.getContext();
140 Void
= Type::getVoidTy(Context
);
141 Boolean
= Type::getInt1Ty(Context
);
142 IntMask
= ST
.isWave32() ? Type::getInt32Ty(Context
)
143 : Type::getInt64Ty(Context
);
144 ReturnStruct
= StructType::get(Boolean
, IntMask
);
146 BoolTrue
= ConstantInt::getTrue(Context
);
147 BoolFalse
= ConstantInt::getFalse(Context
);
148 BoolUndef
= UndefValue::get(Boolean
);
149 IntMaskZero
= ConstantInt::get(IntMask
, 0);
151 If
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_if
, { IntMask
});
152 Else
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_else
,
153 { IntMask
, IntMask
});
154 IfBreak
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_if_break
,
155 { IntMask
, IntMask
});
156 Loop
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_loop
, { IntMask
});
157 EndCf
= Intrinsic::getDeclaration(&M
, Intrinsic::amdgcn_end_cf
, { IntMask
});
160 /// Is the branch condition uniform or did the StructurizeCFG pass
161 /// consider it as such?
162 bool SIAnnotateControlFlow::isUniform(BranchInst
*T
) {
163 return DA
->isUniform(T
) ||
164 T
->getMetadata("structurizecfg.uniform") != nullptr;
167 /// Is BB the last block saved on the stack ?
168 bool SIAnnotateControlFlow::isTopOfStack(BasicBlock
*BB
) {
169 return !Stack
.empty() && Stack
.back().first
== BB
;
172 /// Pop the last saved value from the control flow stack
173 Value
*SIAnnotateControlFlow::popSaved() {
174 return Stack
.pop_back_val().second
;
177 /// Push a BB and saved value to the control flow stack
178 void SIAnnotateControlFlow::push(BasicBlock
*BB
, Value
*Saved
) {
179 Stack
.push_back(std::make_pair(BB
, Saved
));
182 /// Can the condition represented by this PHI node treated like
184 bool SIAnnotateControlFlow::isElse(PHINode
*Phi
) {
185 BasicBlock
*IDom
= DT
->getNode(Phi
->getParent())->getIDom()->getBlock();
186 for (unsigned i
= 0, e
= Phi
->getNumIncomingValues(); i
!= e
; ++i
) {
187 if (Phi
->getIncomingBlock(i
) == IDom
) {
189 if (Phi
->getIncomingValue(i
) != BoolTrue
)
193 if (Phi
->getIncomingValue(i
) != BoolFalse
)
201 // Erase "Phi" if it is not used any more
202 void SIAnnotateControlFlow::eraseIfUnused(PHINode
*Phi
) {
203 if (RecursivelyDeleteDeadPHINode(Phi
)) {
204 LLVM_DEBUG(dbgs() << "Erased unused condition phi\n");
208 /// Open a new "If" block
209 void SIAnnotateControlFlow::openIf(BranchInst
*Term
) {
213 Value
*Ret
= CallInst::Create(If
, Term
->getCondition(), "", Term
);
214 Term
->setCondition(ExtractValueInst::Create(Ret
, 0, "", Term
));
215 push(Term
->getSuccessor(1), ExtractValueInst::Create(Ret
, 1, "", Term
));
218 /// Close the last "If" block and open a new "Else" block
219 void SIAnnotateControlFlow::insertElse(BranchInst
*Term
) {
220 if (isUniform(Term
)) {
223 Value
*Ret
= CallInst::Create(Else
, popSaved(), "", Term
);
224 Term
->setCondition(ExtractValueInst::Create(Ret
, 0, "", Term
));
225 push(Term
->getSuccessor(1), ExtractValueInst::Create(Ret
, 1, "", Term
));
228 /// Recursively handle the condition leading to a loop
229 Value
*SIAnnotateControlFlow::handleLoopCondition(
230 Value
*Cond
, PHINode
*Broken
, llvm::Loop
*L
, BranchInst
*Term
) {
231 if (Instruction
*Inst
= dyn_cast
<Instruction
>(Cond
)) {
232 BasicBlock
*Parent
= Inst
->getParent();
234 if (L
->contains(Inst
)) {
235 Insert
= Parent
->getTerminator();
237 Insert
= L
->getHeader()->getFirstNonPHIOrDbgOrLifetime();
240 Value
*Args
[] = { Cond
, Broken
};
241 return CallInst::Create(IfBreak
, Args
, "", Insert
);
244 // Insert IfBreak in the loop header TERM for constant COND other than true.
245 if (isa
<Constant
>(Cond
)) {
246 Instruction
*Insert
= Cond
== BoolTrue
?
247 Term
: L
->getHeader()->getTerminator();
249 Value
*Args
[] = { Cond
, Broken
};
250 return CallInst::Create(IfBreak
, Args
, "", Insert
);
253 llvm_unreachable("Unhandled loop condition!");
256 /// Handle a back edge (loop)
257 void SIAnnotateControlFlow::handleLoop(BranchInst
*Term
) {
261 BasicBlock
*BB
= Term
->getParent();
262 llvm::Loop
*L
= LI
->getLoopFor(BB
);
266 BasicBlock
*Target
= Term
->getSuccessor(1);
267 PHINode
*Broken
= PHINode::Create(IntMask
, 0, "phi.broken", &Target
->front());
269 Value
*Cond
= Term
->getCondition();
270 Term
->setCondition(BoolTrue
);
271 Value
*Arg
= handleLoopCondition(Cond
, Broken
, L
, Term
);
273 for (BasicBlock
*Pred
: predecessors(Target
)) {
274 Value
*PHIValue
= IntMaskZero
;
275 if (Pred
== BB
) // Remember the value of the previous iteration.
277 // If the backedge from Pred to Target could be executed before the exit
278 // of the loop at BB, it should not reset or change "Broken", which keeps
279 // track of the number of threads exited the loop at BB.
280 else if (L
->contains(Pred
) && DT
->dominates(Pred
, BB
))
282 Broken
->addIncoming(PHIValue
, Pred
);
285 Term
->setCondition(CallInst::Create(Loop
, Arg
, "", Term
));
287 push(Term
->getSuccessor(0), Arg
);
290 /// Close the last opened control flow
291 void SIAnnotateControlFlow::closeControlFlow(BasicBlock
*BB
) {
292 llvm::Loop
*L
= LI
->getLoopFor(BB
);
294 assert(Stack
.back().first
== BB
);
296 if (L
&& L
->getHeader() == BB
) {
297 // We can't insert an EndCF call into a loop header, because it will
298 // get executed on every iteration of the loop, when it should be
299 // executed only once before the loop.
300 SmallVector
<BasicBlock
*, 8> Latches
;
301 L
->getLoopLatches(Latches
);
303 SmallVector
<BasicBlock
*, 2> Preds
;
304 for (BasicBlock
*Pred
: predecessors(BB
)) {
305 if (!is_contained(Latches
, Pred
))
306 Preds
.push_back(Pred
);
309 BB
= SplitBlockPredecessors(BB
, Preds
, "endcf.split", DT
, LI
, nullptr,
313 Value
*Exec
= popSaved();
314 Instruction
*FirstInsertionPt
= &*BB
->getFirstInsertionPt();
315 if (!isa
<UndefValue
>(Exec
) && !isa
<UnreachableInst
>(FirstInsertionPt
))
316 CallInst::Create(EndCf
, Exec
, "", FirstInsertionPt
);
319 /// Annotate the control flow with intrinsics so the backend can
320 /// recognize if/then/else and loops.
321 bool SIAnnotateControlFlow::runOnFunction(Function
&F
) {
322 DT
= &getAnalysis
<DominatorTreeWrapperPass
>().getDomTree();
323 LI
= &getAnalysis
<LoopInfoWrapperPass
>().getLoopInfo();
324 DA
= &getAnalysis
<LegacyDivergenceAnalysis
>();
325 TargetPassConfig
&TPC
= getAnalysis
<TargetPassConfig
>();
326 const TargetMachine
&TM
= TPC
.getTM
<TargetMachine
>();
328 initialize(*F
.getParent(), TM
.getSubtarget
<GCNSubtarget
>(F
));
330 for (df_iterator
<BasicBlock
*> I
= df_begin(&F
.getEntryBlock()),
331 E
= df_end(&F
.getEntryBlock()); I
!= E
; ++I
) {
333 BranchInst
*Term
= dyn_cast
<BranchInst
>(BB
->getTerminator());
335 if (!Term
|| Term
->isUnconditional()) {
336 if (isTopOfStack(BB
))
337 closeControlFlow(BB
);
342 if (I
.nodeVisited(Term
->getSuccessor(1))) {
343 if (isTopOfStack(BB
))
344 closeControlFlow(BB
);
350 if (isTopOfStack(BB
)) {
351 PHINode
*Phi
= dyn_cast
<PHINode
>(Term
->getCondition());
352 if (Phi
&& Phi
->getParent() == BB
&& isElse(Phi
)) {
358 closeControlFlow(BB
);
364 if (!Stack
.empty()) {
365 // CFG was probably not structured.
366 report_fatal_error("failed to annotate CFG");
372 /// Create the annotation pass
373 FunctionPass
*llvm::createSIAnnotateControlFlowPass() {
374 return new SIAnnotateControlFlow();