mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-02 07:16:29 +00:00
Make skipping of vardecls more precise: it's ok to skip a decl if the entire
compound stmt containing the decl is skipped. llvm-svn: 126639
This commit is contained in:
parent
62208c395a
commit
35d3ac5e9e
@ -887,9 +887,16 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
||||
// the skipped statements must be skippable) or we might already have it.
|
||||
CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end();
|
||||
if (Case) {
|
||||
// Keep track of whether we see a skipped declaration. The code could be
|
||||
// using the declaration even if it is skipped, so we can't optimize out
|
||||
// the decl if the kept statements might refer to it.
|
||||
bool HadSkippedDecl = false;
|
||||
|
||||
// If we're looking for the case, just see if we can skip each of the
|
||||
// substatements.
|
||||
for (; Case && I != E; ++I) {
|
||||
HadSkippedDecl |= isa<DeclStmt>(I);
|
||||
|
||||
switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) {
|
||||
case CSFC_Failure: return CSFC_Failure;
|
||||
case CSFC_Success:
|
||||
@ -898,6 +905,11 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
||||
// and also contains the break to exit the switch. In the later case,
|
||||
// we just verify the rest of the statements are elidable.
|
||||
if (FoundCase) {
|
||||
// If we found the case and skipped declarations, we can't do the
|
||||
// optimization.
|
||||
if (HadSkippedDecl)
|
||||
return CSFC_Failure;
|
||||
|
||||
for (++I; I != E; ++I)
|
||||
if (CodeGenFunction::ContainsLabel(*I, true))
|
||||
return CSFC_Failure;
|
||||
@ -911,6 +923,11 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
||||
assert(FoundCase && "Didn't find case but returned fallthrough?");
|
||||
// We recursively found Case, so we're not looking for it anymore.
|
||||
Case = 0;
|
||||
|
||||
// If we found the case and skipped declarations, we can't do the
|
||||
// optimization.
|
||||
if (HadSkippedDecl)
|
||||
return CSFC_Failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -943,9 +960,7 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
||||
// for statement or increment etc. If we are skipping over this statement,
|
||||
// just verify it doesn't have labels, which would make it invalid to elide.
|
||||
if (Case) {
|
||||
if (CodeGenFunction::ContainsLabel(S, true) ||
|
||||
// Don't skip over DeclStmts, which can be used even if skipped over.
|
||||
isa<DeclStmt>(S))
|
||||
if (CodeGenFunction::ContainsLabel(S, true))
|
||||
return CSFC_Failure;
|
||||
return CSFC_Success;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ void test5() {
|
||||
int x; // eliding var decl?
|
||||
case 1:
|
||||
x = 4;
|
||||
i = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -196,3 +197,22 @@ void test11() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: @test12
|
||||
// CHECK-NOT: switch
|
||||
// CHECK: ret void
|
||||
void test12() {
|
||||
switch (1) {
|
||||
case 2: {
|
||||
int a; // Ok to skip this vardecl.
|
||||
a = 42;
|
||||
}
|
||||
case 1:
|
||||
break;
|
||||
case 42: ;
|
||||
int x; // eliding var decl?
|
||||
x = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user