xref: /llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp (revision 69e75ae695d9ef1360a2a1fbefd6e0e0456c3f7b)
1 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- 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 #include "llvm/CodeGen/MachineModuleInfo.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/CodeGen/MachineFunction.h"
13 #include "llvm/CodeGen/Passes.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Target/TargetLoweringObjectFile.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <memory>
28 #include <utility>
29 #include <vector>
30 
31 using namespace llvm;
32 using namespace llvm::dwarf;
33 
34 static cl::opt<bool>
35     DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
36                              cl::desc("Disable debug info printing"));
37 
38 // Out of line virtual method.
39 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
40 
41 void MachineModuleInfo::initialize() {
42   ObjFileMMI = nullptr;
43   CurCallSite = 0;
44   NextFnNum = 0;
45   UsesMSVCFloatingPoint = false;
46   DbgInfoAvailable = false;
47 }
48 
49 void MachineModuleInfo::finalize() {
50   Personalities.clear();
51 
52   Context.reset();
53   // We don't clear the ExternalContext.
54 
55   delete ObjFileMMI;
56   ObjFileMMI = nullptr;
57 }
58 
59 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
60     : TM(std::move(MMI.TM)),
61       Context(MMI.TM.getTargetTriple(), MMI.TM.getMCAsmInfo(),
62               MMI.TM.getMCRegisterInfo(), MMI.TM.getMCSubtargetInfo(), nullptr,
63               &MMI.TM.Options.MCOptions, false),
64       MachineFunctions(std::move(MMI.MachineFunctions)) {
65   Context.setObjectFileInfo(MMI.TM.getObjFileLowering());
66   ObjFileMMI = MMI.ObjFileMMI;
67   CurCallSite = MMI.CurCallSite;
68   ExternalContext = MMI.ExternalContext;
69   TheModule = MMI.TheModule;
70 }
71 
72 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
73     : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
74                        TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
75                        nullptr, &TM->Options.MCOptions, false) {
76   Context.setObjectFileInfo(TM->getObjFileLowering());
77   initialize();
78 }
79 
80 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM,
81                                      MCContext *ExtContext)
82     : TM(*TM), Context(TM->getTargetTriple(), TM->getMCAsmInfo(),
83                        TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(),
84                        nullptr, &TM->Options.MCOptions, false),
85       ExternalContext(ExtContext) {
86   Context.setObjectFileInfo(TM->getObjFileLowering());
87   initialize();
88 }
89 
90 MachineModuleInfo::~MachineModuleInfo() { finalize(); }
91 
92 /// \name Exception Handling
93 /// \{
94 
95 void MachineModuleInfo::addPersonality(const Function *Personality) {
96   if (!llvm::is_contained(Personalities, Personality))
97     Personalities.push_back(Personality);
98 }
99 
100 /// \}
101 
102 MachineFunction *
103 MachineModuleInfo::getMachineFunction(const Function &F) const {
104   auto I = MachineFunctions.find(&F);
105   return I != MachineFunctions.end() ? I->second.get() : nullptr;
106 }
107 
108 MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) {
109   // Shortcut for the common case where a sequence of MachineFunctionPasses
110   // all query for the same Function.
111   if (LastRequest == &F)
112     return *LastResult;
113 
114   auto I = MachineFunctions.insert(
115       std::make_pair(&F, std::unique_ptr<MachineFunction>()));
116   MachineFunction *MF;
117   if (I.second) {
118     // No pre-existing machine function, create a new one.
119     const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F);
120     MF = new MachineFunction(F, TM, STI, NextFnNum++, *this);
121     MF->initTargetMachineFunctionInfo(STI);
122     // Update the set entry.
123     I.first->second.reset(MF);
124   } else {
125     MF = I.first->second.get();
126   }
127 
128   LastRequest = &F;
129   LastResult = MF;
130   return *MF;
131 }
132 
133 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
134   MachineFunctions.erase(&F);
135   LastRequest = nullptr;
136   LastResult = nullptr;
137 }
138 
139 void MachineModuleInfo::insertFunction(const Function &F,
140                                        std::unique_ptr<MachineFunction> &&MF) {
141   auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF)));
142   assert(I.second && "machine function already mapped");
143   (void)I;
144 }
145 
146 namespace {
147 
148 /// This pass frees the MachineFunction object associated with a Function.
149 class FreeMachineFunction : public FunctionPass {
150 public:
151   static char ID;
152 
153   FreeMachineFunction() : FunctionPass(ID) {}
154 
155   void getAnalysisUsage(AnalysisUsage &AU) const override {
156     AU.addRequired<MachineModuleInfoWrapperPass>();
157     AU.addPreserved<MachineModuleInfoWrapperPass>();
158   }
159 
160   bool runOnFunction(Function &F) override {
161     MachineModuleInfo &MMI =
162         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
163     MMI.deleteMachineFunctionFor(F);
164     return true;
165   }
166 
167   StringRef getPassName() const override {
168     return "Free MachineFunction";
169   }
170 };
171 
172 } // end anonymous namespace
173 
174 char FreeMachineFunction::ID;
175 
176 FunctionPass *llvm::createFreeMachineFunctionPass() {
177   return new FreeMachineFunction();
178 }
179 
180 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
181     const LLVMTargetMachine *TM)
182     : ImmutablePass(ID), MMI(TM) {
183   initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
184 }
185 
186 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
187     const LLVMTargetMachine *TM, MCContext *ExtContext)
188     : ImmutablePass(ID), MMI(TM, ExtContext) {
189   initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
190 }
191 
192 // Handle the Pass registration stuff necessary to use DataLayout's.
193 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
194                 "Machine Module Information", false, false)
195 char MachineModuleInfoWrapperPass::ID = 0;
196 
197 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
198                              std::vector<const MDNode *> &LocInfos) {
199   // Look up a LocInfo for the buffer this diagnostic is coming from.
200   unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
201   const MDNode *LocInfo = nullptr;
202   if (BufNum > 0 && BufNum <= LocInfos.size())
203     LocInfo = LocInfos[BufNum - 1];
204 
205   // If the inline asm had metadata associated with it, pull out a location
206   // cookie corresponding to which line the error occurred on.
207   unsigned LocCookie = 0;
208   if (LocInfo) {
209     unsigned ErrorLine = SMD.getLineNo() - 1;
210     if (ErrorLine >= LocInfo->getNumOperands())
211       ErrorLine = 0;
212 
213     if (LocInfo->getNumOperands() != 0)
214       if (const ConstantInt *CI =
215               mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
216         LocCookie = CI->getZExtValue();
217   }
218 
219   return LocCookie;
220 }
221 
222 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
223   MMI.initialize();
224   MMI.TheModule = &M;
225   // FIXME: Do this for new pass manager.
226   LLVMContext &Ctx = M.getContext();
227   MMI.getContext().setDiagnosticHandler(
228       [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
229                  const SourceMgr &SrcMgr,
230                  std::vector<const MDNode *> &LocInfos) {
231         unsigned LocCookie = 0;
232         if (IsInlineAsm)
233           LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
234         Ctx.diagnose(
235             DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
236       });
237   MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
238                          !M.debug_compile_units().empty();
239   return false;
240 }
241 
242 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
243   MMI.finalize();
244   return false;
245 }
246 
247 AnalysisKey MachineModuleAnalysis::Key;
248 
249 MachineModuleInfo MachineModuleAnalysis::run(Module &M,
250                                              ModuleAnalysisManager &) {
251   MachineModuleInfo MMI(TM);
252   MMI.TheModule = &M;
253   MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
254                          !M.debug_compile_units().empty();
255   return MMI;
256 }
257