This is an archive of the discontinued LLVM Phabricator instance.

[Clang][ExtendLifetimes][3/4] Add -fextend-lifetimes flag to Clang to extend the lifetime of local variables
Needs ReviewPublic

Authored by StephenTozer on Aug 10 2023, 6:49 AM.

Details

Summary

This patch is part of a set of patches that add an -fextend-lifetimes flag to clang, which extends the lifetimes of local variables and parameters for improved debuggability. In addition to that flag, the patch series adds a new function attribute to disable the post-RA scheduler (which is applied by -fextend-lifetimes), a pragma to selectively disable -fextend-lifetimes, and an -fextend-this-ptr flag which functions as -fextend-lifetimes for this pointers only. All changes and tests in these patches were written by @wolfgangp, though I will be managing these reviews and addressing any comments raised. Discussion on the approach of this patch series as a whole should be directed to this patch, in order to simplify review.


This particular patch implements the clang side of the -fextend-lifetimes and -fextend-this-ptr flags, including adding the command line flags, applying the disable-post-ra attribute to functions having lifetimes extended (see the first patch in this sequence), and the emission of llvm.fake.use intrinsics for variables at the end of their scopes. The main bulk of the patch concerns emitting fake.use intrinsics, which are treated as noop cleanups since they should be emitted at all points where the variable falls out of scope.

In our (Sony's) own internal measurements (presented at EuroLLVM2023), using this flag at -O1 gave a 2.4% performance cost for a 22.1% increase in step and variable availability compared to just -O1. From these results, it appears that using this flag gives an efficient increase in debuggability of programs for its performance cost, and should be very useful for development builds.

Diff Detail

Event Timeline

StephenTozer created this revision.Aug 10 2023, 6:49 AM
Herald added a project: Restricted Project. · View Herald Transcript
StephenTozer requested review of this revision.Aug 10 2023, 6:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 10 2023, 6:49 AM
StephenTozer edited the summary of this revision. (Show Details)Aug 10 2023, 6:54 AM
jmorse added a subscriber: jmorse.Oct 5 2023, 4:23 AM

The code changes here look good, but it's time to be annoying about the tests -- most of them appear to run the optimisation pipelines, which is testing all of LLVM as well as clang in these tests. Possibly a simple fix to that is to put these in cross-project-tests. Otherwise, I believe these should be only testing the plain codegen output without optimisations at all, i.e. --disable-llvm-passes.

clang/lib/CodeGen/CGCall.cpp
3492–3499

It's a bit ugly to switch away from having a range-based loop, am I right in thinking this is because you need to skip the load-to-fake-use? Annoying but necessary I guess. Could I request an explicit "II = std::next(II);" though to really ram home to the reader that we're skipping an extra instruction, using the pre-increment is liable to be missed, and we're not trying to be super-concise here IMO.

The addition of the "I" variable looks like it might be un-necessary, that's only _used_ by GetStoreIfValid which has a domination assignment above it no?

clang/lib/CodeGen/CGDecl.cpp
1729–1730

(This could be even more concise; no strong opinion though).

StephenTozer added inline comments.Oct 5 2023, 7:09 AM
clang/lib/CodeGen/CGCall.cpp
3492–3499

Annoying but necessary I guess.

Probably not necessary actually - the addition of an extra variable could cover this case without removing the for-range.