• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   /// Maps IR Functions to their corresponding MachineFunctions.
103   DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
104   /// Next unique number available for a MachineFunction.
105   unsigned NextFnNum = 0;
106   const Function *LastRequest = nullptr; ///< Used for shortcut/cache.
107   MachineFunction *LastResult = nullptr; ///< Used for shortcut/cache.
108 
109   MachineModuleInfo &operator=(MachineModuleInfo &&MMII) = delete;
110 
111 public:
112   explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr);
113 
114   explicit MachineModuleInfo(const LLVMTargetMachine *TM,
115                              MCContext *ExtContext);
116 
117   MachineModuleInfo(MachineModuleInfo &&MMII);
118 
119   ~MachineModuleInfo();
120 
121   void initialize();
122   void finalize();
123 
getTarget()124   const LLVMTargetMachine &getTarget() const { return TM; }
125 
getContext()126   const MCContext &getContext() const {
127     return ExternalContext ? *ExternalContext : Context;
128   }
getContext()129   MCContext &getContext() {
130     return ExternalContext ? *ExternalContext : Context;
131   }
132 
getModule()133   const Module *getModule() const { return TheModule; }
134 
135   /// Returns the MachineFunction constructed for the IR function \p F.
136   /// Creates a new MachineFunction if none exists yet.
137   /// NOTE: New pass manager clients shall not use this method to get
138   /// the `MachineFunction`, use `MachineFunctionAnalysis` instead.
139   MachineFunction &getOrCreateMachineFunction(Function &F);
140 
141   /// \brief Returns the MachineFunction associated to IR function \p F if there
142   /// is one, otherwise nullptr.
143   /// NOTE: New pass manager clients shall not use this method to get
144   /// the `MachineFunction`, use `MachineFunctionAnalysis` instead.
145   MachineFunction *getMachineFunction(const Function &F) const;
146 
147   /// Delete the MachineFunction \p MF and reset the link in the IR Function to
148   /// Machine Function map.
149   void deleteMachineFunctionFor(Function &F);
150 
151   /// Add an externally created MachineFunction \p MF for \p F.
152   void insertFunction(const Function &F, std::unique_ptr<MachineFunction> &&MF);
153 
154   /// Keep track of various per-module pieces of information for backends
155   /// that would like to do so.
156   template<typename Ty>
getObjFileInfo()157   Ty &getObjFileInfo() {
158     if (ObjFileMMI == nullptr)
159       ObjFileMMI = new Ty(*this);
160     return *static_cast<Ty*>(ObjFileMMI);
161   }
162 
163   template<typename Ty>
getObjFileInfo()164   const Ty &getObjFileInfo() const {
165     return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
166   }
167 
168   /// \}
169 }; // End class MachineModuleInfo
170 
171 class MachineModuleInfoWrapperPass : public ImmutablePass {
172   MachineModuleInfo MMI;
173 
174 public:
175   static char ID; // Pass identification, replacement for typeid
176   explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr);
177 
178   explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM,
179                                         MCContext *ExtContext);
180 
181   // Initialization and Finalization
182   bool doInitialization(Module &) override;
183   bool doFinalization(Module &) override;
184 
getMMI()185   MachineModuleInfo &getMMI() { return MMI; }
getMMI()186   const MachineModuleInfo &getMMI() const { return MMI; }
187 };
188 
189 /// An analysis that produces \c MachineModuleInfo for a module.
190 /// This does not produce its own MachineModuleInfo because we need a consistent
191 /// MachineModuleInfo to keep ownership of MachineFunctions regardless of
192 /// analysis invalidation/clearing. So something outside the analysis
193 /// infrastructure must own the MachineModuleInfo.
194 class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> {
195   friend AnalysisInfoMixin<MachineModuleAnalysis>;
196   static AnalysisKey Key;
197 
198   MachineModuleInfo &MMI;
199 
200 public:
201   class Result {
202     MachineModuleInfo &MMI;
Result(MachineModuleInfo & MMI)203     Result(MachineModuleInfo &MMI) : MMI(MMI) {}
204     friend class MachineModuleAnalysis;
205 
206   public:
getMMI()207     MachineModuleInfo &getMMI() { return MMI; }
208 
209     // MMI owes MCContext. It should never be invalidated.
invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)210     bool invalidate(Module &, const PreservedAnalyses &,
211                     ModuleAnalysisManager::Invalidator &) {
212       return false;
213     }
214   };
215 
MachineModuleAnalysis(MachineModuleInfo & MMI)216   MachineModuleAnalysis(MachineModuleInfo &MMI) : MMI(MMI) {}
217 
218   /// Run the analysis pass and produce machine module information.
219   Result run(Module &M, ModuleAnalysisManager &);
220 };
221 
222 } // end namespace llvm
223 
224 #endif // LLVM_CODEGEN_MACHINEMODULEINFO_H
225