-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RemoveDIs] Update DIBuilder to conditionally insert DbgRecords #84739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…also only want to do this if no terminator is present and the inst is at the end
This reverts commit 8b8cddb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible that the C-interface changes could be split into a separate patch? My concern is that it's going to be a very disruptive patch, and so the commit that breaks everyone using the llvm-c interface should be as small and specific as possible.
SGTM. We could even consider leaving the C interface in an "old-format-only-mode" until we completely remove the "old format". The only thing that'd need to change in the C API at that point would be the return type of those functions. Looking at usages of DIBuilder in LLVM and Clang, the return type isn't used very often, so applying that update to a codebase using the builder API in a similar fashion would be trivial (there may be no work to do in a lot of cases). wdyt? |
9adb5b7
to
25c66b1
Compare
Rebased, removed C-API changes as mentioned above. |
That might work - though since the work is already done, perhaps the right order would be to have a patch that adds the RemoveDI-version of the C interface and an intrinsic-focused version, then in another patch change the original function to be the RemoveDIs version - that way the downstream consumers get a nudge, but have an immediate fix if needed (change instances of the existing function to the intrinsic version), then eventually we can delete the extra versions. Does that sound reasonable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Largely looks good, some comments inline.
assert(Dest != end() && | ||
"Transferring trailing DPValues to another trailing position"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something that we see happen when building BBs in clang?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is hit by test OpenMP/cancel_codegen.cpp
assert(Where->getParent() == this); | ||
if (!Where->DbgMarker) | ||
createMarker(Where); | ||
assert(Where == end() || Where->getParent() == this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the first condition in this assert meant to be inverted? I would have thought that if Where == end()
, then Where->getParent() == this
would be trivially true!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Where == end()
then we can't dereference Where
to check the parent matches. It's checking either Where is end()
or, if it's not then the parent should match this bb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, so this is changing the condition here to account for insertions at end()
(as for the OpenMP test above), while also preventing the error you just described. Got it!
llvm/lib/IR/DIBuilder.cpp
Outdated
InsertBB->insertDPValueBefore(DPL, InsertBefore->getIterator()); | ||
else if (InsertBB) | ||
InsertBB->insertDPValueBefore(DPL, InsertBB->end()); | ||
// FIXME: Use smart pointers for DbgRecord ownership management. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would we need smart pointers for here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that was a leftover comment to myself. Not needed here, was just musing on whether introducing smart pointers to type-ify DbgRecod ownership might be beneficial in the future. Deleted the comment!
llvm/lib/Transforms/Scalar/SROA.cpp
Outdated
Dest, | ||
DIExpression::get(Expr->getContext(), std::nullopt), | ||
DbgAssign->getDebugLoc()) | ||
.template get<decltype(DbgInstType)>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++20 can't come soon enough. That being said, instead of passing the extra DbgInstType
to this class, you could create an overloaded function just above this function body:
DPValue *UnwrapDbgInstPtr(DbgInstPtr P, DPValue *) { return static_cast<DPValue*>(cast<DbgRecord*>(P)); }
`DPValue *UnwrapDbgInstPtr(DbgInstPtr P, DbgAssignIntrinsic *) { return static_cast<DbgAssignIntrinsic*>(cast<Instruction*>(P)); }
And then you could just call UnwrapDbgInstPtr(DIB.insertDbgAssign(...), DbgAssign)
here. YMMV on this though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, that moves some of the ugliness out of this lambda, which is desirable. Done.
llvm/unittests/IR/IRBuilderTest.cpp
Outdated
|
||
// Test in new-debug mode. | ||
// Reset the test then call convertToNewDbgValues to flip the flag | ||
// on the test's Module, Funciton and BasicBlock. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// on the test's Module, Funciton and BasicBlock. | |
// on the test's Module, Function and BasicBlock. |
// on the test's Module, Funciton and BasicBlock. | ||
TearDown(); | ||
SetUp(); | ||
M->convertToNewDbgValues(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to convert M
back afterwards? In some of the unit tests we do this (restore the previous state), but I'm not sure if these ones require it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question but no not needed here. The module is deleted and recreated automatically for each test with TearDown
and SetUp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that sound reasonable?
SGTM
assert(Dest != end() && | ||
"Transferring trailing DPValues to another trailing position"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is hit by test OpenMP/cancel_codegen.cpp
llvm/lib/IR/DIBuilder.cpp
Outdated
InsertBB->insertDPValueBefore(DPL, InsertBefore->getIterator()); | ||
else if (InsertBB) | ||
InsertBB->insertDPValueBefore(DPL, InsertBB->end()); | ||
// FIXME: Use smart pointers for DbgRecord ownership management. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that was a leftover comment to myself. Not needed here, was just musing on whether introducing smart pointers to type-ify DbgRecod ownership might be beneficial in the future. Deleted the comment!
// on the test's Module, Funciton and BasicBlock. | ||
TearDown(); | ||
SetUp(); | ||
M->convertToNewDbgValues(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question but no not needed here. The module is deleted and recreated automatically for each test with TearDown
and SetUp
.
llvm/lib/Transforms/Scalar/SROA.cpp
Outdated
Dest, | ||
DIExpression::get(Expr->getContext(), std::nullopt), | ||
DbgAssign->getDebugLoc()) | ||
.template get<decltype(DbgInstType)>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, that moves some of the ugliness out of this lambda, which is desirable. Done.
assert(Where->getParent() == this); | ||
if (!Where->DbgMarker) | ||
createMarker(Where); | ||
assert(Where == end() || Where->getParent() == this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Where == end()
then we can't dereference Where
to check the parent matches. It's checking either Where is end()
or, if it's not then the parent should match this bb.
Thanks for the review! |
This patch fixes problems that pop up when clang emits DbgRecords instead of debug intrinsics. Note: this doesn't mean clang is emitting DbgRecords yet, because the modules it creates are still always in the old debug mode. That will come in a future patch. Depends on #84739
This patch fixes problems that pop up when clang emits DbgRecords instead of debug intrinsics. Note: this doesn't mean clang is emitting DbgRecords yet, because the modules it creates are still always in the old debug mode. That will come in a future patch. Depends on #84739
…4915) Follow on from #84739, which updates the DIBuilder class. All the functions that have been added are temporary and will be deprecated in the future. The intention is that they'll help downstream projects adapt during the transition period. ``` New functions (all to be deprecated) ------------------------------------ LLVMIsNewDbgInfoFormat # Returns true if the module is in the new non-instruction mode. LLVMSetIsNewDbgInfoFormat # Convert to the requested debug info format. LLVMDIBuilderInsertDeclareIntrinsicBefore # Insert a debug intrinsic (old debug info format). LLVMDIBuilderInsertDeclareIntrinsicAtEnd # Same as above. LLVMDIBuilderInsertDbgValueIntrinsicBefore # Same as above. LLVMDIBuilderInsertDbgValueIntrinsicAtEnd # Same as above. LLVMDIBuilderInsertDeclareRecordBefore # Insert a debug record (new debug info format). LLVMDIBuilderInsertDeclareRecordAtEnd # Same as above. LLVMDIBuilderInsertDbgValueRecordBefore # Same as above. LLVMDIBuilderInsertDbgValueRecordAtEnd # Same as above. ``` The existing `LLVMDIBuilderInsert...` functions call through to the intrinsic versions (old debug info format) currently. In the next patch, I'll swap them to call the debug records versions (new debug info format). Downstream users of this API can query and change the current format using the first two functions above, or can instead opt to temporarily use intrinsics or records explicitly.
Have DIBuilder conditionally insert either debug intrinsics or DbgRecord depending on the module's IsNewDbgInfoFormat flag. The insertion methods now return a
DbgInstPtr
(aPointerUnion<Instruction *, DbgRecord *>
).Add a unittest for both modes (I couldn't find an existing test testing insertion behaviours specifically).
Update the DIBuilder C API. I went a different direction for this, rather than returning a union, I've added an additional set of functions.
I figured this would minimise disruption to the C API, because we'll be removing debug intrinsics entirely at some point. However, if anyone strongly feels the approach should match the DIBuilder returning-a-union interface I can change it, I'm not particularly attached to either method.
This patch changes the existing assumption that DbgRecords are only ever inserted if there's an instruction to insert-before because clang currently inserts debug intrinsics while CodeGening (like any other instruction) meaning it'll try inserting to the end of a block without a terminator. We already have machinery in place to maintain the DbgRecords when a terminator is removed - these become "trailing DbgRecords" which are re-attached when a new instruction is inserted. All I've done is allow this state to occur while inserting DbgRecords too, i.e., it's not only removing terminators that causes this valid transient state, but inserting DbgRecords into incomplete blocks too.
Note: this doesn't mean clang is emitting DbgRecords yet, because the modules it creates are still always in the old debug mode. That will come in a future patch.