aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DebugInfo.cpp
diff options
context:
space:
mode:
authorBjörn Pettersson <bjorn.a.pettersson@ericsson.com>2025-09-25 15:20:55 +0200
committerGitHub <noreply@github.com>2025-09-25 13:20:55 +0000
commit0956febc4c1d7c66eae0064ce02dbb98880021dc (patch)
tree505b45060d16aee9617f58f529c2695170060897 /llvm/lib/IR/DebugInfo.cpp
parent48a0bb71053bf4dd7884cae998ed341df02ecef3 (diff)
downloadllvm-0956febc4c1d7c66eae0064ce02dbb98880021dc.zip
llvm-0956febc4c1d7c66eae0064ce02dbb98880021dc.tar.gz
llvm-0956febc4c1d7c66eae0064ce02dbb98880021dc.tar.bz2
[DebugInfo] Handle followup loop metadata in updateLoopMetadataDebugLocations (#157557)
Inliner/IROutliner/CodeExtractor all uses the updateLoopMetadataDebugLocations helper in order to modify debug location related to loop metadata. However, the helper has only been updating DILocation nodes found as operands to the first level of the MD_loop metadata. There could however be more DILocations as part of the various kinds of followup metadata. A typical example would be llvm.loop metadata like this !6 = distinct !{!6, !7, !8, !9, !10, !11} !7 = !DILocation(line: 6, column: 3, scope: !3) !8 = !DILocation(line: 7, column: 22, scope: !3) !11 = !{!"llvm.loop.distribute.followup_all", !7, !8, ..., !14} !14 = !{!"llvm.loop.vectorize.followup_all", !7, !8, ...} Instead of just updating !7 and !8 in !6, this patch make sure that we now recursively update the DILocations in !11 and !14 as well. Fixes #141568
Diffstat (limited to 'llvm/lib/IR/DebugInfo.cpp')
-rw-r--r--llvm/lib/IR/DebugInfo.cpp38
1 files changed, 35 insertions, 3 deletions
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 166521a..f9ded50 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -375,6 +375,38 @@ bool DebugInfoFinder::addScope(DIScope *Scope) {
return true;
}
+/// Recursively handle DILocations in followup metadata etc.
+///
+/// TODO: If for example a followup loop metadata would refence itself this
+/// function would go into infinite recursion. We do not expect such cycles in
+/// the loop metadata (except for the self-referencing first element
+/// "LoopID"). However, we could at least handle such situations more gracefully
+/// somehow (e.g. by keeping track of visited nodes and dropping metadata).
+static Metadata *updateLoopMetadataDebugLocationsRecursive(
+ Metadata *MetadataIn, function_ref<Metadata *(Metadata *)> Updater) {
+ const MDTuple *M = dyn_cast_or_null<MDTuple>(MetadataIn);
+ // The loop metadata options should start with a MDString.
+ if (!M || M->getNumOperands() < 1 || !isa<MDString>(M->getOperand(0)))
+ return MetadataIn;
+
+ bool Updated = false;
+ SmallVector<Metadata *, 4> MDs{M->getOperand(0)};
+ for (Metadata *MD : llvm::drop_begin(M->operands())) {
+ if (!MD) {
+ MDs.push_back(nullptr);
+ continue;
+ }
+ Metadata *NewMD =
+ Updater(updateLoopMetadataDebugLocationsRecursive(MD, Updater));
+ if (NewMD)
+ MDs.push_back(NewMD);
+ Updated |= NewMD != MD;
+ }
+
+ assert(!M->isDistinct() && "M should not be distinct.");
+ return Updated ? MDNode::get(M->getContext(), MDs) : MetadataIn;
+}
+
static MDNode *updateLoopMetadataDebugLocationsImpl(
MDNode *OrigLoopID, function_ref<Metadata *(Metadata *)> Updater) {
assert(OrigLoopID && OrigLoopID->getNumOperands() > 0 &&
@@ -385,11 +417,11 @@ static MDNode *updateLoopMetadataDebugLocationsImpl(
// Save space for the self-referential LoopID.
SmallVector<Metadata *, 4> MDs = {nullptr};
- for (unsigned i = 1; i < OrigLoopID->getNumOperands(); ++i) {
- Metadata *MD = OrigLoopID->getOperand(i);
+ for (Metadata *MD : llvm::drop_begin(OrigLoopID->operands())) {
if (!MD)
MDs.push_back(nullptr);
- else if (Metadata *NewMD = Updater(MD))
+ else if (Metadata *NewMD = Updater(
+ updateLoopMetadataDebugLocationsRecursive(MD, Updater)))
MDs.push_back(NewMD);
}