C++: Speed up UncheckedReturnValueForTimeFunctions.ql
#303
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This query was performing quite poorly on a large internal Microsoft C++ project. The issue was mostly due to bad magic insertion by the compiler in a transitive closure of the
ControlFlow.getAPredecessorrelation:It should not take 12 hours to evaluate this predicate 😅. And the
Plus#bfpart of the name tells me 2 things:*or+) on some relation. In this case the relation isControlFlowNode.getAPredecessor.I never really trust the magic inserted by the compiler in such transitive closures. However, as the query is currently written it needs some magic to even be feasible to execute. So I decided to rewrite it and bring in all the magic "manually".
The gist of the problem is all the uses of
a = b.getAPredecessor*()in the query. In order for that to perform well we need some bounds on the "end points" of that relation (i.e.,aandb). So I define a small little parameterized module that allows you to specify these end-points up-front, and then I do the usual forward/reverse pruning that we've seen so many times.That's all done in the first commit. The next three rewrites the query to make use of this new module in various parts of the query.
The end result? The query executes in 34 seconds on the same DB 🎉