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