Skip to content

Go: Avoid combinatorial explosion in mostRecentSideEffect when there are multiple entry points#21753

Open
hvitved wants to merge 1 commit intogithub:mainfrom
hvitved:go/most-recent-side-effect-multi-entry
Open

Go: Avoid combinatorial explosion in mostRecentSideEffect when there are multiple entry points#21753
hvitved wants to merge 1 commit intogithub:mainfrom
hvitved:go/most-recent-side-effect-multi-entry

Conversation

@hvitved
Copy link
Copy Markdown
Contributor

@hvitved hvitved commented Apr 24, 2026

I'm not sure why multiple entry points can happen in the first place (likely TRAP deduplication), but when they do, we need to prevent them from getting mixed in the computation of mostRecentSideEffect. In one example, mostRecentSideEffect would contain 3,095,056,949 rows, whereas after this PR it only contains 3,628,500 rows.

@github-actions github-actions Bot added the Go label Apr 24, 2026
@hvitved hvitved force-pushed the go/most-recent-side-effect-multi-entry branch from 84d3f61 to 8e26fa1 Compare April 24, 2026 11:25
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Apr 24, 2026
@hvitved hvitved marked this pull request as ready for review April 24, 2026 13:20
Copilot AI review requested due to automatic review settings April 24, 2026 13:20
@hvitved hvitved requested a review from a team as a code owner April 24, 2026 13:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Go global value numbering’s side-effect dominator computation to avoid a combinatorial blow-up when multiple CFG entry points exist (e.g., due to TRAP deduplication), by separating computations per entry point and reintroducing uniqueness at the call sites that require it.

Changes:

  • Parameterize immediate-dominator computation (iDomEffect) and mostRecentSideEffect by a specific CFG entry node to prevent cross-entry mixing.
  • Add a cached mostRecentSideEffectUnique(node) wrapper that enforces a single result via unique(...).
  • Thread the computed dominator through analyzable expression predicates (field reads, incomplete-SSA variable reads, index reads, pointer dereferences) using mostRecentSideEffectUnique.
Show a summary per file
File Description
go/ql/lib/semmle/go/dataflow/GlobalValueNumbering.qll Refactors side-effect dominator logic to be entry-specific and introduces a cached uniqueness wrapper to prevent combinatorial explosion.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0

entryNode(entry) and
iDomEffect(entry, result) and
iDomEffect*(result, node)
private ControlFlow::Node mostRecentSideEffect(ControlFlow::Node entry, ControlFlow::Node node) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the QLDoc to explain what the new parameter does.

* Holds if `access` is an access to a variable `target` for which SSA information is incomplete.
*/
private predicate analyzableOtherVariable(DataFlow::Node access, ValueEntity target) {
private predicate analyzableOtherVariable(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the QLDoc to explain what the new parameter does.

@@ -181,15 +182,21 @@ private predicate iDomEffect(ControlFlow::Node dominator, ControlFlow::Node node
* The immediate dominator path to line 015 is 000 - 009 - 012 - 015.
* Therefore, the most recent side effect for line 015 is line 009.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Therefore, the most recent side effect for line 015 is line 009.
* Therefore, the most recent side effect for line 015 is line 009.
* (Note that line 009 is not a side-effect itself. Instead, it is the
* point where the control flow paths from the side-effects at 004 and 007
* merge. Because its immediate dominator is the entry node 000, it serves
* as the safe root for expressions evaluated after those side-effects.)

I found the QLDoc for this predicate quite hard to understand. I asked copilot to make it clearer and it suggested this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Go no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants