https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/143592
>From fb65cb7f043586eb6808b229fd1ad018ffd7571d Mon Sep 17 00:00:00 2001 From: Stephen Tozer <stephen.to...@sony.com> Date: Tue, 10 Jun 2025 20:00:51 +0100 Subject: [PATCH] [DLCov] Origin-Tracking: Core implementation --- llvm/include/llvm/IR/DebugLoc.h | 49 +++++++++++++++++++++++++----- llvm/include/llvm/IR/Instruction.h | 2 +- llvm/lib/CodeGen/BranchFolding.cpp | 7 +++++ llvm/lib/IR/DebugLoc.cpp | 22 +++++++++++++- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/IR/DebugLoc.h b/llvm/include/llvm/IR/DebugLoc.h index 999e03b6374a5..6d79aa6b2aa01 100644 --- a/llvm/include/llvm/IR/DebugLoc.h +++ b/llvm/include/llvm/IR/DebugLoc.h @@ -27,6 +27,21 @@ namespace llvm { class Function; #if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE +#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN + struct DbgLocOrigin { + static constexpr unsigned long MaxDepth = 16; + using StackTracesTy = + SmallVector<std::pair<int, std::array<void *, MaxDepth>>, 0>; + StackTracesTy StackTraces; + DbgLocOrigin(bool ShouldCollectTrace); + void addTrace(); + const StackTracesTy &getOriginStackTraces() const { return StackTraces; }; + }; +#else + struct DbgLocOrigin { + DbgLocOrigin(bool) {} + }; +#endif // Used to represent different "kinds" of DebugLoc, expressing that the // instruction it is part of is either normal and should contain a valid // DILocation, or otherwise describing the reason why the instruction does @@ -55,22 +70,29 @@ namespace llvm { Temporary }; - // Extends TrackingMDNodeRef to also store a DebugLocKind, allowing Debugify - // to ignore intentionally-empty DebugLocs. - class DILocAndCoverageTracking : public TrackingMDNodeRef { + // Extends TrackingMDNodeRef to also store a DebugLocKind and Origin, + // allowing Debugify to ignore intentionally-empty DebugLocs and display the + // code responsible for generating unintentionally-empty DebugLocs. + // Currently we only need to track the Origin of this DILoc when using a + // DebugLoc that is not annotated (i.e. has DebugLocKind::Normal) and has a + // null DILocation, so only collect the origin stacktrace in those cases. + class DILocAndCoverageTracking : public TrackingMDNodeRef, + public DbgLocOrigin { public: DebugLocKind Kind; // Default constructor for empty DebugLocs. DILocAndCoverageTracking() - : TrackingMDNodeRef(nullptr), Kind(DebugLocKind::Normal) {} - // Valid or nullptr MDNode*, normal DebugLocKind. + : TrackingMDNodeRef(nullptr), DbgLocOrigin(true), + Kind(DebugLocKind::Normal) {} + // Valid or nullptr MDNode*, no annotative DebugLocKind. DILocAndCoverageTracking(const MDNode *Loc) - : TrackingMDNodeRef(const_cast<MDNode *>(Loc)), + : TrackingMDNodeRef(const_cast<MDNode *>(Loc)), DbgLocOrigin(!Loc), Kind(DebugLocKind::Normal) {} LLVM_ABI DILocAndCoverageTracking(const DILocation *Loc); // Explicit DebugLocKind, which always means a nullptr MDNode*. DILocAndCoverageTracking(DebugLocKind Kind) - : TrackingMDNodeRef(nullptr), Kind(Kind) {} + : TrackingMDNodeRef(nullptr), + DbgLocOrigin(Kind == DebugLocKind::Normal), Kind(Kind) {} }; template <> struct simplify_type<DILocAndCoverageTracking> { using SimpleType = MDNode *; @@ -187,6 +209,19 @@ namespace llvm { #endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE } +#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN + const DbgLocOrigin::StackTracesTy &getOriginStackTraces() const { + return Loc.getOriginStackTraces(); + } + DebugLoc getCopied() const { + DebugLoc NewDL = *this; + NewDL.Loc.addTrace(); + return NewDL; + } +#else + DebugLoc getCopied() const { return *this; } +#endif + /// Get the underlying \a DILocation. /// /// \pre !*this or \c isa<DILocation>(getAsMDNode()). diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 8e1ef24226789..ef382a9168f24 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -507,7 +507,7 @@ class Instruction : public User, LLVM_ABI bool extractProfTotalWeight(uint64_t &TotalVal) const; /// Set the debug location information for this instruction. - void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } + void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc).getCopied(); } /// Return the debug location for this node as a DebugLoc. const DebugLoc &getDebugLoc() const { return DbgLoc; } diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index ff9f0ff5d5bc3..3b3e7a418feb5 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -42,6 +42,7 @@ #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Config/llvm-config.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" @@ -933,7 +934,13 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB, // Sort by hash value so that blocks with identical end sequences sort // together. +#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN + // If origin-tracking is enabled then MergePotentialElt is no longer a POD + // type, so we need std::sort instead. + std::sort(MergePotentials.begin(), MergePotentials.end()); +#else array_pod_sort(MergePotentials.begin(), MergePotentials.end()); +#endif // Walk through equivalence sets looking for actual exact matches. while (MergePotentials.size() > 1) { diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index ffeeeb6f1e4b0..c519630b0f0d1 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -9,11 +9,31 @@ #include "llvm/IR/DebugLoc.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/DebugInfo.h" + +#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN +#include "llvm/Support/Signals.h" + +namespace llvm { +DbgLocOrigin::DbgLocOrigin(bool ShouldCollectTrace) { + if (ShouldCollectTrace) { + auto &[Depth, StackTrace] = StackTraces.emplace_back(); + Depth = sys::getStackTrace(StackTrace); + } +} +void DbgLocOrigin::addTrace() { + if (StackTraces.empty()) + return; + auto &[Depth, StackTrace] = StackTraces.emplace_back(); + Depth = sys::getStackTrace(StackTrace); +} +} // namespace llvm +#endif + using namespace llvm; #if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE DILocAndCoverageTracking::DILocAndCoverageTracking(const DILocation *L) - : TrackingMDNodeRef(const_cast<DILocation *>(L)), + : TrackingMDNodeRef(const_cast<DILocation *>(L)), DbgLocOrigin(!L), Kind(DebugLocKind::Normal) {} #endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits