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 | virtual ~MachineModuleInfoImpl(); |
62 | |
63 | protected: |
64 | /// Return the entries from a DenseMap in a deterministic sorted orer. |
65 | /// Clears the map. |
66 | static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&); |
67 | }; |
68 | |
69 | //===----------------------------------------------------------------------===// |
70 | /// This class contains meta information specific to a module. Queries can be |
71 | /// made by different debugging and exception handling schemes and reformated |
72 | /// for specific use. |
73 | /// |
74 | class MachineModuleInfo { |
75 | friend class MachineModuleInfoWrapperPass; |
76 | friend class MachineModuleAnalysis; |
77 | |
78 | const LLVMTargetMachine &TM; |
79 | |
80 | /// This is the MCContext used for the entire code generator. |
81 | MCContext Context; |
82 | // This is an external context, that if assigned, will be used instead of the |
83 | // internal context. |
84 | MCContext *ExternalContext = nullptr; |
85 | |
86 | /// This is the LLVM Module being worked on. |
87 | const Module *TheModule = nullptr; |
88 | |
89 | /// This is the object-file-format-specific implementation of |
90 | /// MachineModuleInfoImpl, which lets targets accumulate whatever info they |
91 | /// want. |
92 | MachineModuleInfoImpl *ObjFileMMI; |
93 | |
94 | /// \name Exception Handling |
95 | /// \{ |
96 | |
97 | /// The current call site index being processed, if any. 0 if none. |
98 | unsigned CurCallSite = 0; |
99 | |
100 | /// \} |
101 | |
102 | // TODO: Ideally, what we'd like is to have a switch that allows emitting |
103 | // synchronous (precise at call-sites only) CFA into .eh_frame. However, |
104 | // even under this switch, we'd like .debug_frame to be precise when using |
105 | // -g. At this moment, there's no way to specify that some CFI directives |
106 | // go into .eh_frame only, while others go into .debug_frame only. |
107 | |
108 | /// True if debugging information is available in this module. |
109 | bool DbgInfoAvailable = false; |
110 | |
111 | /// True if this module is being built for windows/msvc, and uses floating |
112 | /// point. This is used to emit an undefined reference to _fltused. |
113 | bool UsesMSVCFloatingPoint = false; |
114 | |
115 | /// Maps IR Functions to their corresponding MachineFunctions. |
116 | DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions; |
117 | /// Next unique number available for a MachineFunction. |
118 | unsigned NextFnNum = 0; |
119 | const Function *LastRequest = nullptr; ///< Used for shortcut/cache. |
120 | MachineFunction *LastResult = nullptr; ///< Used for shortcut/cache. |
121 | |
122 | MachineModuleInfo &operator=(MachineModuleInfo &&MMII) = delete; |
123 | |
124 | public: |
125 | explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr); |
126 | |
127 | explicit MachineModuleInfo(const LLVMTargetMachine *TM, |
128 | MCContext *ExtContext); |
129 | |
130 | MachineModuleInfo(MachineModuleInfo &&MMII); |
131 | |
132 | ~MachineModuleInfo(); |
133 | |
134 | void initialize(); |
135 | void finalize(); |
136 | |
137 | const LLVMTargetMachine &getTarget() const { return TM; } |
138 | |
139 | const MCContext &getContext() const { |
140 | return ExternalContext ? *ExternalContext : Context; |
141 | } |
142 | MCContext &getContext() { |
143 | return ExternalContext ? *ExternalContext : Context; |
144 | } |
145 | |
146 | const Module *getModule() const { return TheModule; } |
147 | |
148 | /// Returns the MachineFunction constructed for the IR function \p F. |
149 | /// Creates a new MachineFunction if none exists yet. |
150 | MachineFunction &getOrCreateMachineFunction(Function &F); |
151 | |
152 | /// \brief Returns the MachineFunction associated to IR function \p F if there |
153 | /// is one, otherwise nullptr. |
154 | MachineFunction *getMachineFunction(const Function &F) const; |
155 | |
156 | /// Delete the MachineFunction \p MF and reset the link in the IR Function to |
157 | /// Machine Function map. |
158 | void deleteMachineFunctionFor(Function &F); |
159 | |
160 | /// Add an externally created MachineFunction \p MF for \p F. |
161 | void insertFunction(const Function &F, std::unique_ptr<MachineFunction> &&MF); |
162 | |
163 | /// Keep track of various per-module pieces of information for backends |
164 | /// that would like to do so. |
165 | template<typename Ty> |
166 | Ty &getObjFileInfo() { |
167 | if (ObjFileMMI == nullptr) |
168 | ObjFileMMI = new Ty(*this); |
169 | return *static_cast<Ty*>(ObjFileMMI); |
170 | } |
171 | |
172 | template<typename Ty> |
173 | const Ty &getObjFileInfo() const { |
174 | return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>(); |
175 | } |
176 | |
177 | /// Returns true if valid debug info is present. |
178 | bool hasDebugInfo() const { return DbgInfoAvailable; } |
179 | |
180 | bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; } |
181 | |
182 | void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; } |
183 | |
184 | /// \name Exception Handling |
185 | /// \{ |
186 | |
187 | /// Set the call site currently being processed. |
188 | void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } |
189 | |
190 | /// Get the call site currently being processed, if any. return zero if |
191 | /// none. |
192 | unsigned getCurrentCallSite() { return CurCallSite; } |
193 | |
194 | /// \} |
195 | }; // End class MachineModuleInfo |
196 | |
197 | class MachineModuleInfoWrapperPass : public ImmutablePass { |
198 | MachineModuleInfo MMI; |
199 | |
200 | public: |
201 | static char ID; // Pass identification, replacement for typeid |
202 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr); |
203 | |
204 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM, |
205 | MCContext *ExtContext); |
206 | |
207 | // Initialization and Finalization |
208 | bool doInitialization(Module &) override; |
209 | bool doFinalization(Module &) override; |
210 | |
211 | MachineModuleInfo &getMMI() { return MMI; } |
212 | const MachineModuleInfo &getMMI() const { return MMI; } |
213 | }; |
214 | |
215 | /// An analysis that produces \c MachineModuleInfo for a module. |
216 | /// This does not produce its own MachineModuleInfo because we need a consistent |
217 | /// MachineModuleInfo to keep ownership of MachineFunctions regardless of |
218 | /// analysis invalidation/clearing. So something outside the analysis |
219 | /// infrastructure must own the MachineModuleInfo. |
220 | class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> { |
221 | friend AnalysisInfoMixin<MachineModuleAnalysis>; |
222 | static AnalysisKey Key; |
223 | |
224 | MachineModuleInfo &MMI; |
225 | |
226 | public: |
227 | class Result { |
228 | MachineModuleInfo &MMI; |
229 | Result(MachineModuleInfo &MMI) : MMI(MMI) {} |
230 | friend class MachineModuleAnalysis; |
231 | |
232 | public: |
233 | MachineModuleInfo &getMMI() { return MMI; } |
234 | |
235 | // MMI owes MCContext. It should never be invalidated. |
236 | bool invalidate(Module &, const PreservedAnalyses &, |
237 | ModuleAnalysisManager::Invalidator &) { |
238 | return false; |
239 | } |
240 | }; |
241 | |
242 | MachineModuleAnalysis(MachineModuleInfo &MMI) : MMI(MMI) {} |
243 | |
244 | /// Run the analysis pass and produce machine module information. |
245 | Result run(Module &M, ModuleAnalysisManager &); |
246 | }; |
247 | |
248 | } // end namespace llvm |
249 | |
250 | #endif // LLVM_CODEGEN_MACHINEMODULEINFO_H |
251 | |