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