xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- llvm/CodeGen/DebugHandlerBase.h -----------------------*- C++ -*--===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Common functionality for different debug information format backends.
10 // LLVM currently supports DWARF and CodeView.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_DEBUGHANDLERBASE_H
15 #define LLVM_CODEGEN_DEBUGHANDLERBASE_H
16 
17 #include "llvm/CodeGen/AsmPrinterHandler.h"
18 #include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
19 #include "llvm/CodeGen/LexicalScopes.h"
20 #include "llvm/IR/DebugInfoMetadata.h"
21 #include "llvm/IR/DebugLoc.h"
22 #include <optional>
23 
24 namespace llvm {
25 
26 class AsmPrinter;
27 class MachineInstr;
28 class MachineModuleInfo;
29 
30 /// Represents the location at which a variable is stored.
31 struct DbgVariableLocation {
32   /// Base register.
33   unsigned Register;
34 
35   /// Chain of offsetted loads necessary to load the value if it lives in
36   /// memory. Every load except for the last is pointer-sized.
37   SmallVector<int64_t, 1> LoadChain;
38 
39   /// Present if the location is part of a larger variable.
40   std::optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
41 
42   /// Extract a VariableLocation from a MachineInstr.
43   /// This will only work if Instruction is a debug value instruction
44   /// and the associated DIExpression is in one of the supported forms.
45   /// If these requirements are not met, the returned Optional will not
46   /// have a value.
47   static std::optional<DbgVariableLocation>
48   extractFromMachineInstruction(const MachineInstr &Instruction);
49 };
50 
51 /// Base class for debug information backends. Common functionality related to
52 /// tracking which variables and scopes are alive at a given PC live here.
53 class DebugHandlerBase {
54 protected:
55   DebugHandlerBase(AsmPrinter *A);
56 
57 public:
58   virtual ~DebugHandlerBase();
59 
60 protected:
61   /// Target of debug info emission.
62   AsmPrinter *Asm = nullptr;
63 
64   /// Collected machine module information.
65   MachineModuleInfo *MMI = nullptr;
66 
67   /// Previous instruction's location information. This is used to
68   /// determine label location to indicate scope boundaries in debug info.
69   /// We track the previous instruction's source location (if not line 0),
70   /// whether it was a label, and its parent BB.
71   DebugLoc PrevInstLoc;
72   MCSymbol *PrevLabel = nullptr;
73   const MachineBasicBlock *PrevInstBB = nullptr;
74 
75   /// This location indicates end of function prologue and beginning of
76   /// function body.
77   DebugLoc PrologEndLoc;
78 
79   /// This block includes epilogue instructions.
80   const MachineBasicBlock *EpilogBeginBlock = nullptr;
81 
82   /// If nonnull, stores the current machine instruction we're processing.
83   const MachineInstr *CurMI = nullptr;
84 
85   LexicalScopes LScopes;
86 
87   /// History of DBG_VALUE and clobber instructions for each user
88   /// variable.  Variables are listed in order of appearance.
89   DbgValueHistoryMap DbgValues;
90 
91   /// Mapping of inlined labels and DBG_LABEL machine instruction.
92   DbgLabelInstrMap DbgLabels;
93 
94   /// Maps instruction with label emitted before instruction.
95   /// FIXME: Make this private from DwarfDebug, we have the necessary accessors
96   /// for it.
97   DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn;
98 
99   /// Maps instruction with label emitted after instruction.
100   DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
101 
102   /// Indentify instructions that are marking the beginning of or
103   /// ending of a scope.
104   void identifyScopeMarkers();
105 
106   /// Ensure that a label will be emitted before MI.
requestLabelBeforeInsn(const MachineInstr * MI)107   void requestLabelBeforeInsn(const MachineInstr *MI) {
108     LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
109   }
110 
111   /// Ensure that a label will be emitted after MI.
requestLabelAfterInsn(const MachineInstr * MI)112   void requestLabelAfterInsn(const MachineInstr *MI) {
113     LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
114   }
115 
116   virtual void beginFunctionImpl(const MachineFunction *MF) = 0;
117   virtual void endFunctionImpl(const MachineFunction *MF) = 0;
skippedNonDebugFunction()118   virtual void skippedNonDebugFunction() {}
119 
120 private:
121   InstructionOrdering InstOrdering;
122 
123 public:
124   /// For symbols that have a size designated (e.g. common symbols),
125   /// this tracks that size. Only used by DWARF.
setSymbolSize(const MCSymbol * Sym,uint64_t Size)126   virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {}
127 
128   virtual void beginModule(Module *M);
129   virtual void endModule() = 0;
130 
131   virtual void beginInstruction(const MachineInstr *MI);
132   virtual void endInstruction();
133 
134   void beginFunction(const MachineFunction *MF);
135   void endFunction(const MachineFunction *MF);
136 
137   void beginBasicBlockSection(const MachineBasicBlock &MBB);
138   void endBasicBlockSection(const MachineBasicBlock &MBB);
139 
140   /// Return Label preceding the instruction.
141   MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
142 
143   /// Return Label immediately following the instruction.
144   MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
145 
146   /// If this type is derived from a base type then return base type size.
147   static uint64_t getBaseTypeSize(const DIType *Ty);
148 
149   /// Return true if type encoding is unsigned.
150   static bool isUnsignedDIType(const DIType *Ty);
151 
getInstOrdering()152   const InstructionOrdering &getInstOrdering() const { return InstOrdering; }
153 };
154 
155 } // namespace llvm
156 
157 #endif
158