diff options
author | Mike Stump <mrs@apple.com> | 2009-07-21 01:12:51 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-07-21 01:12:51 +0000 |
commit | fefb9f7009702befaf715e7a8debc9505c3c8634 (patch) | |
tree | d801458ff83eba8504ffe3e10406766e95cf39ed /lib/Analysis/CFG.cpp | |
parent | 5f20363dc8ea094b3f6139f52084beb10d6fcd85 (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
Diffstat (limited to 'lib/Analysis/CFG.cpp')
-rw-r--r-- | lib/Analysis/CFG.cpp | 41 |
1 files changed, 31 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; |