forked from OSchip/llvm-project
CFG:
- Add 'LoopTarget' pointer field to CFGBlock. This records if the block is used as the 'loop back' path back to the head of a loop. - For ForStmt, encode the loop back target as the increment code. llvm-svn: 70274
This commit is contained in:
parent
5d72d41189
commit
902393b4b7
|
@ -68,6 +68,11 @@ class CFGBlock {
|
|||
/// and its successors.
|
||||
Stmt *Terminator;
|
||||
|
||||
/// LoopTarget - Some blocks are used to represent the "loop edge" to
|
||||
/// the start of a loop from within the loop body. This Stmt* will be
|
||||
/// refer to the loop statement for such blocks (and be null otherwise).
|
||||
const Stmt *LoopTarget;
|
||||
|
||||
/// BlockID - A numerical ID assigned to a CFGBlock during construction
|
||||
/// of the CFG.
|
||||
unsigned BlockID;
|
||||
|
@ -80,7 +85,7 @@ class CFGBlock {
|
|||
|
||||
public:
|
||||
explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
|
||||
BlockID(blockid) {}
|
||||
LoopTarget(NULL), BlockID(blockid) {}
|
||||
~CFGBlock() {};
|
||||
|
||||
// Statement iterators
|
||||
|
@ -149,6 +154,7 @@ public:
|
|||
void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
|
||||
void setTerminator(Stmt* Statement) { Terminator = Statement; }
|
||||
void setLabel(Stmt* Statement) { Label = Statement; }
|
||||
void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
|
||||
|
||||
Stmt* getTerminator() { return Terminator; }
|
||||
const Stmt* getTerminator() const { return Terminator; }
|
||||
|
@ -159,6 +165,8 @@ public:
|
|||
return const_cast<CFGBlock*>(this)->getTerminatorCondition();
|
||||
}
|
||||
|
||||
const Stmt *getLoopTarget() const { return LoopTarget; }
|
||||
|
||||
bool hasBinaryBranchTerminator() const;
|
||||
|
||||
Stmt* getLabel() { return Label; }
|
||||
|
|
|
@ -752,8 +752,15 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
|
|||
// Generate increment code in its own basic block. This is the target
|
||||
// of continue statements.
|
||||
Succ = Visit(I);
|
||||
}
|
||||
else {
|
||||
// No increment code. Create a special, empty, block that is used as
|
||||
// the target block for "looping back" to the start of the loop.
|
||||
assert(Succ == EntryConditionBlock);
|
||||
Succ = createBlock();
|
||||
}
|
||||
|
||||
// Finish up the increment block if it hasn't been already.
|
||||
// Finish up the increment (or empty) block if it hasn't been already.
|
||||
if (Block) {
|
||||
assert(Block == Succ);
|
||||
FinishBlock(Block);
|
||||
|
@ -761,11 +768,10 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
|
|||
}
|
||||
|
||||
ContinueTargetBlock = Succ;
|
||||
}
|
||||
else {
|
||||
// No increment code. Continues should go the the entry condition block.
|
||||
ContinueTargetBlock = EntryConditionBlock;
|
||||
}
|
||||
|
||||
// The starting block for the loop increment is the block that should
|
||||
// represent the 'loop target' for looping back to the start of the loop.
|
||||
ContinueTargetBlock->setLoopTarget(F);
|
||||
|
||||
// All breaks should go to the code following the loop.
|
||||
BreakTargetBlock = LoopSuccessor;
|
||||
|
|
Loading…
Reference in New Issue