blob: fa900affb214ea9e938bbfc72d119cc14375bacf [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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/ArrayRef.h"
34#include "llvm/ADT/DenseMap.h"
35#include "llvm/ADT/PointerIntPair.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020036#include "llvm/IR/PassManager.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010037#include "llvm/MC/MCContext.h"
38#include "llvm/MC/MCSymbol.h"
39#include "llvm/Pass.h"
40#include <memory>
41#include <utility>
42#include <vector>
43
44namespace llvm {
45
46class BasicBlock;
47class CallInst;
48class Function;
Andrew Walbran16937d02019-10-22 13:54:20 +010049class LLVMTargetMachine;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010050class MMIAddrLabelMap;
Andrew Walbran16937d02019-10-22 13:54:20 +010051class MachineFunction;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010052class Module;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010053
54//===----------------------------------------------------------------------===//
55/// This class can be derived from and used by targets to hold private
56/// target-specific information for each Module. Objects of type are
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020057/// accessed/created with MachineModuleInfo::getObjFileInfo and destroyed when
58/// the MachineModuleInfo is destroyed.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010059///
60class MachineModuleInfoImpl {
61public:
62 using StubValueTy = PointerIntPair<MCSymbol *, 1, bool>;
63 using SymbolListTy = std::vector<std::pair<MCSymbol *, StubValueTy>>;
64
65 virtual ~MachineModuleInfoImpl();
66
67protected:
68 /// Return the entries from a DenseMap in a deterministic sorted orer.
69 /// Clears the map.
70 static SymbolListTy getSortedStubs(DenseMap<MCSymbol*, StubValueTy>&);
71};
72
73//===----------------------------------------------------------------------===//
74/// This class contains meta information specific to a module. Queries can be
75/// made by different debugging and exception handling schemes and reformated
76/// for specific use.
77///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020078class MachineModuleInfo {
79 friend class MachineModuleInfoWrapperPass;
80 friend class MachineModuleAnalysis;
81
Andrew Walbran16937d02019-10-22 13:54:20 +010082 const LLVMTargetMachine &TM;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083
84 /// This is the MCContext used for the entire code generator.
85 MCContext Context;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020086 // This is an external context, that if assigned, will be used instead of the
87 // internal context.
88 MCContext *ExternalContext = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089
90 /// This is the LLVM Module being worked on.
91 const Module *TheModule;
92
93 /// This is the object-file-format-specific implementation of
94 /// MachineModuleInfoImpl, which lets targets accumulate whatever info they
95 /// want.
96 MachineModuleInfoImpl *ObjFileMMI;
97
98 /// \name Exception Handling
99 /// \{
100
101 /// Vector of all personality functions ever seen. Used to emit common EH
102 /// frames.
103 std::vector<const Function *> Personalities;
104
105 /// The current call site index being processed, if any. 0 if none.
106 unsigned CurCallSite;
107
108 /// \}
109
110 /// This map keeps track of which symbol is being used for the specified
111 /// basic block's address of label.
112 MMIAddrLabelMap *AddrLabelSymbols;
113
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100114 // TODO: Ideally, what we'd like is to have a switch that allows emitting
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100115 // synchronous (precise at call-sites only) CFA into .eh_frame. However,
116 // even under this switch, we'd like .debug_frame to be precise when using
117 // -g. At this moment, there's no way to specify that some CFI directives
118 // go into .eh_frame only, while others go into .debug_frame only.
119
120 /// True if debugging information is available in this module.
121 bool DbgInfoAvailable;
122
Andrew Walbran16937d02019-10-22 13:54:20 +0100123 /// True if this module is being built for windows/msvc, and uses floating
124 /// point. This is used to emit an undefined reference to _fltused.
125 bool UsesMSVCFloatingPoint;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126
127 /// True if the module calls the __morestack function indirectly, as is
128 /// required under the large code model on x86. This is used to emit
129 /// a definition of a symbol, __morestack_addr, containing the address. See
130 /// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
131 bool UsesMorestackAddr;
132
133 /// True if the module contains split-stack functions. This is used to
134 /// emit .note.GNU-split-stack section as required by the linker for
135 /// special handling split-stack function calling no-split-stack function.
136 bool HasSplitStack;
137
138 /// True if the module contains no-split-stack functions. This is used to
139 /// emit .note.GNU-no-split-stack section when it also contains split-stack
140 /// functions.
141 bool HasNosplitStack;
142
143 /// Maps IR Functions to their corresponding MachineFunctions.
144 DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
145 /// Next unique number available for a MachineFunction.
146 unsigned NextFnNum = 0;
147 const Function *LastRequest = nullptr; ///< Used for shortcut/cache.
148 MachineFunction *LastResult = nullptr; ///< Used for shortcut/cache.
149
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200150 MachineModuleInfo &operator=(MachineModuleInfo &&MMII) = delete;
151
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152public:
Andrew Walbran16937d02019-10-22 13:54:20 +0100153 explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100154
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200155 explicit MachineModuleInfo(const LLVMTargetMachine *TM,
156 MCContext *ExtContext);
157
158 MachineModuleInfo(MachineModuleInfo &&MMII);
159
160 ~MachineModuleInfo();
161
162 void initialize();
163 void finalize();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100164
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100165 const LLVMTargetMachine &getTarget() const { return TM; }
166
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200167 const MCContext &getContext() const {
168 return ExternalContext ? *ExternalContext : Context;
169 }
170 MCContext &getContext() {
171 return ExternalContext ? *ExternalContext : Context;
172 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100173
174 const Module *getModule() const { return TheModule; }
175
176 /// Returns the MachineFunction constructed for the IR function \p F.
177 /// Creates a new MachineFunction if none exists yet.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200178 MachineFunction &getOrCreateMachineFunction(Function &F);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100179
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200180 /// \brief Returns the MachineFunction associated to IR function \p F if there
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100181 /// is one, otherwise nullptr.
182 MachineFunction *getMachineFunction(const Function &F) const;
183
184 /// Delete the MachineFunction \p MF and reset the link in the IR Function to
185 /// Machine Function map.
186 void deleteMachineFunctionFor(Function &F);
187
188 /// Keep track of various per-function pieces of information for backends
189 /// that would like to do so.
190 template<typename Ty>
191 Ty &getObjFileInfo() {
192 if (ObjFileMMI == nullptr)
193 ObjFileMMI = new Ty(*this);
194 return *static_cast<Ty*>(ObjFileMMI);
195 }
196
197 template<typename Ty>
198 const Ty &getObjFileInfo() const {
199 return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
200 }
201
202 /// Returns true if valid debug info is present.
203 bool hasDebugInfo() const { return DbgInfoAvailable; }
204 void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
205
Andrew Walbran16937d02019-10-22 13:54:20 +0100206 bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100207
Andrew Walbran16937d02019-10-22 13:54:20 +0100208 void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100209
210 bool usesMorestackAddr() const {
211 return UsesMorestackAddr;
212 }
213
214 void setUsesMorestackAddr(bool b) {
215 UsesMorestackAddr = b;
216 }
217
218 bool hasSplitStack() const {
219 return HasSplitStack;
220 }
221
222 void setHasSplitStack(bool b) {
223 HasSplitStack = b;
224 }
225
226 bool hasNosplitStack() const {
227 return HasNosplitStack;
228 }
229
230 void setHasNosplitStack(bool b) {
231 HasNosplitStack = b;
232 }
233
234 /// Return the symbol to be used for the specified basic block when its
235 /// address is taken. This cannot be its normal LBB label because the block
236 /// may be accessed outside its containing function.
237 MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) {
238 return getAddrLabelSymbolToEmit(BB).front();
239 }
240
241 /// Return the symbol to be used for the specified basic block when its
242 /// address is taken. If other blocks were RAUW'd to this one, we may have
243 /// to emit them as well, return the whole set.
244 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB);
245
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100246 /// \name Exception Handling
247 /// \{
248
249 /// Set the call site currently being processed.
250 void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
251
252 /// Get the call site currently being processed, if any. return zero if
253 /// none.
254 unsigned getCurrentCallSite() { return CurCallSite; }
255
256 /// Provide the personality function for the exception information.
257 void addPersonality(const Function *Personality);
258
259 /// Return array of personality functions ever seen.
260 const std::vector<const Function *>& getPersonalities() const {
261 return Personalities;
262 }
263 /// \}
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200264
265 // MMI owes MCContext. It should never be invalidated.
266 bool invalidate(Module &, const PreservedAnalyses &,
267 ModuleAnalysisManager::Invalidator &) {
268 return false;
269 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100270}; // End class MachineModuleInfo
271
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200272class MachineModuleInfoWrapperPass : public ImmutablePass {
273 MachineModuleInfo MMI;
274
275public:
276 static char ID; // Pass identification, replacement for typeid
277 explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr);
278
279 explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM,
280 MCContext *ExtContext);
281
282 // Initialization and Finalization
283 bool doInitialization(Module &) override;
284 bool doFinalization(Module &) override;
285
286 MachineModuleInfo &getMMI() { return MMI; }
287 const MachineModuleInfo &getMMI() const { return MMI; }
288};
289
290/// An analysis that produces \c MachineInfo for a module.
291class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> {
292 friend AnalysisInfoMixin<MachineModuleAnalysis>;
293 static AnalysisKey Key;
294
295 const LLVMTargetMachine *TM;
296
297public:
298 /// Provide the result type for this analysis pass.
299 using Result = MachineModuleInfo;
300
301 MachineModuleAnalysis(const LLVMTargetMachine *TM) : TM(TM) {}
302
303 /// Run the analysis pass and produce machine module information.
304 MachineModuleInfo run(Module &M, ModuleAnalysisManager &);
305};
306
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100307} // end namespace llvm
308
309#endif // LLVM_CODEGEN_MACHINEMODULEINFO_H