Skip to content

C++: reachableRecursive refactor for performance#1325

Merged
rdmarsh2 merged 2 commits into
github:masterfrom
jbj:reachableRecursive
May 16, 2019
Merged

C++: reachableRecursive refactor for performance#1325
rdmarsh2 merged 2 commits into
github:masterfrom
jbj:reachableRecursive

Conversation

@jbj
Copy link
Copy Markdown
Contributor

@jbj jbj commented May 15, 2019

Reviewers, sorry for the long diff. The only code changes are in the three predicates that start with reachable. See the commit message for all the details.

@jbj jbj added the C++ label May 15, 2019
@jbj jbj requested a review from a team as a code owner May 15, 2019 11:31
@rdmarsh2
Copy link
Copy Markdown
Contributor

rdmarsh2 commented May 15, 2019

Is it possible to split this into a commit with the relocation followed by a commit with the substantive changes?

@jbj
Copy link
Copy Markdown
Contributor Author

jbj commented May 16, 2019

Yes. I'll do that.

jbj added 2 commits May 16, 2019 13:34
This change only moves code around -- there are no changes to predicate
bodies or signatures.

The predicates that go in `ConstantExprs.Cached` after this change were
already cached in the same stage or, in the case of the `aborting*`
predicates, did not need to be cached. This is a fortunate consequence
of how the mutual recursion between the predicates happens to work, and
it's not going to be the case after the next commit.
The `reachable` predicate is large and slow to compute. It's part of a
mutual recursion that's non-linear, meaning it has a recursive call on
both sides of an `and`.

This change removes a part of the base case that has no effect on
recursive cases. The removed part is added back after the recursion has
finished.

Before, on Wireshark:

    ControlFlowGraph::Cached::reachable#f .......... 20.8s (executed 9800 times)
    ConstantExprs::successors_adapted#ff ........... 4.2s (executed 615 times)
    ConstantExprs::potentiallyReturningFunction#f .. 3.9s (executed 9799 times)
    ConstantExprs::possiblePredecessor#f ........... 2.9s (executed 788 times)

After, on Wireshark:

    ConstantExprs::reachableRecursive#f ............ 13.2s (executed 9800 times)
    ConstantExprs::successors_adapted#ff ........... 4.2s (executed 615 times)
    ConstantExprs::potentiallyReturningFunction#f .. 4.3s (executed 9799 times)
    ConstantExprs::possiblePredecessor#f ........... 2.6s (executed 788 times)

I've verified that this change doesn't change what's computed by
checking that the output of the following query is unchanged:

    import cpp
    import semmle.code.cpp.controlflow.internal.ConstantExprs

    select
      strictcount(ControlFlowNode n | reachable(n)) as reachable,
      strictcount(ControlFlowNode n1, ControlFlowNode n2 | n2 = n1.getASuccessor()) as edges,
      strictcount(FunctionCall c | aborting(c)) as abortingCall,
      strictcount(Function f | abortingFunction(f)) as abortingFunction
@jbj jbj force-pushed the reachableRecursive branch from 5296d7b to 947aaa9 Compare May 16, 2019 11:41
@jbj
Copy link
Copy Markdown
Contributor Author

jbj commented May 16, 2019

Done.

I also moved successors_adapted out of the ControlFlowGraphPublic module, where it had accidentally ended up. The successors_adapted was not exposed by import cpp before, and that should not change.

@rdmarsh2 rdmarsh2 merged commit 5f77ac4 into github:master May 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants