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
initialize()41 void MachineModuleInfo::initialize() {
42 ObjFileMMI = nullptr;
43 CurCallSite = 0;
44 NextFnNum = 0;
45 UsesMSVCFloatingPoint = false;
46 DbgInfoAvailable = false;
47 }
48
finalize()49 void MachineModuleInfo::finalize() {
50 Context.reset();
51 // We don't clear the ExternalContext.
52
53 delete ObjFileMMI;
54 ObjFileMMI = nullptr;
55 }
56
MachineModuleInfo(MachineModuleInfo && MMI)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
MachineModuleInfo(const LLVMTargetMachine * TM)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
MachineModuleInfo(const LLVMTargetMachine * TM,MCContext * ExtContext)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
~MachineModuleInfo()87 MachineModuleInfo::~MachineModuleInfo() { finalize(); }
88
89 MachineFunction *
getMachineFunction(const Function & F) const90 MachineModuleInfo::getMachineFunction(const Function &F) const {
91 auto I = MachineFunctions.find(&F);
92 return I != MachineFunctions.end() ? I->second.get() : nullptr;
93 }
94
getOrCreateMachineFunction(Function & F)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
110 // MRI callback for target specific initializations.
111 TM.registerMachineRegisterInfoCallback(*MF);
112
113 // Update the set entry.
114 I.first->second.reset(MF);
115 } else {
116 MF = I.first->second.get();
117 }
118
119 LastRequest = &F;
120 LastResult = MF;
121 return *MF;
122 }
123
deleteMachineFunctionFor(Function & F)124 void MachineModuleInfo::deleteMachineFunctionFor(Function &F) {
125 MachineFunctions.erase(&F);
126 LastRequest = nullptr;
127 LastResult = nullptr;
128 }
129
insertFunction(const Function & F,std::unique_ptr<MachineFunction> && MF)130 void MachineModuleInfo::insertFunction(const Function &F,
131 std::unique_ptr<MachineFunction> &&MF) {
132 auto I = MachineFunctions.insert(std::make_pair(&F, std::move(MF)));
133 assert(I.second && "machine function already mapped");
134 (void)I;
135 }
136
137 namespace {
138
139 /// This pass frees the MachineFunction object associated with a Function.
140 class FreeMachineFunction : public FunctionPass {
141 public:
142 static char ID;
143
FreeMachineFunction()144 FreeMachineFunction() : FunctionPass(ID) {}
145
getAnalysisUsage(AnalysisUsage & AU) const146 void getAnalysisUsage(AnalysisUsage &AU) const override {
147 AU.addRequired<MachineModuleInfoWrapperPass>();
148 AU.addPreserved<MachineModuleInfoWrapperPass>();
149 }
150
runOnFunction(Function & F)151 bool runOnFunction(Function &F) override {
152 MachineModuleInfo &MMI =
153 getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
154 MMI.deleteMachineFunctionFor(F);
155 return true;
156 }
157
getPassName() const158 StringRef getPassName() const override {
159 return "Free MachineFunction";
160 }
161 };
162
163 } // end anonymous namespace
164
165 char FreeMachineFunction::ID;
166
createFreeMachineFunctionPass()167 FunctionPass *llvm::createFreeMachineFunctionPass() {
168 return new FreeMachineFunction();
169 }
170
MachineModuleInfoWrapperPass(const LLVMTargetMachine * TM)171 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
172 const LLVMTargetMachine *TM)
173 : ImmutablePass(ID), MMI(TM) {
174 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
175 }
176
MachineModuleInfoWrapperPass(const LLVMTargetMachine * TM,MCContext * ExtContext)177 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
178 const LLVMTargetMachine *TM, MCContext *ExtContext)
179 : ImmutablePass(ID), MMI(TM, ExtContext) {
180 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
181 }
182
183 // Handle the Pass registration stuff necessary to use DataLayout's.
184 INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
185 "Machine Module Information", false, false)
186 char MachineModuleInfoWrapperPass::ID = 0;
187
getLocCookie(const SMDiagnostic & SMD,const SourceMgr & SrcMgr,std::vector<const MDNode * > & LocInfos)188 static uint64_t getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
189 std::vector<const MDNode *> &LocInfos) {
190 // Look up a LocInfo for the buffer this diagnostic is coming from.
191 unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
192 const MDNode *LocInfo = nullptr;
193 if (BufNum > 0 && BufNum <= LocInfos.size())
194 LocInfo = LocInfos[BufNum - 1];
195
196 // If the inline asm had metadata associated with it, pull out a location
197 // cookie corresponding to which line the error occurred on.
198 uint64_t LocCookie = 0;
199 if (LocInfo) {
200 unsigned ErrorLine = SMD.getLineNo() - 1;
201 if (ErrorLine >= LocInfo->getNumOperands())
202 ErrorLine = 0;
203
204 if (LocInfo->getNumOperands() != 0)
205 if (const ConstantInt *CI =
206 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
207 LocCookie = CI->getZExtValue();
208 }
209
210 return LocCookie;
211 }
212
doInitialization(Module & M)213 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
214 MMI.initialize();
215 MMI.TheModule = &M;
216 LLVMContext &Ctx = M.getContext();
217 MMI.getContext().setDiagnosticHandler(
218 [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
219 const SourceMgr &SrcMgr,
220 std::vector<const MDNode *> &LocInfos) {
221 uint64_t LocCookie = 0;
222 if (IsInlineAsm)
223 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
224 Ctx.diagnose(
225 DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
226 });
227 MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
228 !M.debug_compile_units().empty();
229 return false;
230 }
231
doFinalization(Module & M)232 bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
233 MMI.finalize();
234 return false;
235 }
236
237 AnalysisKey MachineModuleAnalysis::Key;
238
239 MachineModuleAnalysis::Result
run(Module & M,ModuleAnalysisManager &)240 MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
241 MMI.TheModule = &M;
242 LLVMContext &Ctx = M.getContext();
243 MMI.getContext().setDiagnosticHandler(
244 [&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
245 const SourceMgr &SrcMgr,
246 std::vector<const MDNode *> &LocInfos) {
247 unsigned LocCookie = 0;
248 if (IsInlineAsm)
249 LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
250 Ctx.diagnose(
251 DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
252 });
253 MMI.DbgInfoAvailable =
254 !DisableDebugInfoPrinting && !M.debug_compile_units().empty();
255 return Result(MMI);
256 }
257