Skip to content

Improve exp.single-threaded for analysis without threadflag and escape#1981

Merged
sim642 merged 14 commits into
masterfrom
no-threadflag
Apr 14, 2026
Merged

Improve exp.single-threaded for analysis without threadflag and escape#1981
sim642 merged 14 commits into
masterfrom
no-threadflag

Conversation

@sim642
Copy link
Copy Markdown
Member

@sim642 sim642 commented Apr 8, 2026

So far, exp.single-threaded only prevented new threads from being spawned but did not override multi-threadedness related queries.
Now, using the queries through the corresponding helper functions, the option has stronger effect.

In particular, this allows analyzing a single-threaded program without the threadflag and escape analyses enabled, without immediately becoming flow-insensitive for globals (like exp.earlyglobs) and assuming all locals may have escaped (and become globals).

There is a performance benefit for having less analyses activated, even if they don't compute anything for single-threaded programs.
This is also what motivated the single-threaded autotuner for SV-COMP. This PR would allow pushing that autotuner even further to disable threadflag and escape analyses for such programs.

@sim642 sim642 added this to the v2.8.0 Clumsy Clurichaun milestone Apr 8, 2026
Copilot AI review requested due to automatic review settings April 8, 2026 08:43
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 strengthens the effect of exp.single-threaded by routing multi-threadedness and escape-related decisions through centralized helper functions, allowing more precise analysis of single-threaded programs even when threadflag, threadid, or escape analyses are disabled.

Changes:

  • Add regression tests covering exp.single-threaded behavior when escape / threadflag (and threadid) are deactivated.
  • Introduce/extend helper-based semantics for MayEscape and MustBeSingleThreaded queries via ThreadEscape.has_escaped and ThreadFlag.{is_currently_multi,has_ever_been_multi}.
  • Update multiple analyses to use these helpers instead of directly querying Queries.MayEscape / Queries.MustBeSingleThreaded.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/regression/00-sanity/42-no-threadflag.t New cram test for single-threaded mode with threadflag/threadid deactivated (and earlyglobs toggled).
tests/regression/00-sanity/42-no-threadflag.c C input for the above test (simple global flow-sensitivity expectation).
tests/regression/00-sanity/43-no-escape.t New cram test for single-threaded mode with escape deactivated (with earlyglobs enabled).
tests/regression/00-sanity/43-no-escape.c C input for the above test (address-taken local should remain non-escaped under forced single-threaded mode).
src/domains/queries.ml Document intended access paths for MayEscape / MustBeSingleThreaded via helper functions.
src/analyses/threadFlag.ml Make helper functions respect exp.single-threaded by forcing “not multi-threaded”.
src/analyses/threadEscape.ml Make ThreadEscape.has_escaped return false under exp.single-threaded.
src/analyses/singleThreadedLifter.ml Use ThreadFlag.has_ever_been_multi for multithreaded detection.
src/analyses/raceAnalysis.ml Use ThreadEscape.has_escaped for “treat as global/escaped” decision.
src/analyses/mutexAnalysis.ml Use ThreadEscape.has_escaped for “treat as global/escaped” decision.
src/analyses/wrapperFunctionAnalysis.ml Use ThreadFlag.has_ever_been_multi instead of direct MustBeSingleThreaded query.
src/analyses/varEq.ml Use ThreadFlag.has_ever_been_multi instead of direct MustBeSingleThreaded query.
src/analyses/useAfterFree.ml Use ThreadFlag.has_ever_been_multi for multi-threaded warning gating.
src/analyses/memLeak.ml Use ThreadFlag helpers for multi-threadedness checks and simplify prior helper.
src/analyses/basePriv.ml Use ThreadFlag helpers to detect “recovered to single-threaded” state.
src/analyses/apron/relationPriv.apron.ml Use ThreadFlag.has_ever_been_multi for branched sync decisions.
src/analyses/mCP.ml Add TODOs around exp.single-threaded spawn suppression message behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/analyses/mCP.ml Outdated
Comment thread tests/regression/00-sanity/42-no-threadflag.t
Comment thread tests/regression/00-sanity/43-no-escape.t Outdated
sim642 added 3 commits April 8, 2026 11:53
Due to 7b2a223, locals which have vaddrof false are not longer queried at all by mutex/race analysis.
1. Don't output final message if no thread creations are even attempted by the program.
2. Output non-final message for each suppressed thread.
@michael-schwarz michael-schwarz self-requested a review April 9, 2026 04:41
@sim642
Copy link
Copy Markdown
Member Author

sim642 commented Apr 9, 2026

In my rsync runs (goblint/bench@58495e9), something strange happens with this change. When deactivating threadflag and escape in favor of exp.single-threaded the runtime increases from 2h 30min to 11h 13min. The number of vars slightly decreases and the number of evals more than doubles.

I thought that maybe the GobConfig.get_bool is causing an overhead because these are probably called very often (probably every access to a global at least), and should be cached into a ref. But that inefficiency wouldn't increase evals, so something else must be happening as well.

@sim642
Copy link
Copy Markdown
Member Author

sim642 commented Apr 9, 2026

In my rsync runs (goblint/bench@58495e9), something strange happens with this change. When deactivating threadflag and escape in favor of exp.single-threaded the runtime increases from 2h 30min to 11h 13min. The number of vars slightly decreases and the number of evals more than doubles.

Apparently our rsync-v3.4.1-gcc-nosignal.i still has some signal handlers left and still was making the analysis multi-threaded. The error improvements for "Thread not spawned" in this PR already paid off.

Copy link
Copy Markdown
Member

@michael-schwarz michael-schwarz left a comment

Choose a reason for hiding this comment

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

Great PR, I think not using the query with the since_start flag directly makes the intent easier to follow.

The warning message in maingoblint.ml about not enabling escape should be adapted so it is not produced if exp.single-threaded is on.

Also, should we maybe make an issue for the improved autotuner (or ask AI to fix the autotuner right away)?

@sim642
Copy link
Copy Markdown
Member Author

sim642 commented Apr 13, 2026

Apparently our rsync-v3.4.1-gcc-nosignal.i still has some signal handlers left and still was making the analysis multi-threaded. The error improvements for "Thread not spawned" in this PR already paid off.

I redid the rsync comparison after removing the remaining signal handlers in goblint/bench@9192101.
It reduced the analysis time of one configuration from ~10h 27min to ~9h 23min, which is ~10% reduction.

The warning message in maingoblint.ml about not enabling escape should be adapted so it is not produced if exp.single-threaded is on.

Indeed, I'll update it.

Also, should we maybe make an issue for the improved autotuner (or ask AI to fix the autotuner right away)?

I'll open a separate issue about it because unlike the existing single-threaded SV-COMP autotuner, this is more aggressive and requires a bit more care. This can become unsound if there are other things which we also treat as thread-like (signal handlers, atexit, etc.). Not sure if any of those are covered by sv-benchmarks though.
And improvements like #1965 which change our approach to thread-like things (e.g. making them non-threads in some sense, but not other) can lead to new problematic interactions.

I'd like to have it for SV-COMP 2027 and it's easy to do closer to it happening. I want to see where we can get with the signal handlers (like #1966) before needing to worry about the SV-COMP interactions.

Copilot AI review requested due to automatic review settings April 13, 2026 21:05
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

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/analyses/threadFlag.ml
Comment thread src/analyses/threadEscape.ml
@sim642 sim642 merged commit 2dc5b68 into master Apr 14, 2026
23 checks passed
@sim642 sim642 deleted the no-threadflag branch April 14, 2026 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

analyze-that cleanup Refactoring, clean-up feature performance Analysis time, memory usage precision usability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants