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] Don't pointlessly scan funcs for debug-info #79327

Merged
merged 1 commit into from
Jan 26, 2024

Conversation

jmorse
Copy link
Member

@jmorse jmorse commented Jan 24, 2024

The utility functions this patch modifies are part of cleanly transitioning from a context where we use dbg.value intrinsics to one where we use DPValue objects to record debug-info, and back again. However, this is a waste of time in non-debug builds (i.e. no -g on the command line). We still have to call the function on all blocks though to set the IsNewDbgInfoFormat flag.

To reduce the overhead of this, test whether there's any debug-info in the function by checking whether the function has a DISubprogram, and pass a flag down to the utility functions indicating whether they can skip the scan.

It feels a bit dumb to me now that we're scanning and setting a flag in a load of blocks when we don't have to -- however it's been really valuable during development for working out where spurious dbg.value intrinsics leak into a RemoveDIs context. Happily we'll be able to just delete this flag entirely when RemoveDIs lands and sticks, and the conversion routines will eventually be pushed down into the debug-info autoupgrade path.

The utility functions this patch modifies are part of cleanly transitioning
from a context where we use dbg.value intrinsics to one where we use
DPValue objects to record debug-info, and back again. However, this is a
waste of time in non-debug builds (i.e. no -g on the command line). We
still have to call the function on all blocks though to set the
IsNewDbgInfoFormat flag.

To reduce the overhead of this, test whether there's any debug-info in the
function by checking whether the function has a DISubprogram, and pass a
flag down to the utility functions indicating whether they can skip the
scan.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 24, 2024

@llvm/pr-subscribers-llvm-ir

Author: Jeremy Morse (jmorse)

Changes

The utility functions this patch modifies are part of cleanly transitioning from a context where we use dbg.value intrinsics to one where we use DPValue objects to record debug-info, and back again. However, this is a waste of time in non-debug builds (i.e. no -g on the command line). We still have to call the function on all blocks though to set the IsNewDbgInfoFormat flag.

To reduce the overhead of this, test whether there's any debug-info in the function by checking whether the function has a DISubprogram, and pass a flag down to the utility functions indicating whether they can skip the scan.

It feels a bit dumb to me now that we're scanning and setting a flag in a load of blocks when we don't have to -- however it's been really valuable during development for working out where spurious dbg.value intrinsics leak into a RemoveDIs context. Happily we'll be able to just delete this flag entirely when RemoveDIs lands and sticks, and the conversion routines will eventually be pushed down into the debug-info autoupgrade path.


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

3 Files Affected:

  • (modified) llvm/include/llvm/IR/BasicBlock.h (+6-2)
  • (modified) llvm/lib/IR/BasicBlock.cpp (+10-2)
  • (modified) llvm/lib/IR/Function.cpp (+4-2)
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index a72b68d867f36e7..39ac9a5cf4a5e40 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -81,12 +81,16 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
   /// intrinsics into DPMarker / DPValue records. Deletes all dbg.values in
   /// the process and sets IsNewDbgInfoFormat = true. Only takes effect if
   /// the UseNewDbgInfoFormat LLVM command line option is given.
-  void convertToNewDbgValues();
+  /// \param HasNoDebugInfo Flag indicating the scan of instructions should be
+  /// skipped as the function is known to have no debug-info.
+  void convertToNewDbgValues(bool HasNoDebugInfo = false);
 
   /// Convert variable location debugging information stored in DPMarkers and
   /// DPValues into the dbg.value intrinsic representation. Sets
   /// IsNewDbgInfoFormat = false.
-  void convertFromNewDbgValues();
+  /// \param HasNoDebugInfo Flag indicating the scan of instructions should be
+  /// skipped as the function is known to have no debug-info.
+  void convertFromNewDbgValues(bool HasNoDebugInfo = false);
 
   /// Ensure the block is in "old" dbg.value format (\p NewFlag == false) or
   /// in the new format (\p NewFlag == true), converting to the desired format
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index dca528328384701..e9d15989b6e5e8e 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -60,13 +60,17 @@ DPMarker *BasicBlock::createMarker(InstListType::iterator It) {
   return DPM;
 }
 
