xref: /llvm-project/llvm/lib/CodeGen/MachineModuleInfo.cpp (revision 7c2db66632486c7c460779843d60477a06ded462)
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 void MachineModuleInfo::insertFunction(const Function &F,
145                                        std::unique_ptr<MachineFunction> &&MF) {
146   auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF)));
147   assert(I.second && "machine function already mapped");
148   (void)I;
149 }
150 
151 namespace {
152 
153 /// This pass frees the MachineFunction object associated with a Function.
154 class FreeMachineFunction : public FunctionPass {
155 public:
156   static char ID;
157 
158   FreeMachineFunction() : FunctionPass(ID) {}
159 
160   void getAnalysisUsage(AnalysisUsage &AU) const override {
161     AU.addRequired<MachineModuleInfoWrapperPass>();
162     AU.addPreserved<MachineModuleInfoWrapperPass>();
163   }
164 
165   bool runOnFunction(Function &F) override {
166     MachineModuleInfo &MMI =
167         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
168     MMI.deleteMachineFunctionFor(F);
169     return true;
170   }
171 
172   StringRef getPassName() const override {
173     return "Free MachineFunction";
174   }
175 };
176 
177 } // end anonymous namespace
178 
179 char FreeMachineFunction::ID;
180 
181 FunctionPass *llvm::createFreeMachineFunctionPass() {
182   return new FreeMachineFunction();
183 }
184 
185 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
186     const LLVMTargetMachine *TM)
187     : ImmutablePass(ID), MMI(TM) {
188   initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
189 }
190 
191 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
192     const LLVMTargetMachine *TM, MCContext *ExtContext)
193     : ImmutablePass(ID), MMI(TM, ExtContext) {
194   initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
195 }
196 
197 // Handle the Pass registration stuff necessary to use DataLayout's.
198 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
199                 "Machine Module Information", false, false)
200 char MachineModuleInfoWrapperPass::ID = 0;
201 
202 static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
203                              std::vector<const MDNode *> &LocInfos) {
204   // Look up a LocInfo for the buffer this diagnostic is coming from.
205   unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
206   const MDNode *LocInfo = nullptr;
207   if (BufNum > 0 && BufNum <= LocInfos.size())
208     LocInfo = LocInfos[BufNum - 1];
209 
210   // If the inline asm had metadata associated with it, pull out a location
211   // cookie corresponding to which line the error occurred on.
212   unsigned LocCookie = 0;
213   if (LocInfo) {
214     unsigned ErrorLine = SMD.getLineNo() - 1;
215     if (ErrorLine >= LocInfo->getNumOperands())
216       ErrorLine = 0;
217 
218     if (LocInfo->getNumOperands() != 0)
219       if (const ConstantInt *CI =
220               mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
221         LocCookie = CI->getZExtValue();
222   }
223 
224   return LocCookie;
225 }
226 
227 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
228   MMI.initialize();
229   MMI.TheModule = &M;
230   // FIXME: Do this for new pass manager.
231   LLVMContext &Ctx = M.getContext();
232   MMI.getContext().setDiagnosticHandler(
233       [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
234                  const SourceMgr &SrcMgr,
235                  std::vector<const MDNode *> &LocInfos) {
236         unsigned LocCookie = 0;
237         if (IsInlineAsm)
238           LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
239         Ctx.diagnose(
240             DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
241       });
242   MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
243                          !M.debug_compile_units().empty();
244   return false;
245 }
246 
247 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
248   MMI.finalize();
249   return false;
250 }
251 
252 AnalysisKey MachineModuleAnalysis::Key;
253 
254 MachineModuleInfo MachineModuleAnalysis::run(Module &M,
255                                              ModuleAnalysisManager &) {
256   MachineModuleInfo MMI(TM);
257   MMI.TheModule = &M;
258   MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
259                          !M.debug_compile_units().empty();
260   return MMI;
261 }
262