aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-07-21 01:12:51 +0000
committerMike Stump <mrs@apple.com>2009-07-21 01:12:51 +0000
commitfefb9f7009702befaf715e7a8debc9505c3c8634 (patch)
treed801458ff83eba8504ffe3e10406766e95cf39ed
parent5f20363dc8ea094b3f6139f52084beb10d6fcd85 (diff)
Wire up for statement CFG improvements for conditionals that are known.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76529 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/CFG.cpp41
-rw-r--r--test/Analysis/dead-stores.c24
2 files changed, 55 insertions, 10 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 3dc364292e..01cb6cb7f6 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -863,10 +863,24 @@ CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) {
}
CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
- // "for" 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 (F->getCond() && F->getCond()->Evaluate(Result, *Context)
+ && Result.Val.isInt()) {
+ if (Result.Val.getInt().getBoolValue())
+ KnownTrue = true;
+ else
+ KnownFalse = true;
+ }
+ if (F->getCond() == 0)
+ KnownTrue = true;
+
CFGBlock* LoopSuccessor = NULL;
+ // "for" is a control-flow statement. Thus we stop processing the current
+ // block.
if (Block) {
if (!FinishBlock(Block))
return 0;
@@ -949,13 +963,21 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
return 0;
}
- // This new body block is a successor to our "exit" condition block.
- ExitConditionBlock->addSuccessor(BodyBlock);
+ if (KnownFalse)
+ ExitConditionBlock->addSuccessor(0);
+ else {
+ // This new body block is a successor to our "exit" condition block.
+ 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);
+ }
// If the loop contains initialization, create a new block for those
// statements. This block can also contain statements that precede the loop.
@@ -1099,9 +1121,6 @@ CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
}
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;
@@ -1116,6 +1135,8 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
CFGBlock* LoopSuccessor = NULL;
+ // "while" is a control-flow statement. Thus we stop processing the current
+ // block.
if (Block) {
if (!FinishBlock(Block))
return 0;
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 4798eb152a..3233b974d6 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -201,6 +201,9 @@ void f22() {
int y10 = 4;
int y11 = 4;
int y12 = 4;
+ int y13 = 4;
+ int y14 = 4;
+ int y15 = 4;
++x; // expected-warning{{never read}}
++y1;
@@ -215,6 +218,9 @@ void f22() {
++y10;
++y11;
++y12;
+ ++y13;
+ ++y14;
+ ++y15;
switch (j) {
case 1:
@@ -282,5 +288,23 @@ void f22() {
}
(void)y12;
break;
+ case 12:
+ for (;;) {
+ (void)y13;
+ }
+ (void)x;
+ break;
+ case 13:
+ for (;1;) {
+ (void)y14;
+ }
+ (void)x;
+ break;
+ case 14:
+ for (;0;) {
+ (void)x;
+ }
+ (void)y15;
+ break;
}
}