1 //===-- SIAnnotateControlFlow.cpp -  ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// Annotates the control flow with hardware specific intrinsics.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "AMDGPU.h"
16 #include "llvm/ADT/DepthFirstIterator.h"
17 #include "llvm/Analysis/DivergenceAnalysis.h"
18 #include "llvm/Analysis/LoopInfo.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/Dominators.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
25 #include "llvm/Transforms/Utils/SSAUpdater.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "si-annotate-control-flow"
30 
31 namespace {
32 
33 // Complex types used in this pass
34 typedef std::pair<BasicBlock *, Value *> StackEntry;
35 typedef SmallVector<StackEntry, 16> StackVector;
36 
37 // Intrinsic names the control flow is annotated with
38 static const char *const IfIntrinsic = "llvm.amdgcn.if";
39 static const char *const ElseIntrinsic = "llvm.amdgcn.else";
40 static const char *const BreakIntrinsic = "llvm.amdgcn.break";
41 static const char *const IfBreakIntrinsic = "llvm.amdgcn.if.break";
42 static const char *const ElseBreakIntrinsic = "llvm.amdgcn.else.break";
43 static const char *const LoopIntrinsic = "llvm.amdgcn.loop";
44 static const char *const EndCfIntrinsic = "llvm.amdgcn.end.cf";
45 
46 class SIAnnotateControlFlow : public FunctionPass {
47   DivergenceAnalysis *DA;
48 
49   Type *Boolean;
50   Type *Void;
51   Type *Int64;
52   Type *ReturnStruct;
53 
54   ConstantInt *BoolTrue;
55   ConstantInt *BoolFalse;
56   UndefValue *BoolUndef;
57   Constant *Int64Zero;
58 
59   Constant *If;
60   Constant *Else;
61   Constant *Break;
62   Constant *IfBreak;
63   Constant *ElseBreak;
64   Constant *Loop;
65   Constant *EndCf;
66 
67   DominatorTree *DT;
68   StackVector Stack;
69 
70   LoopInfo *LI;
71 
72   bool isTopOfStack(BasicBlock *BB);
73 
74   Value *popSaved();
75 
76   void push(BasicBlock *BB, Value *Saved);
77 
78   bool isElse(PHINode *Phi);
79 
80   void eraseIfUnused(PHINode *Phi);
81 
82   void openIf(BranchInst *Term);
83 
84   void insertElse(BranchInst *Term);
85 
86   Value *handleLoopCondition(Value *Cond, PHINode *Broken,
87                              llvm::Loop *L, BranchInst *Term);
88 
89   void handleLoop(BranchInst *Term);
90 
91   void closeControlFlow(BasicBlock *BB);
92 
93 public:
94   static char ID;
95 
96   SIAnnotateControlFlow():
97     FunctionPass(ID) { }
98 
99   bool doInitialization(Module &M) override;
100 
101   bool runOnFunction(Function &F) override;
102 
103   const char *getPassName() const override {
104     return "SI annotate control flow";
105   }
106 
107   void getAnalysisUsage(AnalysisUsage &AU) const override {
108     AU.addRequired<LoopInfoWrapperPass>();
109     AU.addRequired<DominatorTreeWrapperPass>();
110     AU.addRequired<DivergenceAnalysis>();
111     AU.addPreserved<DominatorTreeWrapperPass>();
112     FunctionPass::getAnalysisUsage(AU);
113   }
114 
115 };
116 
117 } // end anonymous namespace
118 
119 INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE,
120                       "Annotate SI Control Flow", false, false)
121 INITIALIZE_PASS_DEPENDENCY(DivergenceAnalysis)
122 INITIALIZE_PASS_END(SIAnnotateControlFlow, DEBUG_TYPE,
123                     "Annotate SI Control Flow", false, false)
124 
125 char SIAnnotateControlFlow::ID = 0;
126 
127 /// \brief Initialize all the types and constants used in the pass
128 bool SIAnnotateControlFlow::doInitialization(Module &M) {
129   LLVMContext &Context = M.getContext();
130 
131   Void = Type::getVoidTy(Context);
132   Boolean = Type::getInt1Ty(Context);
133   Int64 = Type::getInt64Ty(Context);
134   ReturnStruct = StructType::get(Boolean, Int64, (Type *)nullptr);
135 
136   BoolTrue = ConstantInt::getTrue(Context);
137   BoolFalse = ConstantInt::getFalse(Context);
138   BoolUndef = UndefValue::get(Boolean);
139   Int64Zero = ConstantInt::get(Int64, 0);
140 
141   If = M.getOrInsertFunction(
142     IfIntrinsic, ReturnStruct, Boolean, (Type *)nullptr);
143 
144   Else = M.getOrInsertFunction(
145     ElseIntrinsic, ReturnStruct, Int64, (Type *)nullptr);
146 
147   Break = M.getOrInsertFunction(
148     BreakIntrinsic, Int64, Int64, (Type *)nullptr);
149 
150   IfBreak = M.getOrInsertFunction(
151     IfBreakIntrinsic, Int64, Boolean, Int64, (Type *)nullptr);
152 
153   ElseBreak = M.getOrInsertFunction(
154     ElseBreakIntrinsic, Int64, Int64, Int64, (Type *)nullptr);
155 
156   Loop = M.getOrInsertFunction(
157     LoopIntrinsic, Boolean, Int64, (Type *)nullptr);
158 
159   EndCf = M.getOrInsertFunction(
160     EndCfIntrinsic, Void, Int64, (Type *)nullptr);
161 
162   return false;
163 }
164 
165 /// \brief Is BB the last block saved on the stack ?
166 bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) {
167   return !Stack.empty() && Stack.back().first == BB;
168 }
169 
170 /// \brief Pop the last saved value from the control flow stack
171 Value *SIAnnotateControlFlow::popSaved() {
172   return Stack.pop_back_val().second;
173 }
174 
175 /// \brief Push a BB and saved value to the control flow stack
176 void SIAnnotateControlFlow::push(BasicBlock *BB, Value *Saved) {
177   Stack.push_back(std::make_pair(BB, Saved));
178 }
179 
180 /// \brief Can the condition represented by this PHI node treated like
181 /// an "Else" block?
182 bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
183   BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock();
184   for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
185     if (Phi->getIncomingBlock(i) == IDom) {
186 
187       if (Phi->getIncomingValue(i) != BoolTrue)
188         return false;
189 
190     } else {
191       if (Phi->getIncomingValue(i) != BoolFalse)
192         return false;
193 
194     }
195   }
196   return true;
197 }
198 
199 // \brief Erase "Phi" if it is not used any more
200 void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
201   if (!Phi->hasNUsesOrMore(1))
202     Phi->eraseFromParent();
203 }
204 
205 /// \brief Open a new "If" block
206 void SIAnnotateControlFlow::openIf(BranchInst *Term) {
207   if (DA->isUniform(Term->getCondition())) {
208     return;
209   }
210   Value *Ret = CallInst::Create(If, Term->getCondition(), "", Term);
211   Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
212   push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
213 }
214 
215 /// \brief Close the last "If" block and open a new "Else" block
216 void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
217   if (DA->isUniform(Term->getCondition())) {
218     return;
219   }
220   Value *Ret = CallInst::Create(Else, popSaved(), "", Term);
221   Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
222   push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
223 }
224 
225 /// \brief Recursively handle the condition leading to a loop
226 Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken,
227                                              llvm::Loop *L, BranchInst *Term) {
228 
229   // Only search through PHI nodes which are inside the loop.  If we try this
230   // with PHI nodes that are outside of the loop, we end up inserting new PHI
231   // nodes outside of the loop which depend on values defined inside the loop.
232   // This will break the module with
233   // 'Instruction does not dominate all users!' errors.
234   PHINode *Phi = nullptr;
235   if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) {
236 
237     BasicBlock *Parent = Phi->getParent();
238     PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front());
239     Value *Ret = NewPhi;
240 
241     // Handle all non-constant incoming values first
242     for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
243       Value *Incoming = Phi->getIncomingValue(i);
244       BasicBlock *From = Phi->getIncomingBlock(i);
245       if (isa<ConstantInt>(Incoming)) {
246         NewPhi->addIncoming(Broken, From);
247         continue;
248       }
249 
250       Phi->setIncomingValue(i, BoolFalse);
251       Value *PhiArg = handleLoopCondition(Incoming, Broken, L, Term);
252       NewPhi->addIncoming(PhiArg, From);
253     }
254 
255     BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
256 
257     for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
258 
259       Value *Incoming = Phi->getIncomingValue(i);
260       if (Incoming != BoolTrue)
261         continue;
262 
263       BasicBlock *From = Phi->getIncomingBlock(i);
264       if (From == IDom) {
265         CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
266         if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
267           Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
268           Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
269           continue;
270         }
271       }
272       TerminatorInst *Insert = From->getTerminator();
273       Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
274       NewPhi->setIncomingValue(i, PhiArg);
275     }
276     eraseIfUnused(Phi);
277     return Ret;
278 
279   } else if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
280     BasicBlock *Parent = Inst->getParent();
281     Instruction *Insert;
282     if (L->contains(Inst)) {
283       Insert = Parent->getTerminator();
284     } else {
285       Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
286     }
287     Value *Args[] = { Cond, Broken };
288     return CallInst::Create(IfBreak, Args, "", Insert);
289 
290   // Insert IfBreak before TERM for constant COND.
291   } else if (isa<ConstantInt>(Cond)) {
292     Value *Args[] = { Cond, Broken };
293     return CallInst::Create(IfBreak, Args, "", Term);
294 
295   } else {
296     llvm_unreachable("Unhandled loop condition!");
297   }
298   return 0;
299 }
300 
301 /// \brief Handle a back edge (loop)
302 void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
303   if (DA->isUniform(Term->getCondition())) {
304     return;
305   }
306 
307   BasicBlock *BB = Term->getParent();
308   llvm::Loop *L = LI->getLoopFor(BB);
309   BasicBlock *Target = Term->getSuccessor(1);
310   PHINode *Broken = PHINode::Create(Int64, 0, "", &Target->front());
311 
312   Value *Cond = Term->getCondition();
313   Term->setCondition(BoolTrue);
314   Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
315 
316   for (pred_iterator PI = pred_begin(Target), PE = pred_end(Target);
317        PI != PE; ++PI) {
318 
319     Broken->addIncoming(*PI == BB ? Arg : Int64Zero, *PI);
320   }
321 
322   Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
323   push(Term->getSuccessor(0), Arg);
324 }/// \brief Close the last opened control flow
325 void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
326   llvm::Loop *L = LI->getLoopFor(BB);
327 
328   if (Stack.back().first != BB)
329     return;
330 
331   if (L && L->getHeader() == BB) {
332     // We can't insert an EndCF call into a loop header, because it will
333     // get executed on every iteration of the loop, when it should be
334     // executed only once before the loop.
335     SmallVector <BasicBlock*, 8> Latches;
336     L->getLoopLatches(Latches);
337 
338     std::vector<BasicBlock*> Preds;
339     for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
340       if (std::find(Latches.begin(), Latches.end(), *PI) == Latches.end())
341         Preds.push_back(*PI);
342     }
343     BB = llvm::SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, false);
344   }
345 
346   Value *Exec = popSaved();
347   if (!isa<UndefValue>(Exec))
348     CallInst::Create(EndCf, Exec, "", &*BB->getFirstInsertionPt());
349 }
350 
351 /// \brief Annotate the control flow with intrinsics so the backend can
352 /// recognize if/then/else and loops.
353 bool SIAnnotateControlFlow::runOnFunction(Function &F) {
354 
355   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
356   LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
357   DA = &getAnalysis<DivergenceAnalysis>();
358 
359   for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()),
360        E = df_end(&F.getEntryBlock()); I != E; ++I) {
361 
362     BranchInst *Term = dyn_cast<BranchInst>((*I)->getTerminator());
363 
364     if (!Term || Term->isUnconditional()) {
365       if (isTopOfStack(*I))
366         closeControlFlow(*I);
367 
368       continue;
369     }
370 
371     if (I.nodeVisited(Term->getSuccessor(1))) {
372       if (isTopOfStack(*I))
373         closeControlFlow(*I);
374 
375       handleLoop(Term);
376       continue;
377     }
378 
379     if (isTopOfStack(*I)) {
380       PHINode *Phi = dyn_cast<PHINode>(Term->getCondition());
381       if (Phi && Phi->getParent() == *I && isElse(Phi)) {
382         insertElse(Term);
383         eraseIfUnused(Phi);
384         continue;
385       }
386       closeControlFlow(*I);
387     }
388     openIf(Term);
389   }
390 
391   assert(Stack.empty());
392   return true;
393 }
394 
395 /// \brief Create the annotation pass
396 FunctionPass *llvm::createSIAnnotateControlFlowPass() {
397   return new SIAnnotateControlFlow();
398 }
399