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