30 typedef std::pair<BasicBlock *, Value *> StackEntry;
34 static const char *
const IfIntrinsic =
"llvm.SI.if";
35 static const char *
const ElseIntrinsic =
"llvm.SI.else";
36 static const char *
const BreakIntrinsic =
"llvm.SI.break";
37 static const char *
const IfBreakIntrinsic =
"llvm.SI.if.break";
38 static const char *
const ElseBreakIntrinsic =
"llvm.SI.else.break";
39 static const char *
const LoopIntrinsic =
"llvm.SI.loop";
40 static const char *
const EndCfIntrinsic =
"llvm.SI.end.cf";
76 void eraseIfUnused(
PHINode *Phi);
82 void handleLoopCondition(
Value *Cond);
89 SIAnnotateControlFlow():
92 virtual bool doInitialization(
Module &M);
96 virtual const char *getPassName()
const {
97 return "SI annotate control flow";
113 bool SIAnnotateControlFlow::doInitialization(
Module &M) {
130 ElseIntrinsic, ReturnStruct, Int64, (
Type *)0);
133 BreakIntrinsic, Int64, Int64, (
Type *)0);
136 IfBreakIntrinsic, Int64,
Boolean, Int64, (
Type *)0);
139 ElseBreakIntrinsic, Int64, Int64, Int64, (
Type *)0);
145 EndCfIntrinsic, Void, Int64, (
Type *)0);
151 bool SIAnnotateControlFlow::isTopOfStack(
BasicBlock *BB) {
152 return !Stack.empty() && Stack.back().first == BB;
156 Value *SIAnnotateControlFlow::popSaved() {
157 return Stack.pop_back_val().second;
162 Stack.push_back(std::make_pair(BB, Saved));
167 bool SIAnnotateControlFlow::isElse(
PHINode *Phi) {
185 void SIAnnotateControlFlow::eraseIfUnused(
PHINode *Phi) {
191 void SIAnnotateControlFlow::openIf(
BranchInst *Term) {
198 void SIAnnotateControlFlow::insertElse(
BranchInst *Term) {
205 void SIAnnotateControlFlow::handleLoopCondition(
Value *Cond) {
206 if (
PHINode *Phi = dyn_cast<PHINode>(Cond)) {
211 if (isa<ConstantInt>(Incoming))
215 handleLoopCondition(Incoming);
219 BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
224 if (Incoming != BoolTrue)
233 PhiInserter.GetValueAtEndOfBlock(Parent)
236 PhiInserter.AddAvailableValue(Parent, Ret);
242 Value *Arg = PhiInserter.GetValueAtEndOfBlock(From);
244 PhiInserter.AddAvailableValue(From, Ret);
248 }
else if (
Instruction *Inst = dyn_cast<Instruction>(Cond)) {
251 Value *Args[] = { Cond, PhiInserter.GetValueAtEndOfBlock(Parent) };
253 PhiInserter.AddAvailableValue(Parent, Ret);
256 assert(0 &&
"Unhandled loop condition!");
261 void SIAnnotateControlFlow::handleLoop(
BranchInst *Term) {
265 PhiInserter.Initialize(Int64,
"");
266 PhiInserter.AddAvailableValue(Target, Broken);
270 handleLoopCondition(Cond);
273 Value *Arg = PhiInserter.GetValueAtEndOfBlock(BB);
277 Broken->
addIncoming(*PI == BB ? Arg : Int64Zero, *PI);
285 void SIAnnotateControlFlow::closeControlFlow(
BasicBlock *BB) {
291 bool SIAnnotateControlFlow::runOnFunction(
Function &
F) {
292 DT = &getAnalysis<DominatorTree>();
300 if (isTopOfStack(*
I))
301 closeControlFlow(*
I);
306 if (isTopOfStack(*
I))
307 closeControlFlow(*
I);
312 if (isTopOfStack(*
I)) {
314 if (Phi && Phi->
getParent() == *
I && isElse(Phi)) {
319 closeControlFlow(*
I);
324 assert(Stack.empty());
330 return new SIAnnotateControlFlow();
static ConstantInt * getFalse(LLVMContext &Context)
AnalysisUsage & addPreserved()
static IntegerType * getInt1Ty(LLVMContext &C)
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
Helper class for SSA formation on a set of values defined in multiple blocks.
void addIncoming(Value *V, BasicBlock *BB)
The main container class for the LLVM Intermediate Representation.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual void getAnalysisUsage(AnalysisUsage &) const
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
static IntegerType * getInt64Ty(LLVMContext &C)
AnalysisUsage & addRequired()
bool isUnconditional() const
ID
LLVM Calling Convention Representation.
BasicBlock * getSuccessor(unsigned i) const
unsigned getNumIncomingValues() const
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
LLVM Basic Block Representation.
df_iterator< T > df_end(const T &G)
LLVM Constant Representation.
Instr is a loop (backwards branch).
Interval::pred_iterator pred_begin(Interval *I)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=0)
static Type * getVoidTy(LLVMContext &C)
BasicBlock * getIncomingBlock(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
static UndefValue * get(Type *T)
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
Class for constant integers.
Value * getIncomingValue(unsigned i) const
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
Function * getCalledFunction() const
const BasicBlock & getEntryBlock() const
static ConstantInt * getTrue(LLVMContext &Context)
df_iterator< T > df_begin(const T &G)
Value * getArgOperand(unsigned i) const
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
void setCondition(Value *V)
LLVM Value Representation.
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