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