xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
getTarget()145   const LLVMTargetMachine &getTarget() const { return TM; }
146 
getContext()147   const MCContext &getContext() const {
148     return ExternalContext ? *ExternalContext : Context;
149   }
getContext()150   MCContext &getContext() {
151     return ExternalContext ? *ExternalContext : Context;
152   }
153 
getModule()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>
getObjFileInfo()178   Ty &getObjFileInfo() {
179     if (ObjFileMMI == nullptr)
180       ObjFileMMI = new Ty(*this);
181     return *static_cast<Ty*>(ObjFileMMI);
182   }
183 
184   template<typename Ty>
getObjFileInfo()185   const Ty &getObjFileInfo() const {
186     return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
187   }
188 
189   /// Returns true if valid debug info is present.
hasDebugInfo()190   bool hasDebugInfo() const { return DbgInfoAvailable; }
191 
usesMSVCFloatingPoint()192   bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; }
193 
setUsesMSVCFloatingPoint(bool b)194   void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }
195 
196   /// \name Exception Handling
197   /// \{
198 
199   /// Set the call site currently being processed.
setCurrentCallSite(unsigned Site)200   void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
201 
202   /// Get the call site currently being processed, if any.  return zero if
203   /// none.
getCurrentCallSite()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 
getMMI()223   MachineModuleInfo &getMMI() { return MMI; }
getMMI()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;
Result(MachineModuleInfo & MMI)241     Result(MachineModuleInfo &MMI) : MMI(MMI) {}
242     friend class MachineModuleAnalysis;
243 
244   public:
getMMI()245     MachineModuleInfo &getMMI() { return MMI; }
246 
247     // MMI owes MCContext. It should never be invalidated.
invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)248     bool invalidate(Module &, const PreservedAnalyses &,
249                     ModuleAnalysisManager::Invalidator &) {
250       return false;
251     }
252   };
253 
MachineModuleAnalysis(MachineModuleInfo & MMI)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