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