From: Mike Stump Date: Tue, 21 Jul 2009 00:38:52 +0000 (+0000) Subject: Wire up CFG improvements for while when the condition is known. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f20363dc8ea094b3f6139f52084beb10d6fcd85;p=clang Wire up CFG improvements for while when the condition is known. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76522 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 11deec4a23..3dc364292e 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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. diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index f8677e1cfa..4798eb152a 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -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; } }