Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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; |
||
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; |
||
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; |
||
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; |
||
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 | |||
196 | // MMI owes MCContext. It should never be invalidated. |
||
197 | bool invalidate(Module &, const PreservedAnalyses &, |
||
198 | ModuleAnalysisManager::Invalidator &) { |
||
199 | return false; |
||
200 | } |
||
201 | }; // End class MachineModuleInfo |
||
202 | |||
203 | class MachineModuleInfoWrapperPass : public ImmutablePass { |
||
204 | MachineModuleInfo MMI; |
||
205 | |||
206 | public: |
||
207 | static char ID; // Pass identification, replacement for typeid |
||
208 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr); |
||
209 | |||
210 | explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM, |
||
211 | MCContext *ExtContext); |
||
212 | |||
213 | // Initialization and Finalization |
||
214 | bool doInitialization(Module &) override; |
||
215 | bool doFinalization(Module &) override; |
||
216 | |||
217 | MachineModuleInfo &getMMI() { return MMI; } |
||
218 | const MachineModuleInfo &getMMI() const { return MMI; } |
||
219 | }; |
||
220 | |||
221 | /// An analysis that produces \c MachineInfo for a module. |
||
222 | class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> { |
||
223 | friend AnalysisInfoMixin<MachineModuleAnalysis>; |
||
224 | static AnalysisKey Key; |
||
225 | |||
226 | const LLVMTargetMachine *TM; |
||
227 | |||
228 | public: |
||
229 | /// Provide the result type for this analysis pass. |
||
230 | using Result = MachineModuleInfo; |
||
231 | |||
232 | MachineModuleAnalysis(const LLVMTargetMachine *TM) : TM(TM) {} |
||
233 | |||
234 | /// Run the analysis pass and produce machine module information. |
||
235 | MachineModuleInfo run(Module &M, ModuleAnalysisManager &); |
||
236 | }; |
||
237 | |||
238 | } // end namespace llvm |
||
239 | |||
240 | #endif // LLVM_CODEGEN_MACHINEMODULEINFO_H |