1 //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
22 using namespace llvm::dwarf
;
24 // Out of line virtual method.
25 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
27 void MachineModuleInfo::initialize() {
32 void MachineModuleInfo::finalize() {
34 // We don't clear the ExternalContext.
40 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo
&&MMI
)
41 : TM(std::move(MMI
.TM
)),
42 Context(TM
.getTargetTriple(), TM
.getMCAsmInfo(), TM
.getMCRegisterInfo(),
43 TM
.getMCSubtargetInfo(), nullptr, &TM
.Options
.MCOptions
, false),
44 MachineFunctions(std::move(MMI
.MachineFunctions
)) {
45 Context
.setObjectFileInfo(TM
.getObjFileLowering());
46 ObjFileMMI
= MMI
.ObjFileMMI
;
47 ExternalContext
= MMI
.ExternalContext
;
48 TheModule
= MMI
.TheModule
;
51 MachineModuleInfo::MachineModuleInfo(const TargetMachine
*TM
)
52 : TM(*TM
), Context(TM
->getTargetTriple(), TM
->getMCAsmInfo(),
53 TM
->getMCRegisterInfo(), TM
->getMCSubtargetInfo(),
54 nullptr, &TM
->Options
.MCOptions
, false) {
55 Context
.setObjectFileInfo(TM
->getObjFileLowering());
59 MachineModuleInfo::MachineModuleInfo(const TargetMachine
*TM
,
60 MCContext
*ExtContext
)
61 : TM(*TM
), Context(TM
->getTargetTriple(), TM
->getMCAsmInfo(),
62 TM
->getMCRegisterInfo(), TM
->getMCSubtargetInfo(),
63 nullptr, &TM
->Options
.MCOptions
, false),
64 ExternalContext(ExtContext
) {
65 Context
.setObjectFileInfo(TM
->getObjFileLowering());
69 MachineModuleInfo::~MachineModuleInfo() { finalize(); }
72 MachineModuleInfo::getMachineFunction(const Function
&F
) const {
73 auto I
= MachineFunctions
.find(&F
);
74 return I
!= MachineFunctions
.end() ? I
->second
.get() : nullptr;
77 MachineFunction
&MachineModuleInfo::getOrCreateMachineFunction(Function
&F
) {
78 // Shortcut for the common case where a sequence of MachineFunctionPasses
79 // all query for the same Function.
80 if (LastRequest
== &F
)
83 auto I
= MachineFunctions
.insert(
84 std::make_pair(&F
, std::unique_ptr
<MachineFunction
>()));
87 // No pre-existing machine function, create a new one.
88 const TargetSubtargetInfo
&STI
= *TM
.getSubtargetImpl(F
);
89 MF
= new MachineFunction(F
, TM
, STI
, getContext(), NextFnNum
++);
90 MF
->initTargetMachineFunctionInfo(STI
);
92 // MRI callback for target specific initializations.
93 TM
.registerMachineRegisterInfoCallback(*MF
);
95 // Update the set entry.
96 I
.first
->second
.reset(MF
);
98 MF
= I
.first
->second
.get();
106 void MachineModuleInfo::deleteMachineFunctionFor(Function
&F
) {
107 MachineFunctions
.erase(&F
);
108 LastRequest
= nullptr;
109 LastResult
= nullptr;
112 void MachineModuleInfo::insertFunction(const Function
&F
,
113 std::unique_ptr
<MachineFunction
> &&MF
) {
114 auto I
= MachineFunctions
.insert(std::make_pair(&F
, std::move(MF
)));
115 assert(I
.second
&& "machine function already mapped");
121 /// This pass frees the MachineFunction object associated with a Function.
122 class FreeMachineFunction
: public FunctionPass
{
126 FreeMachineFunction() : FunctionPass(ID
) {}
128 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
129 AU
.addRequired
<MachineModuleInfoWrapperPass
>();
130 AU
.addPreserved
<MachineModuleInfoWrapperPass
>();
133 bool runOnFunction(Function
&F
) override
{
134 MachineModuleInfo
&MMI
=
135 getAnalysis
<MachineModuleInfoWrapperPass
>().getMMI();
136 MMI
.deleteMachineFunctionFor(F
);
140 StringRef
getPassName() const override
{
141 return "Free MachineFunction";
145 } // end anonymous namespace
147 char FreeMachineFunction::ID
;
149 FunctionPass
*llvm::createFreeMachineFunctionPass() {
150 return new FreeMachineFunction();
153 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
154 const TargetMachine
*TM
)
155 : ImmutablePass(ID
), MMI(TM
) {
156 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
159 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
160 const TargetMachine
*TM
, MCContext
*ExtContext
)
161 : ImmutablePass(ID
), MMI(TM
, ExtContext
) {
162 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
165 // Handle the Pass registration stuff necessary to use DataLayout's.
166 INITIALIZE_PASS(MachineModuleInfoWrapperPass
, "machinemoduleinfo",
167 "Machine Module Information", false, false)
168 char MachineModuleInfoWrapperPass::ID
= 0;
170 static uint64_t getLocCookie(const SMDiagnostic
&SMD
, const SourceMgr
&SrcMgr
,
171 std::vector
<const MDNode
*> &LocInfos
) {
172 // Look up a LocInfo for the buffer this diagnostic is coming from.
173 unsigned BufNum
= SrcMgr
.FindBufferContainingLoc(SMD
.getLoc());
174 const MDNode
*LocInfo
= nullptr;
175 if (BufNum
> 0 && BufNum
<= LocInfos
.size())
176 LocInfo
= LocInfos
[BufNum
- 1];
178 // If the inline asm had metadata associated with it, pull out a location
179 // cookie corresponding to which line the error occurred on.
180 uint64_t LocCookie
= 0;
182 unsigned ErrorLine
= SMD
.getLineNo() - 1;
183 if (ErrorLine
>= LocInfo
->getNumOperands())
186 if (LocInfo
->getNumOperands() != 0)
187 if (const ConstantInt
*CI
=
188 mdconst::dyn_extract
<ConstantInt
>(LocInfo
->getOperand(ErrorLine
)))
189 LocCookie
= CI
->getZExtValue();
195 bool MachineModuleInfoWrapperPass::doInitialization(Module
&M
) {
198 LLVMContext
&Ctx
= M
.getContext();
199 MMI
.getContext().setDiagnosticHandler(
200 [&Ctx
, &M
](const SMDiagnostic
&SMD
, bool IsInlineAsm
,
201 const SourceMgr
&SrcMgr
,
202 std::vector
<const MDNode
*> &LocInfos
) {
203 uint64_t LocCookie
= 0;
205 LocCookie
= getLocCookie(SMD
, SrcMgr
, LocInfos
);
207 DiagnosticInfoSrcMgr(SMD
, M
.getName(), IsInlineAsm
, LocCookie
));
212 bool MachineModuleInfoWrapperPass::doFinalization(Module
&M
) {
217 AnalysisKey
MachineModuleAnalysis::Key
;
219 MachineModuleAnalysis::Result
220 MachineModuleAnalysis::run(Module
&M
, ModuleAnalysisManager
&) {
222 LLVMContext
&Ctx
= M
.getContext();
223 MMI
.getContext().setDiagnosticHandler(
224 [&Ctx
, &M
](const SMDiagnostic
&SMD
, bool IsInlineAsm
,
225 const SourceMgr
&SrcMgr
,
226 std::vector
<const MDNode
*> &LocInfos
) {
227 unsigned LocCookie
= 0;
229 LocCookie
= getLocCookie(SMD
, SrcMgr
, LocInfos
);
231 DiagnosticInfoSrcMgr(SMD
, M
.getName(), IsInlineAsm
, LocCookie
));