28 #define DEBUG_TYPE "si-annotate-control-flow"
33 typedef std::pair<BasicBlock *, Value *> StackEntry;
37 static const char *
const IfIntrinsic =
"llvm.SI.if";
38 static const char *
const ElseIntrinsic =
"llvm.SI.else";
39 static const char *
const BreakIntrinsic =
"llvm.SI.break";
40 static const char *
const IfBreakIntrinsic =
"llvm.SI.if.break";
41 static const char *
const ElseBreakIntrinsic =
"llvm.SI.else.break";
42 static const char *
const LoopIntrinsic =
"llvm.SI.loop";
43 static const char *
const EndCfIntrinsic =
"llvm.SI.end.cf";
80 void eraseIfUnused(
PHINode *Phi);
93 SIAnnotateControlFlow():
96 bool doInitialization(
Module &M)
override;
100 const char *getPassName()
const override {
101 return "SI annotate control flow";
118 bool SIAnnotateControlFlow::doInitialization(
Module &M) {
132 IfIntrinsic, ReturnStruct,
Boolean, (
Type *)
nullptr);
135 ElseIntrinsic, ReturnStruct,
Int64, (
Type *)
nullptr);
150 EndCfIntrinsic, Void,
Int64, (
Type *)
nullptr);
156 bool SIAnnotateControlFlow::isTopOfStack(
BasicBlock *BB) {
157 return !
Stack.empty() &&
Stack.back().first == BB;
161 Value *SIAnnotateControlFlow::popSaved() {
162 return Stack.pop_back_val().second;
167 Stack.push_back(std::make_pair(BB, Saved));
172 bool SIAnnotateControlFlow::isElse(
PHINode *Phi) {
190 void SIAnnotateControlFlow::eraseIfUnused(
PHINode *Phi) {
196 void SIAnnotateControlFlow::openIf(
BranchInst *Term) {
203 void SIAnnotateControlFlow::insertElse(
BranchInst *Term) {
219 if ((Phi = dyn_cast<PHINode>(Cond)) && L->
contains(Phi)) {
229 if (isa<ConstantInt>(Incoming)) {
235 Value *PhiArg = handleLoopCondition(Incoming, Broken, L);
239 BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
244 if (Incoming != BoolTrue)
263 }
else if (
Instruction *Inst = dyn_cast<Instruction>(Cond)) {
269 Insert = L->
getHeader()->getFirstNonPHIOrDbgOrLifetime();
271 Value *Args[] = { Cond, Broken };
281 void SIAnnotateControlFlow::handleLoop(
BranchInst *Term) {
289 Value *Arg = handleLoopCondition(Cond, Broken, L);
294 Broken->
addIncoming(*PI == BB ? Arg : Int64Zero, *PI);
300 void SIAnnotateControlFlow::closeControlFlow(
BasicBlock *BB) {
310 std::vector<BasicBlock*> Preds;
312 if (std::find(Latches.
begin(), Latches.
end(), *PI) == Latches.
end())
313 Preds.push_back(*PI);
324 bool SIAnnotateControlFlow::runOnFunction(
Function &
F) {
325 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
326 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
334 if (isTopOfStack(*
I))
335 closeControlFlow(*
I);
340 if (isTopOfStack(*
I))
341 closeControlFlow(*
I);
346 if (isTopOfStack(*
I)) {
348 if (Phi && Phi->
getParent() == *
I && isElse(Phi)) {
353 closeControlFlow(*
I);
358 assert(
Stack.empty());
364 return new SIAnnotateControlFlow();
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
static ConstantInt * getFalse(LLVMContext &Context)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static IntegerType * getInt1Ty(LLVMContext &C)
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
getLoopLatches - Return all loop latch blocks of this loop.
A Module instance is used to store all the information related to an LLVM module. ...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
CallInst - 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.
const Instruction & front() const
static IntegerType * getInt64Ty(LLVMContext &C)
BlockT * getHeader() const
AnalysisUsage & addRequired()
bool isUnconditional() const
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
UndefValue - 'undef' values are things that do not have specified contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Number of individual test Apply this number of consecutive mutations to each input If
BasicBlock * getSuccessor(unsigned i) const
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
Subclasses of this class are all able to terminate a basic block.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
BranchInst - Conditional or Unconditional Branch instruction.
df_iterator< T > df_end(const T &G)
This is an important base class in LLVM.
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...
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
bool contains(const LoopT *L) const
contains - Return true if the specified loop is contained within in this loop.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
This is the shared class of boolean and integer constants.
Value * getIncomingValue(unsigned i) const
getIncomingValue - Return incoming value number x
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
StructType::get - This static method is the primary way to create a literal StructType.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
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.
Function * getCalledFunction() const
getCalledFunction - 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
static ConstantInt * getTrue(LLVMContext &Context)
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.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Value * getCondition() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool hasNUsesOrMore(unsigned N) const
Return true if this value has N users or more.
void setCondition(Value *V)
LLVM Value Representation.
The legacy pass manager's analysis pass to compute loop information.
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, AliasAnalysis *AA=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, bool PreserveLCSSA=false)
SplitBlockPredecessors - This method introduces at least one new basic block into the function and mo...
Legacy analysis pass which computes a DominatorTree.
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
void setIncomingValue(unsigned i, Value *V)
const BasicBlock * getParent() const
LLVMContext & getContext() const
Get the global data context.