Optimization: Improved performance of ForwardAnalyzer by adding some pre-checks and combining conditions

This commit is contained in:
PKEuS 2020-05-18 08:00:01 +02:00
parent c155062cf2
commit 22884888fb
1 changed files with 34 additions and 30 deletions

View File

@ -36,7 +36,7 @@ struct ForwardTraversal {
if (out) if (out)
*out = tok->link(); *out = tok->link();
return Progress::Skip; return Progress::Skip;
} else if (Token::Match(tok, "?|&&|%oror%") && tok->astOperand1() && tok->astOperand2()) { } else if (tok->astOperand1() && tok->astOperand2() && Token::Match(tok, "?|&&|%oror%")) {
if (traverseConditional(tok, f, traverseUnknown) == Progress::Break) if (traverseConditional(tok, f, traverseUnknown) == Progress::Break)
return Progress::Break; return Progress::Break;
if (out) if (out)
@ -49,7 +49,7 @@ struct ForwardTraversal {
if (out) if (out)
*out = lambdaEndToken; *out = lambdaEndToken;
// Skip class scope // Skip class scope
} else if (Token::simpleMatch(tok, "{") && tok->scope() && tok->scope()->isClassOrStruct()) { } else if (tok->str() == "{" && tok->scope() && tok->scope()->isClassOrStruct()) {
if (out) if (out)
*out = tok->link(); *out = tok->link();
} else { } else {
@ -239,16 +239,18 @@ struct ForwardTraversal {
for (Token* tok = start; tok && tok != end; tok = tok->next()) { for (Token* tok = start; tok && tok != end; tok = tok->next()) {
Token* next = nullptr; Token* next = nullptr;
if (tok->link()) {
// Skip casts.. // Skip casts..
if (tok->str() == "(" && !tok->astOperand2() && tok->isCast()) { if (tok->str() == "(" && !tok->astOperand2() && tok->isCast()) {
tok = tok->link(); tok = tok->link();
continue; continue;
} }
// Skip template arguments.. // Skip template arguments..
if (tok->str() == "<" && tok->link()) { if (tok->str() == "<") {
tok = tok->link(); tok = tok->link();
continue; continue;
} }
}
// Evaluate RHS of assignment before LHS // Evaluate RHS of assignment before LHS
if (Token* assignTok = assignExpr(tok)) { if (Token* assignTok = assignExpr(tok)) {
@ -261,7 +263,7 @@ struct ForwardTraversal {
tok = nextAfterAstRightmostLeaf(assignTok); tok = nextAfterAstRightmostLeaf(assignTok);
if (!tok) if (!tok)
return Progress::Break; return Progress::Break;
} else if (Token::simpleMatch(tok, "break")) { } else if (tok->str() == "break") {
const Scope* scope = findBreakScope(tok->scope()); const Scope* scope = findBreakScope(tok->scope());
if (!scope) if (!scope)
return Progress::Break; return Progress::Break;
@ -271,10 +273,11 @@ struct ForwardTraversal {
// TODO: Don't break, instead move to the outer scope // TODO: Don't break, instead move to the outer scope
if (!tok) if (!tok)
return Progress::Break; return Progress::Break;
} else if (Token::Match(tok, "%name% :") || Token::simpleMatch(tok, "case")) { } else if (Token::Match(tok, "%name% :") || tok->str() == "case") {
if (!analyzer->lowerToPossible()) if (!analyzer->lowerToPossible())
return Progress::Break; return Progress::Break;
} else if (Token::simpleMatch(tok, "}") && Token::Match(tok->link()->previous(), ")|else {")) { } else if (tok->link() && tok->str() == "}") {
if (Token::Match(tok->link()->previous(), ")|else {")) {
const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {"); const bool inElse = Token::simpleMatch(tok->link()->previous(), "else {");
const Token* condTok = getCondTokFromEnd(tok); const Token* condTok = getCondTokFromEnd(tok);
if (!condTok) if (!condTok)
@ -288,10 +291,13 @@ struct ForwardTraversal {
analyzer->assume(condTok, !inElse, tok); analyzer->assume(condTok, !inElse, tok);
if (Token::simpleMatch(tok, "} else {")) if (Token::simpleMatch(tok, "} else {"))
tok = tok->linkAt(2); tok = tok->linkAt(2);
} else if (Token::simpleMatch(tok, "}") && Token::simpleMatch(tok->link()->previous(), "try {")) { } else if (Token::simpleMatch(tok->link()->previous(), "try {")) {
if (!analyzer->lowerToPossible()) if (!analyzer->lowerToPossible())
return Progress::Break; return Progress::Break;
} else if (Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) { } else if (Token::simpleMatch(tok->next(), "else {")) {
tok = tok->linkAt(2);
}
} else if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->next()->link(), ") {")) {
Token* endCond = tok->next()->link(); Token* endCond = tok->next()->link();
Token* endBlock = endCond->next()->link(); Token* endBlock = endCond->next()->link();
Token* condTok = getCondTok(tok); Token* condTok = getCondTok(tok);
@ -373,8 +379,6 @@ struct ForwardTraversal {
analyzer->assume(condTok, elseAction.isModified()); analyzer->assume(condTok, elseAction.isModified());
} }
} }
} else if (Token::simpleMatch(tok, "} else {")) {
tok = tok->linkAt(2);
} else if (Token::simpleMatch(tok, "try {")) { } else if (Token::simpleMatch(tok, "try {")) {
Token* endBlock = tok->next()->link(); Token* endBlock = tok->next()->link();
ForwardAnalyzer::Action a = analyzeScope(endBlock); ForwardAnalyzer::Action a = analyzeScope(endBlock);