From: Mike Stump Date: Tue, 21 Jul 2009 01:12:51 +0000 (+0000) Subject: Wire up for statement CFG improvements for conditionals that are known. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fefb9f7009702befaf715e7a8debc9505c3c8634;p=clang 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 --- 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; } }