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