aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2010-01-21 03:07:51 +0000
committerMike Stump <mrs@apple.com>2010-01-21 03:07:51 +0000
commit44fa21054574cf9e5f3a08c0b6a44f82aa5b44e4 (patch)
tree9046be53599838d249b4b10b6066ab7dba71fff9
parent6bde1ae4b7e790691b3a8080a7f1a8fd8a943d3f (diff)
When checking for unreachable code, we can trivially avoid checking
for unreachable loops if all the blocks are already marked live by this point. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94064 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDecl.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b0ee5ee59c..1f7ef3d23e 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1311,7 +1311,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
}
// MarkLive - Mark all the blocks reachable from e as live. Returns the total
-// number of blocks marked live.
+// number of blocks just marked live.
static unsigned MarkLive(CFGBlock *e, llvm::BitVector &live) {
unsigned count = 0;
std::queue<CFGBlock*> workq;
@@ -1425,6 +1425,7 @@ public:
/// CheckUnreachable - Check for unreachable code.
void Sema::CheckUnreachable(AnalysisContext &AC) {
+ unsigned count;
// We avoid checking when there are errors, as the CFG won't faithfully match
// the user's code.
if (getDiagnostics().hasErrorOccurred())
@@ -1438,7 +1439,9 @@ void Sema::CheckUnreachable(AnalysisContext &AC) {
llvm::BitVector live(cfg->getNumBlockIDs());
// Mark all live things first.
- if (MarkLive(&cfg->getEntry(), live) == cfg->getNumBlockIDs())
+ count = MarkLive(&cfg->getEntry(), live);
+
+ if (count == cfg->getNumBlockIDs())
// If there are no dead blocks, we're done.
return;
@@ -1454,21 +1457,24 @@ void Sema::CheckUnreachable(AnalysisContext &AC) {
// Blocks without a location can't produce a warning, so don't mark
// reachable blocks from here as live.
live.set(b.getBlockID());
+ ++count;
continue;
}
lines.push_back(c);
// Avoid excessive errors by marking everything reachable from here
- MarkLive(&b, live);
+ count += MarkLive(&b, live);
}
}
}
- // And then give warnings for the tops of loops.
- for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
- CFGBlock &b = **I;
- if (!live[b.getBlockID()])
- // Avoid excessive errors by marking everything reachable from here
- lines.push_back(MarkLiveTop(&b, live, Context.getSourceManager()));
+ if (count < cfg->getNumBlockIDs()) {
+ // And then give warnings for the tops of loops.
+ for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
+ CFGBlock &b = **I;
+ if (!live[b.getBlockID()])
+ // Avoid excessive errors by marking everything reachable from here
+ lines.push_back(MarkLiveTop(&b, live, Context.getSourceManager()));
+ }
}
std::sort(lines.begin(), lines.end(), LineCmp(Context.getSourceManager()));