Wire up CFG improvements for while when the condition is known.

llvm-svn: 76522
This commit is contained in:
Mike Stump 2009-07-21 00:38:52 +00:00
parent d571c37b54
commit 23a443bea7
2 changed files with 43 additions and 6 deletions

View File

@ -701,7 +701,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(Decl* D) {
}
CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
// See if this is a known constant first.
// See if this is a known constant.
bool KnownTrue = false;
bool KnownFalse = false;
Expr::EvalResult Result;
@ -1102,6 +1102,18 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
// "while" is a control-flow statement. Thus we stop processing the current
// block.
// See if this is a known constant.
bool KnownTrue = false;
bool KnownFalse = false;
Expr::EvalResult Result;
if (W->getCond()->Evaluate(Result, *Context)
&& Result.Val.isInt()) {
if (Result.Val.getInt().getBoolValue())
KnownTrue = true;
else
KnownFalse = true;
}
CFGBlock* LoopSuccessor = NULL;
if (Block) {
@ -1170,13 +1182,21 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
return 0;
}
// Add the loop body entry as a successor to the condition.
ExitConditionBlock->addSuccessor(BodyBlock);
if (KnownFalse)
ExitConditionBlock->addSuccessor(0);
else {
// Add the loop body entry as a successor to the condition.
ExitConditionBlock->addSuccessor(BodyBlock);
}
}
// Link up the condition block with the code that follows the loop. (the
// false branch).
ExitConditionBlock->addSuccessor(LoopSuccessor);
if (KnownTrue)
ExitConditionBlock->addSuccessor(0);
else {
// Link up the condition block with the code that follows the loop. (the
// false branch).
ExitConditionBlock->addSuccessor(LoopSuccessor);
}
// There can be no more statements in the condition block since we loop back
// to this block. NULL out Block to force lazy creation of another block.

View File

@ -199,6 +199,8 @@ void f22() {
int y8 = 4;
int y9 = 4;
int y10 = 4;
int y11 = 4;
int y12 = 4;
++x; // expected-warning{{never read}}
++y1;
@ -211,6 +213,8 @@ void f22() {
++y8;
++y9;
++y10;
++y11;
++y12;
switch (j) {
case 1:
@ -265,5 +269,18 @@ void f22() {
case 9:
(void)(1 || x);
(void)y10;
break;
case 10:
while (1) {
(void)y11;
}
(void)x;
break;
case 11:
while (0) {
(void)x;
}
(void)y12;
break;
}
}