This is an archive of the discontinued LLVM Phabricator instance.

[Assignment Tracking] Fix migrateDebuginfo in SROA
ClosedPublic

Authored by Orlando on Feb 2 2023, 12:45 AM.

Details

Summary

Without this patch, migrateDebugInfo doesn't understand how to handle existing fragments that are smaller than the to-be-split store. This can occur if. e.g. a vector store (1 dbg.assign) is split (many dbg.assigns - 1 fragment for each scalar) and later those stores are re-vectorized (many dbg.assigns), and then SROA runs on that.

The approach taken in this patch is to drop intrinsics with fragments outside of the slice.

For example, starting with:

store <2 x float> %v, ptr %dest !DIAssignID !1
call void @llvm.dbg.assign(..., DIExpression(DW_OP_LLVM_fragment, 0, 32), !1, ...)
call void @llvm.dbg.assign(..., DIExpression(DW_OP_LLVM_fragment, 32, 32), !1, ...)

When visiting the slice of bits 0 to 31 we get:

store float v.extract.0, ptr %dest !DIAssignID !2
call void @llvm.dbg.assign(..., DIExpression(DW_OP_LLVM_fragment, 0, 32), !2, ...)

The other dbg.assign associated with the currently-split store is dropped for this split part. And visiting bits 32 to 63 we get the following:

store float v.extract.1, ptr %adjusted.dest !DIAssignID !3
call void @llvm.dbg.assign(..., DIExpression(DW_OP_LLVM_fragment, 32, 32), !3, ...)

I've added two tests that cover this case.

Implementing this meant re-writing the fragment-calculation part of migrateDebugInfo to work with the absolute offset of the new slice in terms of the base alloca (instead of the offset of the slice into the new alloca), the fragment (if any) of the variable associated with the base alloca, and the fragment associated with the split store. Because we need the offset into the base alloca for the variables being split, some careful wiring is required for memory intrinsics due to the fact that memory intrinsics can be split when either the source or dest allocas are split. In the case where the source alloca drives the splitting, we need to be careful to pass migrateDebugInfo the information in relation to the dest alloca.

Diff Detail

Event Timeline

Orlando created this revision.Feb 2 2023, 12:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2023, 12:46 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
Orlando requested review of this revision.Feb 2 2023, 12:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2023, 12:46 AM

Additional note: I added -sroa-skip-mem2reg / SROASkipMem2Reg as a testing and debugging flag to improve testing of assignment tracking debug-info. It's useful to be able to verify that the SROA'd stores are linked to the resultant dbg.assigns (i.e. their DIAssignID metadata is correct). It's much easier to tell SROA "please don't mem2reg" than to come up with or reduce inputs that result in SROA scalaraizing something without those stores getting promoted by mem2reg.

Looks broadly good to me, with some small suggestions.

llvm/lib/Transforms/Scalar/SROA.cpp
168–169

This looks like it would miss the case where Target.OffsetInBits + Target.SizeInBits > CurrentFragment->OffsetInBits + CurrentFragment->SizeInBits, i.e. the target fragment starts inside the current fragment but extends beyond it.

Optionally, I think the logic in this check might be easier to write and understand if we first set variables (Target|Current)Slice(Start|End), and then both this and the above check could be combined with TargetSliceStart >= CurrentSliceStart && TargetSliceEnd <= CurrentSliceEnd.

179

Slightly confusing that the name has changed to AbsoluteOffsetInBits but the description still says it is relative - is this an update error? If not, I think this might need a variable name that specifies what it is relative to.

246

With the guard against !NewFragment above, this could be simplified?

Orlando updated this revision to Diff 496418.Feb 10 2023, 4:10 AM

Thanks @StephenTozer - I've addressed your suggestions. I've also removed AllocaSliceRewriter::RelativeOffset, which I had added in a previous patch.

llvm/lib/Transforms/Scalar/SROA.cpp
168–169

Good catch, I've added the helper methods startInBits and endInBits to DIExpression::FragmentInfo.

179

Ah you're right that is confusing - is that better? It is a little difficult to convey in a short-ish name exactly what it is + "InBits" (which I think is a useful suffix in the absence of bit/byte types).

To be clear, it's the slice's start bit in OldAlloca rather than its offset in the new alloca (if there is one).

246

Huh, you're right, nice one. Still have to use the !(x == y) form due to lack of operator!= overload though.

StephenTozer added inline comments.Feb 10 2023, 8:07 AM
llvm/include/llvm/IR/DebugInfoMetadata.h
2782

Nit so small you'd need an electron microscope (so feel free to ignore if you disagree), but imo if an illustrative example is being used to demonstrate that this returns the sum of the size and offset, they should both be non-zero values to make it clear that it's the sum and not just selecting the size.

llvm/lib/Transforms/Scalar/SROA.cpp
167–168

This check now subsumes the check above - since the fragment offset and size are always positive (we've got bigger problems if they aren't!), CurrentFragment->endInBits() <= Target.startInBits() will never be true if Target.startInBits() < CurrentFragment->startInBits() isn't (and same for the second condition).

179

YMMV but better to have a long-but-descriptive name than a short name that obscures or confuses the meaning of the variable - new one LGTM!

Orlando updated this revision to Diff 496497.Feb 10 2023, 8:47 AM
Orlando marked 4 inline comments as done.

+ Address comments

llvm/include/llvm/IR/DebugInfoMetadata.h
2782

This is reasonable and wise. Done.

llvm/lib/Transforms/Scalar/SROA.cpp
167–168

This is true - removed the first check and updated the comments.

StephenTozer accepted this revision.Feb 10 2023, 9:07 AM

Thanks for the changes, LGTM.

This revision is now accepted and ready to land.Feb 10 2023, 9:07 AM

Thank you for the review!

This revision was landed with ongoing or failed builds.Feb 10 2023, 10:10 AM
This revision was automatically updated to reflect the committed changes.