-void BasicBlock::convertToNewDbgValues() {
+void BasicBlock::convertToNewDbgValues(bool HasNoDebugInfo) {
   // Is the command line option set?
   if (!UseNewDbgInfoFormat)
     return;
 
   IsNewDbgInfoFormat = true;
 
+  // If the caller knows there's no debug-info in this function, do nothing.
+  if (HasNoDebugInfo)
+    return;
+
   // Iterate over all instructions in the instruction list, collecting dbg.value
   // instructions and converting them to DPValues. Once we find a "real"
   // instruction, attach all those DPValues to a DPMarker in that instruction.
@@ -93,10 +97,14 @@ void BasicBlock::convertToNewDbgValues() {
   }
 }
 
-void BasicBlock::convertFromNewDbgValues() {
+void BasicBlock::convertFromNewDbgValues(bool HasNoDebugInfo) {
   invalidateOrders();
   IsNewDbgInfoFormat = false;
 
+  // If the caller knows there's no debug-info in this function, do nothing.
+  if (HasNoDebugInfo)
+    return;
+
   // Iterate over the block, finding instructions annotated with DPMarkers.
   // Convert any attached DPValues to dbg.values and insert ahead of the
   // instruction.
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 22e2455462bf445..58e180c2fd6a519 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -83,15 +83,17 @@ static cl::opt<unsigned> NonGlobalValueMaxNameSize(
 
 void Function::convertToNewDbgValues() {
   IsNewDbgInfoFormat = true;
+  bool HasNoDebugInfo = getSubprogram() == nullptr;
   for (auto &BB : *this) {
-    BB.convertToNewDbgValues();
+    BB.convertToNewDbgValues(HasNoDebugInfo);
   }
 }
 
 void Function::convertFromNewDbgValues() {
   IsNewDbgInfoFormat = false;
+  bool HasNoDebugInfo = getSubprogram() == nullptr;
   for (auto &BB : *this) {
-    BB.convertFromNewDbgValues();
+    BB.convertFromNewDbgValues(HasNoDebugInfo);
   }
 }
 

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.

Seems sensible, LGTM

@jmorse jmorse merged commit c23608b into llvm:main Jan 26, 2024
4 of 5 checks passed
jmorse added a commit that referenced this pull request Jan 26, 2024
…-info (#79327)"

This reverts commit c23608b.

It looks like this depends on #79345, which isn't going to land today, so revert for now.
jmorse added a commit to jmorse/llvm-project that referenced this pull request Feb 7, 2024
It turned out that this debug-info patch depended on another one that I
wasn't going to land immediately; now that it's in, reapply the original.

Switch to using presence of the CU as an indicator that we're building with
debug-info. There are too many tests without DISubprograms for this to work
it seems, and it's not a verifier requirement that all functions have
DISubprograms.

Original commit message and PR num follows:

[DebugInfo][RemoveDIs] Don't pointlessly scan funcs for debug-info (llvm#79327)

The utility functions this patch modifies are part of cleanly
transitioning from a context where we use dbg.value intrinsics to one
where we use DPValue objects to record debug-info, and back again.
However, this is a waste of time in non-debug builds (i.e. no -g on the
command line). We still have to call the function on all blocks though
to set the IsNewDbgInfoFormat flag.

To reduce the overhead of this, test whether there's any debug-info in
the function by checking whether the function has a DISubprogram, and
pass a flag down to the utility functions indicating whether they can
skip the scan.

It feels a bit dumb to me now that we're scanning and setting a flag in
a load of blocks when we don't have to -- however it's been really
valuable during development for working out where spurious dbg.value
intrinsics leak into a RemoveDIs context. Happily we'll be able to just
delete this flag entirely when RemoveDIs lands and sticks, and the
conversion routines will eventually be pushed down into the debug-info
autoupgrade path.
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.

None yet

3 participants