LLVM  4.0.0
SIAnnotateControlFlow.cpp
Go to the documentation of this file.
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"
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"
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 {
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 isUniform(BranchInst *T);
73 
74  bool isTopOfStack(BasicBlock *BB);
75 
76  Value *popSaved();
77 
78  void push(BasicBlock *BB, Value *Saved);
79 
80  bool isElse(PHINode *Phi);
81 
82  void eraseIfUnused(PHINode *Phi);
83 
84  void openIf(BranchInst *Term);
85 
86  void insertElse(BranchInst *Term);
87 
88  Value *handleLoopCondition(Value *Cond, PHINode *Broken,
89  llvm::Loop *L, BranchInst *Term);
90 
91  void handleLoop(BranchInst *Term);
92 
93  void closeControlFlow(BasicBlock *BB);
94 
95 public:
96  static char ID;
97 
98  SIAnnotateControlFlow():
99  FunctionPass(ID) { }
100 
101  bool doInitialization(Module &M) override;
102 
103  bool runOnFunction(Function &F) override;
104 
105  StringRef getPassName() const override { return "SI annotate control flow"; }
106 
107  void getAnalysisUsage(AnalysisUsage &AU) const override {
113  }
114 
115 };
116 
117 } // end anonymous namespace
118 
119 INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE,
120  "Annotate SI Control Flow", false, false)
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  cast<Function>(Break)->setDoesNotAccessMemory();
150 
151  IfBreak = M.getOrInsertFunction(
152  IfBreakIntrinsic, Int64, Boolean, Int64, (Type *)nullptr);
153  cast<Function>(IfBreak)->setDoesNotAccessMemory();;
154 
155  ElseBreak = M.getOrInsertFunction(
156  ElseBreakIntrinsic, Int64, Int64, Int64, (Type *)nullptr);
157  cast<Function>(ElseBreak)->setDoesNotAccessMemory();
158 
159  Loop = M.getOrInsertFunction(
160  LoopIntrinsic, Boolean, Int64, (Type *)nullptr);
161 
162  EndCf = M.getOrInsertFunction(
163  EndCfIntrinsic, Void, Int64, (Type *)nullptr);
164 
165  return false;
166 }
167 
168 /// \brief Is the branch condition uniform or did the StructurizeCFG pass
169 /// consider it as such?
170 bool SIAnnotateControlFlow::isUniform(BranchInst *T) {
171  return DA->isUniform(T->getCondition()) ||
172  T->getMetadata("structurizecfg.uniform") != nullptr;
173 }
174 
175 /// \brief Is BB the last block saved on the stack ?
176 bool SIAnnotateControlFlow::isTopOfStack(BasicBlock *BB) {
177  return !Stack.empty() && Stack.back().first == BB;
178 }
179 
180 /// \brief Pop the last saved value from the control flow stack
181 Value *SIAnnotateControlFlow::popSaved() {
182  return Stack.pop_back_val().second;
183 }
184 
185 /// \brief Push a BB and saved value to the control flow stack
186 void SIAnnotateControlFlow::push(BasicBlock *BB, Value *Saved) {
187  Stack.push_back(std::make_pair(BB, Saved));
188 }
189 
190 /// \brief Can the condition represented by this PHI node treated like
191 /// an "Else" block?
192 bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
193  BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock();
194  for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
195  if (Phi->getIncomingBlock(i) == IDom) {
196 
197  if (Phi->getIncomingValue(i) != BoolTrue)
198  return false;
199 
200  } else {
201  if (Phi->getIncomingValue(i) != BoolFalse)
202  return false;
203 
204  }
205  }
206  return true;
207 }
208 
209 // \brief Erase "Phi" if it is not used any more
210 void SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
211  if (!Phi->hasNUsesOrMore(1))
212  Phi->eraseFromParent();
213 }
214 
215 /// \brief Open a new "If" block
216 void SIAnnotateControlFlow::openIf(BranchInst *Term) {
217  if (isUniform(Term)) {
218  return;
219  }
220  Value *Ret = CallInst::Create(If, Term->getCondition(), "", Term);
221  Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
222  push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
223 }
224 
225 /// \brief Close the last "If" block and open a new "Else" block
226 void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
227  if (isUniform(Term)) {
228  return;
229  }
230  Value *Ret = CallInst::Create(Else, popSaved(), "", Term);
231  Term->setCondition(ExtractValueInst::Create(Ret, 0, "", Term));
232  push(Term->getSuccessor(1), ExtractValueInst::Create(Ret, 1, "", Term));
233 }
234 
235 /// \brief Recursively handle the condition leading to a loop
236 Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken,
237  llvm::Loop *L, BranchInst *Term) {
238 
239  // Only search through PHI nodes which are inside the loop. If we try this
240  // with PHI nodes that are outside of the loop, we end up inserting new PHI
241  // nodes outside of the loop which depend on values defined inside the loop.
242  // This will break the module with
243  // 'Instruction does not dominate all users!' errors.
244  PHINode *Phi = nullptr;
245  if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) {
246 
247  BasicBlock *Parent = Phi->getParent();
248  PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front());
249  Value *Ret = NewPhi;
250 
251  // Handle all non-constant incoming values first
252  for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
253  Value *Incoming = Phi->getIncomingValue(i);
254  BasicBlock *From = Phi->getIncomingBlock(i);
255  if (isa<ConstantInt>(Incoming)) {
256  NewPhi->addIncoming(Broken, From);
257  continue;
258  }
259 
260  Phi->setIncomingValue(i, BoolFalse);
261  Value *PhiArg = handleLoopCondition(Incoming, Broken, L, Term);
262  NewPhi->addIncoming(PhiArg, From);
263  }
264 
265  BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
266 
267  for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
268 
269  Value *Incoming = Phi->getIncomingValue(i);
270  if (Incoming != BoolTrue)
271  continue;
272 
273  BasicBlock *From = Phi->getIncomingBlock(i);
274  if (From == IDom) {
275  // We're in the following situation:
276  // IDom/From
277  // | \
278  // | If-block
279  // | /
280  // Parent
281  // where we want to break out of the loop if the If-block is not taken.
282  // Due to the depth-first traversal, there should be an end.cf
283  // intrinsic in Parent, and we insert an else.break before it.
284  //
285  // Note that the end.cf need not be the first non-phi instruction
286  // of parent, particularly when we're dealing with a multi-level
287  // break, but it should occur within a group of intrinsic calls
288  // at the beginning of the block.
289  CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
290  while (OldEnd && OldEnd->getCalledFunction() != EndCf)
291  OldEnd = dyn_cast<CallInst>(OldEnd->getNextNode());
292  if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
293  Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
294  Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
295  continue;
296  }
297  }
298  TerminatorInst *Insert = From->getTerminator();
299  Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
300  NewPhi->setIncomingValue(i, PhiArg);
301  }
302  eraseIfUnused(Phi);
303  return Ret;
304 
305  } else if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
306  BasicBlock *Parent = Inst->getParent();
307  Instruction *Insert;
308  if (L->contains(Inst)) {
309  Insert = Parent->getTerminator();
310  } else {
311  Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
312  }
313  Value *Args[] = { Cond, Broken };
314  return CallInst::Create(IfBreak, Args, "", Insert);
315 
316  // Insert IfBreak before TERM for constant COND.
317  } else if (isa<ConstantInt>(Cond)) {
318  Value *Args[] = { Cond, Broken };
319  return CallInst::Create(IfBreak, Args, "", Term);
320 
321  } else {
322  llvm_unreachable("Unhandled loop condition!");
323  }
324  return nullptr;
325 }
326 
327 /// \brief Handle a back edge (loop)
328 void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
329  if (isUniform(Term)) {
330  return;
331  }
332 
333  BasicBlock *BB = Term->getParent();
334  llvm::Loop *L = LI->getLoopFor(BB);
335  if (!L)
336  return;
337  BasicBlock *Target = Term->getSuccessor(1);
338  PHINode *Broken = PHINode::Create(Int64, 0, "", &Target->front());
339 
340  Value *Cond = Term->getCondition();
341  Term->setCondition(BoolTrue);
342  Value *Arg = handleLoopCondition(Cond, Broken, L, Term);
343 
344  for (pred_iterator PI = pred_begin(Target), PE = pred_end(Target);
345  PI != PE; ++PI) {
346 
347  Broken->addIncoming(*PI == BB ? Arg : Int64Zero, *PI);
348  }
349 
350  Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
351  push(Term->getSuccessor(0), Arg);
352 }/// \brief Close the last opened control flow
353 void SIAnnotateControlFlow::closeControlFlow(BasicBlock *BB) {
354  llvm::Loop *L = LI->getLoopFor(BB);
355 
356  assert(Stack.back().first == BB);
357 
358  if (L && L->getHeader() == BB) {
359  // We can't insert an EndCF call into a loop header, because it will
360  // get executed on every iteration of the loop, when it should be
361  // executed only once before the loop.
363  L->getLoopLatches(Latches);
364 
365  std::vector<BasicBlock*> Preds;
366  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
367  if (!is_contained(Latches, *PI))
368  Preds.push_back(*PI);
369  }
370  BB = llvm::SplitBlockPredecessors(BB, Preds, "endcf.split", DT, LI, false);
371  }
372 
373  Value *Exec = popSaved();
374  if (!isa<UndefValue>(Exec))
375  CallInst::Create(EndCf, Exec, "", &*BB->getFirstInsertionPt());
376 }
377 
378 /// \brief Annotate the control flow with intrinsics so the backend can
379 /// recognize if/then/else and loops.
380 bool SIAnnotateControlFlow::runOnFunction(Function &F) {
381 
382  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
383  LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
384  DA = &getAnalysis<DivergenceAnalysis>();
385 
387  E = df_end(&F.getEntryBlock()); I != E; ++I) {
388 
389  BranchInst *Term = dyn_cast<BranchInst>((*I)->getTerminator());
390 
391  if (!Term || Term->isUnconditional()) {
392  if (isTopOfStack(*I))
393  closeControlFlow(*I);
394 
395  continue;
396  }
397 
398  if (I.nodeVisited(Term->getSuccessor(1))) {
399  if (isTopOfStack(*I))
400  closeControlFlow(*I);
401 
402  handleLoop(Term);
403  continue;
404  }
405 
406  if (isTopOfStack(*I)) {
407  PHINode *Phi = dyn_cast<PHINode>(Term->getCondition());
408  if (Phi && Phi->getParent() == *I && isElse(Phi)) {
409  insertElse(Term);
410  eraseIfUnused(Phi);
411  continue;
412  }
413  closeControlFlow(*I);
414  }
415  openIf(Term);
416  }
417 
418  assert(Stack.empty());
419  return true;
420 }
421 
422 /// \brief Create the annotation pass
424  return new SIAnnotateControlFlow();
425 }
MachineLoop * L
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:76
static ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:513
Annotate SI Control false
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static IntegerType * getInt1Ty(LLVMContext &C)
Definition: Type.cpp:166
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
LLVMContext & Context
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:274
size_t i
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
Return all loop latch blocks of this loop.
Definition: LoopInfo.h:250
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:84
This class represents a function call, abstracting a target machine's calling convention.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:100
const Instruction & front() const
Definition: BasicBlock.h:240
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:170
BlockT * getHeader() const
Definition: LoopInfo.h:102
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
bool isUnconditional() const
'undef' values are things that do not have specified contents.
Definition: Constants.h:1258
#define F(x, y, z)
Definition: MD5.cpp:51
BasicBlock * getSuccessor(unsigned i) const
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:96
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Subclasses of this class are all able to terminate a basic block.
Definition: InstrTypes.h:52
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
Conditional or Unconditional Branch instruction.
static ExtractValueInst * Create(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
df_iterator< T > df_end(const T &G)
This is an important base class in LLVM.
Definition: Constant.h:42
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Definition: Interval.h:116
unsigned char Boolean
Definition: ConvertUTF.h:112
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:154
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Annotate SI Control Flow
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Definition: LoopInfo.h:109
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
Interval::pred_iterator pred_end(Interval *I)
Definition: Interval.h:119
static bool setDoesNotAccessMemory(Function &F)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1337
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is the shared class of boolean and integer constants.
Definition: Constants.h:88
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:330
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > Bundles=None, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Module.h This file contains the declarations for the Module class.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:175
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:558
Function * getCalledFunction() const
Return the function called, or null if this is an indirect function invocation.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
const BasicBlock & getEntryBlock() const
Definition: Function.h:519
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:506
df_iterator< T > df_begin(const T &G)
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
Target - Wrapper for Target specific information.
Maximum length of the test input If
Value * getCondition() const
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:368
#define I(x, y, z)
Definition: MD5.cpp:54
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
Definition: Value.cpp:107
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
void setCondition(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:71
The legacy pass manager's analysis pass to compute loop information.
Definition: LoopInfo.h:831
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:217
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:209
void setIncomingValue(unsigned i, Value *V)
INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE,"Annotate SI Control Flow", false, false) INITIALIZE_PASS_END(SIAnnotateControlFlow
#define DEBUG_TYPE
const BasicBlock * getParent() const
Definition: Instruction.h:62
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:783