Improved simplifications of redundant loops:

- Execute simplifyWhile0 after simplifyKnownVariables (#394)
- Support declaration of variable in loop header in removeRedundantFor
This commit is contained in:
PKEuS 2014-09-26 10:46:49 +02:00
parent 3eafb2b5c4
commit de13ad7eca
2 changed files with 45 additions and 21 deletions

View File

@ -3711,7 +3711,6 @@ bool Tokenizer::simplifyTokenList2()
simplifyIfNotNull(); simplifyIfNotNull();
simplifyIfSameInnerCondition(); simplifyIfSameInnerCondition();
simplifyNestedStrcat(); simplifyNestedStrcat();
simplifyWhile0();
simplifyFuncInWhile(); simplifyFuncInWhile();
simplifyIfAndWhileAssign(); // Could be affected by simplifyIfNot simplifyIfAndWhileAssign(); // Could be affected by simplifyIfNot
@ -3741,7 +3740,8 @@ bool Tokenizer::simplifyTokenList2()
modified |= simplifyCalculations(); modified |= simplifyCalculations();
} }
// simplify redundant for // simplify redundant loops
simplifyWhile0();
removeRedundantFor(); removeRedundantFor();
// Remove redundant parentheses in return.. // Remove redundant parentheses in return..
@ -4304,21 +4304,26 @@ bool Tokenizer::removeRedundantConditions()
void Tokenizer::removeRedundantFor() void Tokenizer::removeRedundantFor()
{ {
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "[;{}] for ( %var% = %num% ; %var% < %num% ; ++| %var% ++| ) {")) { if (Token::Match(tok, "[;{}] for ( %var% = %num% ; %var% < %num% ; ++| %var% ++| ) {") ||
Token::Match(tok, "[;{}] for ( %type% %var% = %num% ; %var% < %num% ; ++| %var% ++| ) {")) {
// Same variable name.. // Same variable name..
const std::string varname(tok->strAt(3)); const Token* varTok = tok->tokAt(3);
const unsigned int varid(tok->tokAt(3)->varId()); bool type = varTok->next()->isName();
if (varname != tok->strAt(7)) if (type)
varTok = varTok->next();
const std::string varname(varTok->str());
const unsigned int varid(varTok->varId());
if (varname != varTok->strAt(4))
continue; continue;
const Token *vartok = tok->tokAt(11); const Token *vartok2 = tok->linkAt(2)->previous();
if (vartok->str() == "++") if (vartok2->str() == "++")
vartok = vartok->next(); vartok2 = vartok2->previous();
if (varname != vartok->str()) if (varname != vartok2->str())
continue; continue;
// Check that the difference of the numeric values is 1 // Check that the difference of the numeric values is 1
const MathLib::bigint num1(MathLib::toLongNumber(tok->strAt(5))); const MathLib::bigint num1(MathLib::toLongNumber(varTok->strAt(2)));
const MathLib::bigint num2(MathLib::toLongNumber(tok->strAt(9))); const MathLib::bigint num2(MathLib::toLongNumber(varTok->strAt(6)));
if (num1 + 1 != num2) if (num1 + 1 != num2)
continue; continue;
@ -4341,12 +4346,18 @@ void Tokenizer::removeRedundantFor()
// Simplify loop if loop variable isn't written // Simplify loop if loop variable isn't written
if (!write) { if (!write) {
Token* bodyBegin = tok->linkAt(2)->next();
// remove "for (" // remove "for ("
tok->deleteNext(2); tok->deleteNext(2);
// If loop variable is read then keep assignment before // If loop variable is read then keep assignment before
// loop body.. // loop body..
if (read) { if (type) {
tok->insertToken("{");
Token::createMutualLinks(tok->next(), bodyBegin->link());
bodyBegin->deleteThis();
tok = tok->tokAt(6);
} else if (read) {
// goto ";" // goto ";"
tok = tok->tokAt(4); tok = tok->tokAt(4);
} else { } else {
@ -4357,14 +4368,16 @@ void Tokenizer::removeRedundantFor()
// remove "x < 1 ; x ++ )" // remove "x < 1 ; x ++ )"
tok->deleteNext(7); tok->deleteNext(7);
// Add assignment after the loop body so the loop variable if (!type) {
// get the correct end value // Add assignment after the loop body so the loop variable
Token *tok2 = tok->next()->link(); // get the correct end value
tok2->insertToken(";"); Token *tok2 = tok->next()->link();
tok2->insertToken(MathLib::toString(num2)); tok2->insertToken(";");
tok2->insertToken("="); tok2->insertToken(MathLib::toString(num2));
tok2->insertToken(varname); tok2->insertToken("=");
tok2->next()->varId(varid); tok2->insertToken(varname);
tok2->next()->varId(varid);
}
} }
} }
} }

View File

@ -2753,6 +2753,7 @@ private:
ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (unsigned int i = 0; i < 0; i++) { a; } }")); ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (unsigned int i = 0; i < 0; i++) { a; } }"));
ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (long long i = 0; i < 0; i++) { a; } }")); ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (long long i = 0; i < 0; i++) { a; } }"));
ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (signed long long i = 0; i < 0; i++) { a; } }")); ASSERT_EQUALS("void f ( ) { }", tok("void f() { for (signed long long i = 0; i < 0; i++) { a; } }"));
ASSERT_EQUALS("void f ( ) { }", tok("void f() { int n = 0; for (signed long long i = 0; i < n; i++) { a; } }"));
} }
void while1() { void while1() {
@ -4060,6 +4061,16 @@ private:
"}"; "}";
ASSERT_EQUALS("void f ( ) { x = 0 ; { y = 1 + x ; } x = 1 ; }", tok(code, true)); ASSERT_EQUALS("void f ( ) { x = 0 ; { y = 1 + x ; } x = 1 ; }", tok(code, true));
} }
{
const char code[] = "void f() {"
" foo();"
" for(int x=0;x<1;x++) {"
" y = 1 + x;"
" }"
"}";
ASSERT_EQUALS("void f ( ) { foo ( ) ; { int x = 0 ; y = 1 + x ; } }", tok(code, true));
}
} }
void consecutiveBraces() { void consecutiveBraces() {