Skip to content
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

[DebugInfo][RemoveDIs] Assert if we mix PHIs and debug-info #84054

Merged
merged 1 commit into from
Mar 11, 2024

Conversation

jmorse
Copy link
Member

@jmorse jmorse commented Mar 5, 2024

A potentially erroneous code construction with the work we've done to remove debug intrinsics, is inserting PHIs into blocks when the position hasn't been "sourced correctly". Specifically, if you have:

%foo = PHI
#dbg_value
%bar = add i32...

And plan on inserting a new PHI, you have to use the iterator form of getFirstNonPHI or getFirstInsertionPt (or begin()) to acquire an iterator that tells the debug-info maintenance code "this is supposed to be at the start of the block, put it in front of #dbg_value". We can detect call-sites that aren't doing this at runtime, and should do with this assertion. It might invalidate code that's doing something very unexpected, like walking backwards to find a PHI, then going forwards, then inserting: however that's just an inefficient way of calling getFirstNonPHI.

~

While we can detect this at runtime, it's sort of a sticking plaster. It seems like we might have to end up converting getFirstNonPHI to return an iterator, which is going to be annoying (128 call-sites in llvm/lib/Transforms). However this is all the natural consequence of putting debug-info correctness into the type system which is why we're doing this anyway.

A potentially erronous code construction with the work we've done to remove
debug intrinsics, is inserting PHIs into blocks when the position hasn't
been "sourced correctly". Specifically, if you have:

    %foo = PHI
    #dbg_value
    %bar = add i32...

And plan on inserting a new PHI, you have to use the iterator form of
getFirstNonPHI or getFirstInsertionPt (or begin()) to acquire an iterator
that tells the debug-info maintenence code "this is supposed to be at the
start of the block, put it in front of #dbg_value". We can detect
call-sites that aren't doing this at runtime, and should do with this
assertion. It might invalidate code that's doing something very unexpected,
like walking backwards to find a PHI, then going forwards, then inserting:
however that's just an inefficient way of calling getFirstNonPHI.
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 5, 2024

@llvm/pr-subscribers-llvm-ir

Author: Jeremy Morse (jmorse)

Changes

A potentially erroneous code construction with the work we've done to remove debug intrinsics, is inserting PHIs into blocks when the position hasn't been "sourced correctly". Specifically, if you have:

%foo = PHI
#dbg_value
%bar = add i32...

And plan on inserting a new PHI, you have to use the iterator form of getFirstNonPHI or getFirstInsertionPt (or begin()) to acquire an iterator that tells the debug-info maintenance code "this is supposed to be at the start of the block, put it in front of #dbg_value". We can detect call-sites that aren't doing this at runtime, and should do with this assertion. It might invalidate code that's doing something very unexpected, like walking backwards to find a PHI, then going forwards, then inserting: however that's just an inefficient way of calling getFirstNonPHI.

~

While we can detect this at runtime, it's sort of a sticking plaster. It seems like we might have to end up converting getFirstNonPHI to return an iterator, which is going to be annoying (128 call-sites in llvm/lib/Transforms). However this is all the natural consequence of putting debug-info correctness into the type system which is why we're doing this anyway.


Full diff: https://github.com/llvm/llvm-project/pull/84054.diff

1 Files Affected:

  • (modified) llvm/lib/IR/Instruction.cpp (+12)
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index ce221758ef798b..e863ef3eb8d6d7 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -149,6 +149,18 @@ void Instruction::insertBefore(BasicBlock &BB,
   if (!InsertAtHead) {
     DPMarker *SrcMarker = BB.getMarker(InsertPos);
     if (SrcMarker && !SrcMarker->empty()) {
+      // If this assertion fires, the calling code is about to insert a PHI
+      // after debug-records, which would form a sequence like:
+      //     %0 = PHI
+      //     #dbg_value
+      //     %1 = PHI
+      // Which is de-normalised and undesired -- hence the assertion. To avoid
+      // this, you must insert at that position using an iterator, and it must
+      // be aquired by calling getFirstNonPHIIt / begin or similar methods on
+      // the block. This will signal to this behind-the-scenes debug-info
+      // maintenence code that you intend the PHI to be ahead of everything,
+      // including any debug-info.
+      assert(!isa<PHINode>(this) && "Inserting PHI after debug-records!");
       adoptDbgValues(&BB, InsertPos, false);
     }
   }

@jmorse
Copy link
Member Author

jmorse commented Mar 5, 2024

Testing: this compiles stage2reldeb clang successfully. I've also today merged all our modifications of PHI-creation sites to always use iterators, so it Shouldn't (TM) fire at all.

Copy link
Contributor

@OCHyams OCHyams left a comment

Choose a reason for hiding this comment

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

Makes sense, and should help people track down errant PHI insertions more quickly. SGTM.

Copy link
Collaborator

@dsandersllvm dsandersllvm left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks

@jmorse
Copy link
Member Author

jmorse commented Mar 10, 2024

@OCHyams could you land this for me, as I'm not able to monitor the buildbots tomorrow?

@OCHyams OCHyams merged commit c9465e4 into llvm:main Mar 11, 2024
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants