1 | //===-- llvm/CodeGen/MachineModuleInfo.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 | // Collect meta information for a module. This information should be in a |
10 | // neutral form that can be used by different debugging and exception handling |
11 | // schemes. |
12 | // |
13 | // The organization of information is primarily clustered around the source |
14 | // compile units. The main exception is source line correspondence where |
15 | // inlining may interleave code from various compile units. |
16 | // |
17 | // The following information can be retrieved from the MachineModuleInfo. |
18 | // |
19 | // -- Source directories - Directories are uniqued based on their canonical |
20 | // string and assigned a sequential numeric ID (base 1.) |
21 | // -- Source files - Files are also uniqued based on their name and directory |
22 | // ID. A file ID is sequential number (base 1.) |
23 | // -- Source line correspondence - A vector of file ID, line#, column# triples. |
24 | // A DEBUG_LOCATION instruction is generated by the DAG Legalizer |
25 | // corresponding to each entry in the source line list. This allows a debug |
26 | // emitter to generate labels referenced by debug information tables. |
27 | // |
28 | //===----------------------------------------------------------------------===// |
29 | |
30 | #ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H |
31 | #define LLVM_CODEGEN_MACHINEMODULEINFO_H |
32 | |
33 | #include "llvm/ADT/DenseMap.h" |
34 | #include "llvm/ADT/PointerIntPair.h" |
35 | #include "llvm/IR/PassManager.h" |
36 | #include "llvm/MC/MCContext.h" |
37 | #include "llvm/MC/MCSymbol.h" |
38 | #include "llvm/Pass.h" |
39 | #include <memory> |
40 | #include <utility> |
41 | #include <vector> |
42 | |
43 | namespace llvm { |
44 | |
45 | class Function; |
46 | class LLVMTargetMachine; |
47 | class MachineFunction; |
48 | class Module; |
49 | |
50 | //===----------------------------------------------------------------------===// |
51 | /// This class can be derived from and used by targets to hold private |
52 | /// target-specific information for each Module. Objects of type are |
53 | /// accessed/created with MachineModuleInfo::getObjFileInfo and destroyed when |
54 | /// the MachineModuleInfo is destroyed. |
55 | /// |
56 | class MachineModuleInfoImpl { |
57 | public: |
58 | using StubValueTy = PointerIntPair<MCSymbol *, 1, bool>; |
59 | using SymbolListTy = std::vector<std::pair<MCSymbol *, StubValueTy>>; |
60 | |
61 | /// A variant of SymbolListTy where the stub is a generalized MCExpr. |
62 | using ExprStubListTy = std::vector<std::pair<MCSymbol *, const MCExpr *>>; |
63 | |
64 | virtual ~MachineModuleInfoImpl(); |
65 | |
66 | protected: |
67 | /// Return the entries from a DenseMap in a deterministic sorted orer. |
68 | /// Clears the map. |
69 | static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&); |
70 | |
71 | /// Return the entries from a DenseMap in a deterministic sorted orer. |
72 | /// Clears the map. |
73 | static ExprStubListTy |
74 | getSortedExprStubs(DenseMap<MCSymbol *, const MCExpr *> &); |
75 | }; |
76 | |
77 | //===----------------------------------------------------------------------===// |
78 | /// This class contains meta information specific to a module. Queries can be |
79 | /// made by different debugging and exception handling schemes and reformated |
80 | /// for specific use. |
81 | /// |
82 | class MachineModuleInfo { |
83 | friend class MachineModuleInfoWrapperPass; |
84 | friend class MachineModuleAnalysis; |
85 | |
86 | const LLVMTargetMachine &TM; |
87 | |
88 | /// This is the MCContext used for the entire code generator. |
89 | MCContext Context; |
90 | // This is an external context, that if assigned, will be used instead of the |
91 | // internal context. |
92 | MCContext *ExternalContext = nullptr; |
93 | |
94 | /// This is the LLVM Module being worked on. |
95 | const Module *TheModule = nullptr; |
96 | |
97 | /// This is the object-file-format-specific implementation of |
98 | /// MachineModuleInfoImpl, which lets targets accumulate whatever info they |
99 | /// want. |
100 | MachineModuleInfoImpl *ObjFileMMI; |
101 | |
102 | /// \name Exception Handling |
103 | /// \{ |
104 | |
105 | /// The current call site index being processed, if any. 0 if none. |
106 | unsigned CurCallSite = 0; |
107 | |
108 | /// \} |
109 | |
110 | // TODO: Ideally, what we'd like is to have a switch that allows emitting |
111 | // synchronous (precise at call-sites only) CFA into .eh_frame. However, |
112 | // even under this switch, we'd like .debug_frame to be precise when using |
113 | // -g. At this moment, there's no way to specify that some CFI directives |
114 | // go into .eh_frame only, while others go into .debug_frame only. |
115 | |
116 | /// True if debugging information is available in this module. |
117 | bool DbgInfoAvailable = false; |
118 | |
119 | /// True if this module is being built for windows/msvc, and uses floating |
120 | /// point. This is used to emit an undefined reference to _fltused. |
121 | bool UsesMSVCFloatingPoint = false; |
122 | |
123 | /// Maps IR Functions to their corresponding MachineFunctions. |
124 | DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions; |
125 | /// Next unique number available for a MachineFunction. |
126 | unsigned NextFnNum = 0; |
127 | const Function *LastRequest = nullptr; ///< Used for shortcut/cache. |
128 | MachineFunction *LastResult = nullptr; ///< Used for shortcut/cache. |
129 | |
130 | MachineModuleInfo &operator=(MachineModuleInfo &&MMII) = delete; |
131 | |
132 | public: |
133 | explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr); |
134 | |
135 | explicit MachineModuleInfo(const LLVMTargetMachine *TM, |
136 | MCContext *ExtContext); |
137 | |
138 | MachineModuleInfo(MachineModuleInfo &&MMII); |
139 | |
140 | ~MachineModuleInfo(); |
141 | |
142 | void initialize(); |
143 | void finalize(); |
144 | |
145 | const LLVMTargetMachine &getTarget() const { return TM; } |
146 | |
147 | const MCContext &getContext() const { |
148 | return ExternalContext ? *ExternalContext : Context; |
149 | } |
150 | MCContext &getContext() { |
151 | return ExternalContext ? *ExternalContext : Context; |
152 | } |
153 | |
154 | const Module *getModule() const { return TheModule; } |
155 | |
156 | /// Returns the MachineFunction constructed for the IR function \p F. |
157 | /// Creates a new MachineFunction if none exists yet. |
158 | /// NOTE: New pass manager clients shall not use this method to get |
159 | /// the `MachineFunction`, use `MachineFunctionAnalysis` instead. |
160 | MachineFunction &getOrCreateMachineFunction(Function &F); |
161 | |
162 | /// \brief Returns the MachineFunction associated to IR function \p F if there |
163 | /// is one, otherwise nullptr. |
164 | /// NOTE: New pass manager clients shall not use this method to get |
165 | /// the `MachineFunction`, use `MachineFunctionAnalysis` instead. |
166 | MachineFunction *getMachineFunction(const Function &F) const; |
167 | |
168 | /// Delete the MachineFunction \p MF and reset the link in the IR Function to |
169 | /// Machine Function map. |
170 | void deleteMachineFunctionFor(Function &F); |
171 | |
172 | /// Add an externally created MachineFunction \p MF for \p F. |
173 | void insertFunction(const Function &F, std::unique_ptr<MachineFunction> &&MF); |
174 | |
175 | /// Keep track of various per-module pieces of information for backends |
176 | /// that would like to do so. |
177 | template<typename Ty> |
178 | Ty &getObjFileInfo() { |
179 | if (ObjFileMMI == nullptr) |
180 | ObjFileMMI = new Ty(*this); |
181 | return *static_cast<Ty*>(ObjFileMMI); |
182 | } |
183 | |
184 | template<typename Ty> |
185 | const Ty &getObjFileInfo() const { |
186 | return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>(); |
187 | } |
188 | |
189 | /// Returns true if valid debug info is present. |
190 | bool hasDebugInfo() const { return DbgInfoAvailable; } |
191 | |
192 | bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; } |
193 | |
194 | void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; } |
195 | |
196 | /// \name Exception Handling |
197 | /// \{ |
198 | |
199 | /// Set the call site currently being processed. |
200 | void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } |
201 | |
202 | /// Get the call site currently being processed, if any. return zero if |
203 | /// none. |
204 | unsigned getCurrentCallSite() { return CurCallSite; } |
205 | |
206 | /// \} |
207 | }; // End class MachineModuleInfo |
208 | |
209 | class MachineModuleInfoWrapperPass : public ImmutablePass { |
210 | MachineModuleInfo MMI; |
211 | |
212 | public: |
213 | static char ID; // Pass identification, replacement for typeid |
214 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr); |
215 | |
216 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM, |
217 | MCContext *ExtContext); |
218 | |
219 | // Initialization and Finalization |
220 | bool doInitialization(Module &) override; |
221 | bool doFinalization(Module &) override; |
222 | |
223 | MachineModuleInfo &getMMI() { return MMI; } |
224 | const MachineModuleInfo &getMMI() const { return MMI; } |
225 | }; |
226 | |
227 | /// An analysis that produces \c MachineModuleInfo for a module. |
228 | /// This does not produce its own MachineModuleInfo because we need a consistent |
229 | /// MachineModuleInfo to keep ownership of MachineFunctions regardless of |
230 | /// analysis invalidation/clearing. So something outside the analysis |
231 | /// infrastructure must own the MachineModuleInfo. |
232 | class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> { |
233 | friend AnalysisInfoMixin<MachineModuleAnalysis>; |
234 | static AnalysisKey Key; |
235 | |
236 | MachineModuleInfo &MMI; |
237 | |
238 | public: |
239 | class Result { |
240 | MachineModuleInfo &MMI; |
241 | Result(MachineModuleInfo &MMI) : MMI(MMI) {} |
242 | friend class MachineModuleAnalysis; |
243 | |
244 | public: |
245 | MachineModuleInfo &getMMI() { return MMI; } |
246 | |
247 | // MMI owes MCContext. It should never be invalidated. |
248 | bool invalidate(Module &, const PreservedAnalyses &, |
249 | ModuleAnalysisManager::Invalidator &) { |
250 | return false; |
251 | } |
252 | }; |
253 | |
254 | MachineModuleAnalysis(MachineModuleInfo &MMI) : MMI(MMI) {} |
255 | |
256 | /// Run the analysis pass and produce machine module information. |
257 | Result run(Module &M, ModuleAnalysisManager &); |
258 | }; |
259 | |
260 | } // end namespace llvm |
261 | |
262 | #endif // LLVM_CODEGEN_MACHINEMODULEINFO_H |
263 | |