Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:58

0001 //===- DebugInfo.h - Debug Information Helpers ------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines a bunch of datatypes that are useful for creating and
0010 // walking debug info in LLVM IR form. They essentially provide wrappers around
0011 // the information in the global variables that's needed when constructing the
0012 // DWARF information.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_IR_DEBUGINFO_H
0017 #define LLVM_IR_DEBUGINFO_H
0018 
0019 #include "llvm/ADT/DenseMapInfo.h"
0020 #include "llvm/ADT/STLExtras.h"
0021 #include "llvm/ADT/SetVector.h"
0022 #include "llvm/ADT/SmallPtrSet.h"
0023 #include "llvm/ADT/SmallSet.h"
0024 #include "llvm/ADT/SmallVector.h"
0025 #include "llvm/ADT/TinyPtrVector.h"
0026 #include "llvm/ADT/iterator_range.h"
0027 #include "llvm/IR/DataLayout.h"
0028 #include "llvm/IR/IntrinsicInst.h"
0029 #include "llvm/IR/PassManager.h"
0030 #include <optional>
0031 
0032 namespace llvm {
0033 
0034 class DbgDeclareInst;
0035 class DbgValueInst;
0036 class DbgVariableIntrinsic;
0037 class DbgVariableRecord;
0038 class Instruction;
0039 class Module;
0040 
0041 /// Finds dbg.declare intrinsics declaring local variables as living in the
0042 /// memory that 'V' points to.
0043 TinyPtrVector<DbgDeclareInst *> findDbgDeclares(Value *V);
0044 /// As above, for DVRDeclares.
0045 TinyPtrVector<DbgVariableRecord *> findDVRDeclares(Value *V);
0046 /// As above, for DVRValues.
0047 TinyPtrVector<DbgVariableRecord *> findDVRValues(Value *V);
0048 
0049 /// Finds the llvm.dbg.value intrinsics describing a value.
0050 void findDbgValues(
0051     SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V,
0052     SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords = nullptr);
0053 
0054 /// Finds the debug info intrinsics describing a value.
0055 void findDbgUsers(
0056     SmallVectorImpl<DbgVariableIntrinsic *> &DbgInsts, Value *V,
0057     SmallVectorImpl<DbgVariableRecord *> *DbgVariableRecords = nullptr);
0058 
0059 /// Find subprogram that is enclosing this scope.
0060 DISubprogram *getDISubprogram(const MDNode *Scope);
0061 
0062 /// Produce a DebugLoc to use for each dbg.declare that is promoted to a
0063 /// dbg.value.
0064 DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII);
0065 DebugLoc getDebugValueLoc(DbgVariableRecord *DVR);
0066 
0067 /// Strip debug info in the module if it exists.
0068 ///
0069 /// To do this, we remove all calls to the debugger intrinsics and any named
0070 /// metadata for debugging. We also remove debug locations for instructions.
0071 /// Return true if module is modified.
0072 bool StripDebugInfo(Module &M);
0073 bool stripDebugInfo(Function &F);
0074 
0075 /// Downgrade the debug info in a module to contain only line table information.
0076 ///
0077 /// In order to convert debug info to what -gline-tables-only would have
0078 /// created, this does the following:
0079 ///   1) Delete all debug intrinsics.
0080 ///   2) Delete all non-CU named metadata debug info nodes.
0081 ///   3) Create new DebugLocs for each instruction.
0082 ///   4) Create a new CU debug info, and similarly for every metadata node
0083 ///      that's reachable from the CU debug info.
0084 ///   All debug type metadata nodes are unreachable and garbage collected.
0085 bool stripNonLineTableDebugInfo(Module &M);
0086 
0087 /// Update the debug locations contained within the MD_loop metadata attached
0088 /// to the instruction \p I, if one exists. \p Updater is applied to Metadata
0089 /// operand in the MD_loop metadata: the returned value is included in the
0090 /// updated loop metadata node if it is non-null.
0091 void updateLoopMetadataDebugLocations(
0092     Instruction &I, function_ref<Metadata *(Metadata *)> Updater);
0093 
0094 /// Return Debug Info Metadata Version by checking module flags.
0095 unsigned getDebugMetadataVersionFromModule(const Module &M);
0096 
0097 /// Utility to find all debug info in a module.
0098 ///
0099 /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
0100 /// list debug info MDNodes used by an instruction, DebugInfoFinder uses
0101 /// processDeclare, processValue and processLocation to handle DbgDeclareInst,
0102 /// DbgValueInst and DbgLoc attached to instructions. processModule will go
0103 /// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes
0104 /// used by the CUs.
0105 class DebugInfoFinder {
0106 public:
0107   /// Process entire module and collect debug info anchors.
0108   void processModule(const Module &M);
0109   /// Process a single instruction and collect debug info anchors.
0110   void processInstruction(const Module &M, const Instruction &I);
0111 
0112   /// Process a DILocalVariable.
0113   void processVariable(const Module &M, const DILocalVariable *DVI);
0114   /// Process debug info location.
0115   void processLocation(const Module &M, const DILocation *Loc);
0116   /// Process a DbgRecord (e.g, treat a DbgVariableRecord like a
0117   /// DbgVariableIntrinsic).
0118   void processDbgRecord(const Module &M, const DbgRecord &DR);
0119 
0120   /// Process subprogram.
0121   void processSubprogram(DISubprogram *SP);
0122 
0123   /// Clear all lists.
0124   void reset();
0125 
0126 private:
0127   void processCompileUnit(DICompileUnit *CU);
0128   void processScope(DIScope *Scope);
0129   void processType(DIType *DT);
0130   bool addCompileUnit(DICompileUnit *CU);
0131   bool addGlobalVariable(DIGlobalVariableExpression *DIG);
0132   bool addScope(DIScope *Scope);
0133   bool addSubprogram(DISubprogram *SP);
0134   bool addType(DIType *DT);
0135 
0136 public:
0137   using compile_unit_iterator =
0138       SmallVectorImpl<DICompileUnit *>::const_iterator;
0139   using subprogram_iterator = SmallVectorImpl<DISubprogram *>::const_iterator;
0140   using global_variable_expression_iterator =
0141       SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator;
0142   using type_iterator = SmallVectorImpl<DIType *>::const_iterator;
0143   using scope_iterator = SmallVectorImpl<DIScope *>::const_iterator;
0144 
0145   iterator_range<compile_unit_iterator> compile_units() const {
0146     return make_range(CUs.begin(), CUs.end());
0147   }
0148 
0149   iterator_range<subprogram_iterator> subprograms() const {
0150     return make_range(SPs.begin(), SPs.end());
0151   }
0152 
0153   iterator_range<global_variable_expression_iterator> global_variables() const {
0154     return make_range(GVs.begin(), GVs.end());
0155   }
0156 
0157   iterator_range<type_iterator> types() const {
0158     return make_range(TYs.begin(), TYs.end());
0159   }
0160 
0161   iterator_range<scope_iterator> scopes() const {
0162     return make_range(Scopes.begin(), Scopes.end());
0163   }
0164 
0165   unsigned compile_unit_count() const { return CUs.size(); }
0166   unsigned global_variable_count() const { return GVs.size(); }
0167   unsigned subprogram_count() const { return SPs.size(); }
0168   unsigned type_count() const { return TYs.size(); }
0169   unsigned scope_count() const { return Scopes.size(); }
0170 
0171 private:
0172   SmallVector<DICompileUnit *, 8> CUs;
0173   SmallVector<DISubprogram *, 8> SPs;
0174   SmallVector<DIGlobalVariableExpression *, 8> GVs;
0175   SmallVector<DIType *, 8> TYs;
0176   SmallVector<DIScope *, 8> Scopes;
0177   SmallPtrSet<const MDNode *, 32> NodesSeen;
0178 };
0179 
0180 /// Assignment Tracking (at).
0181 namespace at {
0182 //
0183 // Utilities for enumerating storing instructions from an assignment ID.
0184 //
0185 /// A range of instructions.
0186 using AssignmentInstRange =
0187     iterator_range<SmallVectorImpl<Instruction *>::iterator>;
0188 /// Return a range of instructions (typically just one) that have \p ID
0189 /// as an attachment.
0190 /// Iterators invalidated by adding or removing DIAssignID metadata to/from any
0191 /// instruction (including by deleting or cloning instructions).
0192 AssignmentInstRange getAssignmentInsts(DIAssignID *ID);
0193 /// Return a range of instructions (typically just one) that perform the
0194 /// assignment that \p DAI encodes.
0195 /// Iterators invalidated by adding or removing DIAssignID metadata to/from any
0196 /// instruction (including by deleting or cloning instructions).
0197 inline AssignmentInstRange getAssignmentInsts(const DbgAssignIntrinsic *DAI) {
0198   return getAssignmentInsts(DAI->getAssignID());
0199 }
0200 
0201 inline AssignmentInstRange getAssignmentInsts(const DbgVariableRecord *DVR) {
0202   assert(DVR->isDbgAssign() &&
0203          "Can't get assignment instructions for non-assign DVR!");
0204   return getAssignmentInsts(DVR->getAssignID());
0205 }
0206 
0207 //
0208 // Utilities for enumerating llvm.dbg.assign intrinsic from an assignment ID.
0209 //
0210 /// High level: this is an iterator for llvm.dbg.assign intrinsics.
0211 /// Implementation details: this is a wrapper around Value's User iterator that
0212 /// dereferences to a DbgAssignIntrinsic ptr rather than a User ptr.
0213 class DbgAssignIt
0214     : public iterator_adaptor_base<DbgAssignIt, Value::user_iterator,
0215                                    typename std::iterator_traits<
0216                                        Value::user_iterator>::iterator_category,
0217                                    DbgAssignIntrinsic *, std::ptrdiff_t,
0218                                    DbgAssignIntrinsic **,
0219                                    DbgAssignIntrinsic *&> {
0220 public:
0221   DbgAssignIt(Value::user_iterator It) : iterator_adaptor_base(It) {}
0222   DbgAssignIntrinsic *operator*() const { return cast<DbgAssignIntrinsic>(*I); }
0223 };
0224 /// A range of llvm.dbg.assign intrinsics.
0225 using AssignmentMarkerRange = iterator_range<DbgAssignIt>;
0226 /// Return a range of dbg.assign intrinsics which use \ID as an operand.
0227 /// Iterators invalidated by deleting an intrinsic contained in this range.
0228 AssignmentMarkerRange getAssignmentMarkers(DIAssignID *ID);
0229 /// Return a range of dbg.assign intrinsics for which \p Inst performs the
0230 /// assignment they encode.
0231 /// Iterators invalidated by deleting an intrinsic contained in this range.
0232 inline AssignmentMarkerRange getAssignmentMarkers(const Instruction *Inst) {
0233   if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID))
0234     return getAssignmentMarkers(cast<DIAssignID>(ID));
0235   else
0236     return make_range(Value::user_iterator(), Value::user_iterator());
0237 }
0238 
0239 inline SmallVector<DbgVariableRecord *>
0240 getDVRAssignmentMarkers(const Instruction *Inst) {
0241   if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID))
0242     return cast<DIAssignID>(ID)->getAllDbgVariableRecordUsers();
0243   return {};
0244 }
0245 
0246 /// Delete the llvm.dbg.assign intrinsics linked to \p Inst.
0247 void deleteAssignmentMarkers(const Instruction *Inst);
0248 
0249 /// Replace all uses (and attachments) of \p Old with \p New.
0250 void RAUW(DIAssignID *Old, DIAssignID *New);
0251 
0252 /// Remove all Assignment Tracking related intrinsics and metadata from \p F.
0253 void deleteAll(Function *F);
0254 
0255 /// Calculate the fragment of the variable in \p DAI covered
0256 /// from (Dest + SliceOffsetInBits) to
0257 ///   to (Dest + SliceOffsetInBits + SliceSizeInBits)
0258 ///
0259 /// Return false if it can't be calculated for any reason.
0260 /// Result is set to nullopt if the intersect equals the variable fragment (or
0261 /// variable size) in DAI.
0262 ///
0263 /// Result contains a zero-sized fragment if there's no intersect.
0264 bool calculateFragmentIntersect(
0265     const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
0266     uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign,
0267     std::optional<DIExpression::FragmentInfo> &Result);
0268 bool calculateFragmentIntersect(
0269     const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
0270     uint64_t SliceSizeInBits, const DbgVariableRecord *DVRAssign,
0271     std::optional<DIExpression::FragmentInfo> &Result);
0272 
0273 /// Replace DIAssignID uses and attachments with IDs from \p Map.
0274 /// If an ID is unmapped a new ID is generated and added to \p Map.
0275 void remapAssignID(DenseMap<DIAssignID *, DIAssignID *> &Map, Instruction &I);
0276 
0277 /// Helper struct for trackAssignments, below. We don't use the similar
0278 /// DebugVariable class because trackAssignments doesn't (yet?) understand
0279 /// partial variables (fragment info) as input and want to make that clear and
0280 /// explicit using types. In addition, eventually we will want to understand
0281 /// expressions that modify the base address too, which a DebugVariable doesn't
0282 /// capture.
0283 struct VarRecord {
0284   DILocalVariable *Var;
0285   DILocation *DL;
0286 
0287   VarRecord(DbgVariableIntrinsic *DVI)
0288       : Var(DVI->getVariable()), DL(getDebugValueLoc(DVI)) {}
0289   VarRecord(DbgVariableRecord *DVR)
0290       : Var(DVR->getVariable()), DL(getDebugValueLoc(DVR)) {}
0291   VarRecord(DILocalVariable *Var, DILocation *DL) : Var(Var), DL(DL) {}
0292   friend bool operator<(const VarRecord &LHS, const VarRecord &RHS) {
0293     return std::tie(LHS.Var, LHS.DL) < std::tie(RHS.Var, RHS.DL);
0294   }
0295   friend bool operator==(const VarRecord &LHS, const VarRecord &RHS) {
0296     return std::tie(LHS.Var, LHS.DL) == std::tie(RHS.Var, RHS.DL);
0297   }
0298 };
0299 
0300 } // namespace at
0301 
0302 template <> struct DenseMapInfo<at::VarRecord> {
0303   static inline at::VarRecord getEmptyKey() {
0304     return at::VarRecord(DenseMapInfo<DILocalVariable *>::getEmptyKey(),
0305                          DenseMapInfo<DILocation *>::getEmptyKey());
0306   }
0307 
0308   static inline at::VarRecord getTombstoneKey() {
0309     return at::VarRecord(DenseMapInfo<DILocalVariable *>::getTombstoneKey(),
0310                          DenseMapInfo<DILocation *>::getTombstoneKey());
0311   }
0312 
0313   static unsigned getHashValue(const at::VarRecord &Var) {
0314     return hash_combine(Var.Var, Var.DL);
0315   }
0316 
0317   static bool isEqual(const at::VarRecord &A, const at::VarRecord &B) {
0318     return A == B;
0319   }
0320 };
0321 
0322 namespace at {
0323 /// Map of backing storage to a set of variables that are stored to it.
0324 /// TODO: Backing storage shouldn't be limited to allocas only. Some local
0325 /// variables have their storage allocated by the calling function (addresses
0326 /// passed in with sret & byval parameters).
0327 using StorageToVarsMap =
0328     DenseMap<const AllocaInst *, SmallSetVector<VarRecord, 2>>;
0329 
0330 /// Track assignments to \p Vars between \p Start and \p End.
0331 
0332 void trackAssignments(Function::iterator Start, Function::iterator End,
0333                       const StorageToVarsMap &Vars, const DataLayout &DL,
0334                       bool DebugPrints = false);
0335 
0336 /// Describes properties of a store that has a static size and offset into a
0337 /// some base storage. Used by the getAssignmentInfo functions.
0338 struct AssignmentInfo {
0339   AllocaInst const *Base;  ///< Base storage.
0340   uint64_t OffsetInBits;   ///< Offset into Base.
0341   uint64_t SizeInBits;     ///< Number of bits stored.
0342   bool StoreToWholeAlloca; ///< SizeInBits equals the size of the base storage.
0343 
0344   AssignmentInfo(const DataLayout &DL, AllocaInst const *Base,
0345                  uint64_t OffsetInBits, uint64_t SizeInBits)
0346       : Base(Base), OffsetInBits(OffsetInBits), SizeInBits(SizeInBits),
0347         StoreToWholeAlloca(
0348             OffsetInBits == 0 &&
0349             SizeInBits == DL.getTypeSizeInBits(Base->getAllocatedType())) {}
0350 };
0351 
0352 std::optional<AssignmentInfo> getAssignmentInfo(const DataLayout &DL,
0353                                                 const MemIntrinsic *I);
0354 std::optional<AssignmentInfo> getAssignmentInfo(const DataLayout &DL,
0355                                                 const StoreInst *SI);
0356 std::optional<AssignmentInfo> getAssignmentInfo(const DataLayout &DL,
0357                                                 const AllocaInst *AI);
0358 
0359 } // end namespace at
0360 
0361 /// Convert @llvm.dbg.declare intrinsics into sets of @llvm.dbg.assign
0362 /// intrinsics by treating stores to the dbg.declare'd address as assignments
0363 /// to the variable. Not all kinds of variables are supported yet; those will
0364 /// be left with their dbg.declare intrinsics.
0365 /// The pass sets the debug-info-assignment-tracking module flag to true to
0366 /// indicate assignment tracking has been enabled.
0367 class AssignmentTrackingPass : public PassInfoMixin<AssignmentTrackingPass> {
0368   /// Note: this method does not set the debug-info-assignment-tracking module
0369   /// flag.
0370   bool runOnFunction(Function &F);
0371 
0372 public:
0373   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0374   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0375 };
0376 
0377 /// Return true if assignment tracking is enabled for module \p M.
0378 bool isAssignmentTrackingEnabled(const Module &M);
0379 
0380 } // end namespace llvm
0381 
0382 #endif // LLVM_IR_DEBUGINFO_H