[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
@@ -59,6 +65,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
jmorse wrote:
I feel the term "instance of LLVM" could be more precise: can we us the word
"process" here? All other ambiguities and difficulties of fixed addresses are
brought to mind with the word process.
https://github.com/llvm/llvm-project/pull/143594
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
@@ -59,6 +65,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static SymbolizedAddressMap SymbolizedAddrs;
+static AddressSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
+ << ' ' << SymbolizedFrame << '\n';
+ }
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
jmorse wrote:
Major nit; would we be able to name the type here rather than `auto`? It'll
make the resulting code a lot easier to localise and dissect for future
readers. (The next `auto` makes sense of course).
https://github.com/llvm/llvm-project/pull/143594
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/jmorse commented: Tentative LGTM, noting that you're planning on updating docs in this PR too. I've no familiarity with the python modified alas. https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/jmorse edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
SLTozer wrote: > Are you planning to extend documentation Yes, and it probably is best if the documentation lands in this patch! https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/djtodoro edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
@@ -59,6 +65,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static SymbolizedAddressMap SymbolizedAddrs;
+static AddressSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
djtodoro wrote:
Please run `clang-format`.
https://github.com/llvm/llvm-project/pull/143594
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/djtodoro commented: @SLTozer thanks for doing this! Are you planning to extend documentation, e.g. https://llvm.org/docs/HowToUpdateDebugInfo.html#how-to-automatically-convert-tests-into-debug-info-tests? https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From e2ff01bc95a78c4372bdf538f0433dc882c070f8 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 83 ++---
llvm/utils/llvm-original-di-preservation.py | 24 +++---
2 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 5f70bc442d2f0..e8ed55a99546e 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap> SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
+ << ' ' << SymbolizedFrame << '\n';
+ }
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -375,6 +429,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -450,14 +506,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << N
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From e2ff01bc95a78c4372bdf538f0433dc882c070f8 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 83 ++---
llvm/utils/llvm-original-di-preservation.py | 24 +++---
2 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 5f70bc442d2f0..e8ed55a99546e 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap> SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
+ << ' ' << SymbolizedFrame << '\n';
+ }
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -375,6 +429,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -450,14 +506,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << N
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From afeb26be5f099d384115a55b19707bbb2a730245 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 83 ++---
llvm/utils/llvm-original-di-preservation.py | 24 +++---
2 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index c2dbdc57eb3b5..460b5e50e42d7 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap> SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
+ << ' ' << SymbolizedFrame << '\n';
+ }
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -373,6 +427,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -448,14 +504,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << N
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From afeb26be5f099d384115a55b19707bbb2a730245 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 83 ++---
llvm/utils/llvm-original-di-preservation.py | 24 +++---
2 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index c2dbdc57eb3b5..460b5e50e42d7 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,52 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap> SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+unsigned VirtualFrameNo = 0;
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
+OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(),
std::log10(Depth) + 2)
+ << ' ' << SymbolizedFrame << '\n';
+ }
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -373,6 +427,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -448,14 +504,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << N
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From ef6ccda96703764bbed694f910d56d8a3af27730 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 80 ++---
llvm/utils/llvm-original-di-preservation.py | 24 ---
2 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..01ed9de51c0b2 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +536,7 @@ static bool checkInstructi
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From ef6ccda96703764bbed694f910d56d8a3af27730 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 80 ++---
llvm/utils/llvm-original-di-preservation.py | 24 ---
2 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..01ed9de51c0b2 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +536,7 @@ static bool checkInstructi
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From e46273bec027d0accfbe6d3de9880c29977c6858 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 80 ++---
llvm/utils/llvm-original-di-preservation.py | 24 ---
2 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..01ed9de51c0b2 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +536,7 @@ static bool checkInstructi
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From e46273bec027d0accfbe6d3de9880c29977c6858 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 80 ++---
llvm/utils/llvm-original-di-preservation.py | 24 ---
2 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..01ed9de51c0b2 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +536,7 @@ static bool checkInstructi
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From 4bbd28b23847c069445d9babe9aa8a8aac5036c1 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 80 ++---
llvm/utils/llvm-original-di-preservation.py | 24 ---
2 files changed, 85 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..01ed9de51c0b2 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,23 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+ {"metadata", "DILocation"},
+ {"fn-name", FnName.str()},
+ {"bb-name", BBName.str()},
+ {"instr", InstName},
+ {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+ {"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +536,7 @@ static bool checkInstructi
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer ready_for_review https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
github-actions[bot] wrote: :warning: undef deprecator found issues in your code. :warning: You can test this locally with the following command: ``bash git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 'HEAD~1' HEAD clang/test/CIR/CodeGen/ctor.cpp clang/test/CodeGen/X86/cygwin-varargs.c clang/test/OpenMP/for_private_reduction_codegen.cpp flang-rt/include/flang-rt/runtime/work-queue.h flang-rt/lib/runtime/work-queue.cpp libcxx/test/std/time/time.point/time.point.arithmetic/op_++.pass.cpp libcxx/test/std/time/time.point/time.point.arithmetic/op_++int.pass.cpp libcxx/test/std/time/time.point/time.point.arithmetic/op_--.pass.cpp libcxx/test/std/time/time.point/time.point.arithmetic/op_--int.pass.cpp llvm/test/CodeGen/AMDGPU/move-to-valu-pseudo-scalar-trans-f16-fake16.ll llvm/test/CodeGen/AMDGPU/move-to-valu-pseudo-scalar-trans-f16-true16.ll llvm/test/CodeGen/RISCV/select-cond.ll llvm/test/CodeGen/X86/bsf.ll llvm/test/CodeGen/X86/bsr.ll llvm/test/Transforms/IndVarSimplify/iv-cmp-sext.ll llvm/test/Transforms/LoopUnroll/peel-last-iteration-minmax.ll llvm/test/Transforms/LowerMatrixIntrinsics/unary.ll openmp/runtime/test/worksharing/for/omp_for_private_reduction.cpp bolt/include/bolt/Core/BinaryFunction.h bolt/include/bolt/Profile/DataReader.h bolt/include/bolt/Profile/ProfileYAMLMapping.h bolt/lib/Core/BinaryFunction.cpp bolt/lib/Passes/ProfileQualityStats.cpp bolt/lib/Profile/DataAggregator.cpp bolt/lib/Profile/DataReader.cpp bolt/lib/Profile/YAMLProfileReader.cpp bolt/lib/Profile/YAMLProfileWriter.cpp clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp clang-tools-extra/clang-tidy/abseil/CleanupCtadCheck.cpp clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/android/AndroidTidyModule.cpp clang-tools-extra/clang-tidy/boost/BoostTidyModule.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp clang-tools-extra/clang-tidy/bugprone/StringviewNullptrCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp clang-tools-extra/clang-tidy/concurrency/ConcurrencyTidyModule.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp clang-tools-extra/clang-tidy/darwin/DarwinTidyModule.cpp clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp clang-tools-extra/clang-tidy/llvmlibc/CalleeNamespaceCheck.cpp clang-tools-extra/clang-tidy/llvmlibc/LLVMLibcTidyModule.cpp clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp clang-tools-extra/clang-tidy/mpi/MPITidyModule.cpp clang-tools-extra/clang-tidy/objc/NSDateFormatterCheck.cpp clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp clang-tools-extra/clang-tidy/openmp/OpenMPTidyModule.cpp clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp clang-tools-extra/clang-tidy/plugin/ClangTidyPlugin.cpp clang-tools-extra/clang-tidy/portability/PortabilityTidyModule.cpp clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierC
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer edited https://github.com/llvm/llvm-project/pull/143594 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From c973e73b792cc1440af7c9001a0ddcfef94a9e21 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 77 ++---
llvm/utils/llvm-original-di-preservation.py | 22 +++---
2 files changed, 80 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..a9a66baf5571f 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,20 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+{"metadata", "DILocation"}, {"fn-name", FnName.str()},
+{"bb-name", BBName.str()}, {"instr", InstName}, {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+{"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +533,7 @@ static bool checkInstructions(const DebugInstMap
&DILocsB
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer updated
https://github.com/llvm/llvm-project/pull/143594
>From c973e73b792cc1440af7c9001a0ddcfef94a9e21 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 77 ++---
llvm/utils/llvm-original-di-preservation.py | 22 +++---
2 files changed, 80 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..a9a66baf5571f 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,20 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+{"metadata", "DILocation"}, {"fn-name", FnName.str()},
+{"bb-name", BBName.str()}, {"instr", InstName}, {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+{"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +533,7 @@ static bool checkInstructions(const DebugInstMap
&DILocsB
[llvm-branch-commits] [llvm] [DLCov] Origin-Tracking: Add debugify support (PR #143594)
https://github.com/SLTozer created
https://github.com/llvm/llvm-project/pull/143594
None
>From 4786afd40d73ade22952ca43af1164c6f9545679 Mon Sep 17 00:00:00 2001
From: Stephen Tozer
Date: Tue, 10 Jun 2025 20:02:36 +0100
Subject: [PATCH] [DLCov] Origin-Tracking: Add debugify support
---
llvm/lib/Transforms/Utils/Debugify.cpp | 77 ++---
llvm/utils/llvm-original-di-preservation.py | 22 +++---
2 files changed, 80 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp
b/llvm/lib/Transforms/Utils/Debugify.cpp
index 729813a92f516..a9a66baf5571f 100644
--- a/llvm/lib/Transforms/Utils/Debugify.cpp
+++ b/llvm/lib/Transforms/Utils/Debugify.cpp
@@ -15,7 +15,10 @@
#include "llvm/Transforms/Utils/Debugify.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/config.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/InstIterator.h"
@@ -28,6 +31,11 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// We need the Signals header to operate on stacktraces if we're using DebugLoc
+// origin-tracking.
+#include "llvm/Support/Signals.h"
+#endif
#define DEBUG_TYPE "debugify"
@@ -59,6 +67,49 @@ cl::opt DebugifyLevel(
raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+// These maps refer to addresses in this instance of LLVM, so we can reuse them
+// everywhere - therefore, we store them at file scope.
+static DenseMap SymbolizedAddrs;
+static DenseSet UnsymbolizedAddrs;
+
+std::string symbolizeStackTrace(const Instruction *I) {
+ // We flush the set of unsymbolized addresses at the latest possible moment,
+ // i.e. now.
+ if (!UnsymbolizedAddrs.empty()) {
+sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
+UnsymbolizedAddrs.clear();
+ }
+ auto OriginStackTraces = I->getDebugLoc().getOriginStackTraces();
+ std::string Result;
+ raw_string_ostream OS(Result);
+ for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
+if (TraceIdx != 0)
+ OS << "\n";
+auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx];
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
+ "Expected each address to have been symbolized.");
+ OS << right_justify(formatv("#{0}", Frame).str(), std::log10(Depth) + 2)
+ << ' ' << SymbolizedAddrs[StackTrace[Frame]];
+}
+ }
+ return Result;
+}
+void collectStackAddresses(Instruction &I) {
+ auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces();
+ for (auto &[Depth, StackTrace] : OriginStackTraces) {
+for (int Frame = 0; Frame < Depth; ++Frame) {
+ void *Addr = StackTrace[Frame];
+ if (!SymbolizedAddrs.contains(Addr))
+UnsymbolizedAddrs.insert(Addr);
+}
+ }
+}
+#else
+void collectStackAddresses(Instruction &I) {}
+#endif // LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+
uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
}
@@ -379,6 +430,8 @@ bool llvm::collectDebugInfoMetadata(Module &M,
LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
DebugInfoBeforePass.InstToDelete.insert({&I, &I});
+// Track the addresses to symbolize, if the feature is enabled.
+collectStackAddresses(I);
DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)});
}
}
@@ -454,14 +507,20 @@ static bool checkInstructions(const DebugInstMap
&DILocsBefore,
auto BBName = BB->hasName() ? BB->getName() : "no-name";
auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
+auto CreateJSONBugEntry = [&](const char *Action) {
+ Bugs.push_back(llvm::json::Object({
+{"metadata", "DILocation"}, {"fn-name", FnName.str()},
+{"bb-name", BBName.str()}, {"instr", InstName}, {"action", Action},
+#if LLVM_ENABLE_DEBUGLOC_ORIGIN_TRACKING
+{"origin", symbolizeStackTrace(Instr)},
+#endif
+ }));
+};
+
auto InstrIt = DILocsBefore.find(Instr);
if (InstrIt == DILocsBefore.end()) {
if (ShouldWriteIntoJSON)
-Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
- {"fn-name", FnName.str()},
- {"bb-name", BBName.str()},
- {"instr", InstName},
- {"action", "not-generate"}}));
+CreateJSONBugEntry("not-generate");
else
dbg() << "WARNING: " << NameOfWrappedPass
<< " did not generate DILocation for " << *Instr
@@ -474,11 +533,7 @@ static bool checkInstructions(const DebugInstMap
&D
