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.
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?