forked from OSchip/llvm-project
[analyzer] MinComplexityConstraint now early exits and only does one macro stack lookup
Summary: This patch contains performance improvements for the `MinComplexityConstraint`. It reduces the constraint time when running on the SQLite codebase by around 43% (from 0.085s down to 0.049s). The patch is essentially doing two things: * It introduces a possibility for the complexity value to early exit when reaching the limit we were checking for. This means that once we noticed that the current clone is larger than the limit the user has set, we instantly exit and no longer traverse the tree or do further expensive lookups in the macro stack. * It also removes half of the macro stack lookups we do so far. Previously we always checked the start and the end location of a Stmt for macros, which was only a middle way between checking all locations of the Stmt and just checking one location. In practice I rarely found cases where it really matters if we check start/end or just the start of a statement as code with lots of macros that somehow just produce half a statement are very rare. Reviewers: NoQ Subscribers: cfe-commits, xazax.hun, v.g.vassilev Differential Revision: https://reviews.llvm.org/D34361 llvm-svn: 312440
This commit is contained in:
parent
ac12849d32
commit
785e8161ad
|
@ -288,14 +288,19 @@ public:
|
||||||
MinComplexityConstraint(unsigned MinComplexity)
|
MinComplexityConstraint(unsigned MinComplexity)
|
||||||
: MinComplexity(MinComplexity) {}
|
: MinComplexity(MinComplexity) {}
|
||||||
|
|
||||||
size_t calculateStmtComplexity(const StmtSequence &Seq,
|
/// Calculates the complexity of the given StmtSequence.
|
||||||
|
/// \param Limit The limit of complexity we probe for. After reaching
|
||||||
|
/// this limit during calculation, this method is exiting
|
||||||
|
/// early to improve performance and returns this limit.
|
||||||
|
size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit,
|
||||||
const std::string &ParentMacroStack = "");
|
const std::string &ParentMacroStack = "");
|
||||||
|
|
||||||
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
|
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
|
||||||
CloneConstraint::filterGroups(
|
CloneConstraint::filterGroups(
|
||||||
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
|
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
|
||||||
if (!A.empty())
|
if (!A.empty())
|
||||||
return calculateStmtComplexity(A.front()) < MinComplexity;
|
return calculateStmtComplexity(A.front(), MinComplexity) <
|
||||||
|
MinComplexity;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -422,7 +422,8 @@ void RecursiveCloneTypeIIVerifyConstraint::constrain(
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MinComplexityConstraint::calculateStmtComplexity(
|
size_t MinComplexityConstraint::calculateStmtComplexity(
|
||||||
const StmtSequence &Seq, const std::string &ParentMacroStack) {
|
const StmtSequence &Seq, std::size_t Limit,
|
||||||
|
const std::string &ParentMacroStack) {
|
||||||
if (Seq.empty())
|
if (Seq.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -431,10 +432,8 @@ size_t MinComplexityConstraint::calculateStmtComplexity(
|
||||||
ASTContext &Context = Seq.getASTContext();
|
ASTContext &Context = Seq.getASTContext();
|
||||||
|
|
||||||
// Look up what macros expanded into the current statement.
|
// Look up what macros expanded into the current statement.
|
||||||
std::string StartMacroStack =
|
std::string MacroStack =
|
||||||
data_collection::getMacroStack(Seq.getStartLoc(), Context);
|
data_collection::getMacroStack(Seq.getStartLoc(), Context);
|
||||||
std::string EndMacroStack =
|
|
||||||
data_collection::getMacroStack(Seq.getEndLoc(), Context);
|
|
||||||
|
|
||||||
// First, check if ParentMacroStack is not empty which means we are currently
|
// First, check if ParentMacroStack is not empty which means we are currently
|
||||||
// dealing with a parent statement which was expanded from a macro.
|
// dealing with a parent statement which was expanded from a macro.
|
||||||
|
@ -444,8 +443,7 @@ size_t MinComplexityConstraint::calculateStmtComplexity(
|
||||||
// macro expansion will only increase the total complexity by one.
|
// macro expansion will only increase the total complexity by one.
|
||||||
// Note: This is not the final complexity of this statement as we still
|
// Note: This is not the final complexity of this statement as we still
|
||||||
// add the complexity of the child statements to the complexity value.
|
// add the complexity of the child statements to the complexity value.
|
||||||
if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack &&
|
if (!ParentMacroStack.empty() && MacroStack == ParentMacroStack) {
|
||||||
EndMacroStack == ParentMacroStack)) {
|
|
||||||
Complexity = 0;
|
Complexity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,12 +452,16 @@ size_t MinComplexityConstraint::calculateStmtComplexity(
|
||||||
if (Seq.holdsSequence()) {
|
if (Seq.holdsSequence()) {
|
||||||
for (const Stmt *S : Seq) {
|
for (const Stmt *S : Seq) {
|
||||||
Complexity += calculateStmtComplexity(
|
Complexity += calculateStmtComplexity(
|
||||||
StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
|
StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
|
||||||
|
if (Complexity >= Limit)
|
||||||
|
return Limit;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const Stmt *S : Seq.front()->children()) {
|
for (const Stmt *S : Seq.front()->children()) {
|
||||||
Complexity += calculateStmtComplexity(
|
Complexity += calculateStmtComplexity(
|
||||||
StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
|
StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
|
||||||
|
if (Complexity >= Limit)
|
||||||
|
return Limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Complexity;
|
return Complexity;
|
||||||
|
|
Loading…
Reference in New Issue