C++: Speed up primitive basic block calculation#285
Merged
Conversation
The existing implementation of `primitive_basic_block_entry_node` was "cleverly" computing two properties about `node` with a single `strictcount`: whether `node` had multiple predecessors and whether any of those predecessors had more than once successor. This was fast enough on most snapshots, but on the snapshot of our own code it took 37 seconds to compute `primitive_basic_block_entry_node` and its auxiliary predicates. This is likely to have affected other large snapshots too. With this change, the property is computed like in our other languages, and it brings the run time down to 4 seconds.
This predicate looked like a join of two already-computed predicates, but it was a bit more complicated because the `*` operator expands into two cases: the reflexive case and the transitive case. The join order for the transitive case placed the `PrimitiveBasicBlock` charpred call _after_ the `member_step+` call, which means that all the tuples of `member_step+` passed through the pipeline. This commit changes the implementation by fully writing out the expansion of `*` into two cases, where the base case is manually specialised to make sure the join orderer doesn't get tempted into reusing the same strategy for both cases. This speeds up the predicate from 2m38s to 1s on a snapshot of our own C/C++ code.
geoffw0
approved these changes
Oct 6, 2018
Contributor
geoffw0
left a comment
There was a problem hiding this comment.
Changes LGTM.
I tried a few basic-blocks using queries with and without the change, they generally ran at the same speed or a bit faster. I probably didn't hit any extreme cases.
smowton
added a commit
to smowton/codeql
that referenced
this pull request
Apr 16, 2022
Switch to expanding property initializers and init blocks in-place
MathiasVP
added a commit
to MathiasVP/ql
that referenced
this pull request
Nov 20, 2025
Update the Qhelp guidance for java xss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 is an attempt to fix the timeouts we've seen in Dashboards/Internal in the last few days. I'm aiming this at 1.18.1 because the second commit fixes a regression introduced in #123 that might affect customers -- see the discussion in CPP-279.
The first commit is not a regression fix but should be Nice To Have. I've tested it for correctness by comparing the output of
select strictcount(PrimitiveBasicBlock b)before and after. The implementation is ported from the Java basic-blocks library.