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/ADT/ArrayRef.h"
11 #include "llvm/ADT/DenseMap.h"
12 #include "llvm/ADT/PostOrderIterator.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/TinyPtrVector.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/IR/BasicBlock.h"
18 #include "llvm/IR/DerivedTypes.h"
19 #include "llvm/IR/DiagnosticInfo.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/IR/ValueHandle.h"
25 #include "llvm/InitializePasses.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCSymbolXCOFF.h"
29 #include "llvm/Pass.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Target/TargetLoweringObjectFile.h"
33 #include "llvm/Target/TargetMachine.h"
41 using namespace llvm::dwarf
;
43 // Out of line virtual method.
44 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
48 class MMIAddrLabelMapCallbackPtr final
: CallbackVH
{
49 MMIAddrLabelMap
*Map
= nullptr;
52 MMIAddrLabelMapCallbackPtr() = default;
53 MMIAddrLabelMapCallbackPtr(Value
*V
) : CallbackVH(V
) {}
55 void setPtr(BasicBlock
*BB
) {
56 ValueHandleBase::operator=(BB
);
59 void setMap(MMIAddrLabelMap
*map
) { Map
= map
; }
61 void deleted() override
;
62 void allUsesReplacedWith(Value
*V2
) override
;
65 class MMIAddrLabelMap
{
67 struct AddrLabelSymEntry
{
68 /// The symbols for the label.
69 TinyPtrVector
<MCSymbol
*> Symbols
;
71 Function
*Fn
; // The containing function of the BasicBlock.
72 unsigned Index
; // The index in BBCallbacks for the BasicBlock.
75 DenseMap
<AssertingVH
<BasicBlock
>, AddrLabelSymEntry
> AddrLabelSymbols
;
77 /// Callbacks for the BasicBlock's that we have entries for. We use this so
78 /// we get notified if a block is deleted or RAUWd.
79 std::vector
<MMIAddrLabelMapCallbackPtr
> BBCallbacks
;
81 /// This is a per-function list of symbols whose corresponding BasicBlock got
82 /// deleted. These symbols need to be emitted at some point in the file, so
83 /// AsmPrinter emits them after the function body.
84 DenseMap
<AssertingVH
<Function
>, std::vector
<MCSymbol
*>>
85 DeletedAddrLabelsNeedingEmission
;
88 MMIAddrLabelMap(MCContext
&context
) : Context(context
) {}
91 assert(DeletedAddrLabelsNeedingEmission
.empty() &&
92 "Some labels for deleted blocks never got emitted");
95 ArrayRef
<MCSymbol
*> getAddrLabelSymbolToEmit(BasicBlock
*BB
);
97 void takeDeletedSymbolsForFunction(Function
*F
,
98 std::vector
<MCSymbol
*> &Result
);
100 void UpdateForDeletedBlock(BasicBlock
*BB
);
101 void UpdateForRAUWBlock(BasicBlock
*Old
, BasicBlock
*New
);
104 } // end namespace llvm
106 ArrayRef
<MCSymbol
*> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock
*BB
) {
107 assert(BB
->hasAddressTaken() &&
108 "Shouldn't get label for block without address taken");
109 AddrLabelSymEntry
&Entry
= AddrLabelSymbols
[BB
];
111 // If we already had an entry for this block, just return it.
112 if (!Entry
.Symbols
.empty()) {
113 assert(BB
->getParent() == Entry
.Fn
&& "Parent changed");
114 return Entry
.Symbols
;
117 // Otherwise, this is a new entry, create a new symbol for it and add an
118 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
119 BBCallbacks
.emplace_back(BB
);
120 BBCallbacks
.back().setMap(this);
121 Entry
.Index
= BBCallbacks
.size() - 1;
122 Entry
.Fn
= BB
->getParent();
123 MCSymbol
*Sym
= BB
->hasAddressTaken() ? Context
.createNamedTempSymbol()
124 : Context
.createTempSymbol();
125 Entry
.Symbols
.push_back(Sym
);
126 return Entry
.Symbols
;
129 /// If we have any deleted symbols for F, return them.
130 void MMIAddrLabelMap::
131 takeDeletedSymbolsForFunction(Function
*F
, std::vector
<MCSymbol
*> &Result
) {
132 DenseMap
<AssertingVH
<Function
>, std::vector
<MCSymbol
*>>::iterator I
=
133 DeletedAddrLabelsNeedingEmission
.find(F
);
135 // If there are no entries for the function, just return.
136 if (I
== DeletedAddrLabelsNeedingEmission
.end()) return;
138 // Otherwise, take the list.
139 std::swap(Result
, I
->second
);
140 DeletedAddrLabelsNeedingEmission
.erase(I
);
143 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock
*BB
) {
144 // If the block got deleted, there is no need for the symbol. If the symbol
145 // was already emitted, we can just forget about it, otherwise we need to
146 // queue it up for later emission when the function is output.
147 AddrLabelSymEntry Entry
= std::move(AddrLabelSymbols
[BB
]);
148 AddrLabelSymbols
.erase(BB
);
149 assert(!Entry
.Symbols
.empty() && "Didn't have a symbol, why a callback?");
150 BBCallbacks
[Entry
.Index
] = nullptr; // Clear the callback.
152 assert((BB
->getParent() == nullptr || BB
->getParent() == Entry
.Fn
) &&
153 "Block/parent mismatch");
155 for (MCSymbol
*Sym
: Entry
.Symbols
) {
156 if (Sym
->isDefined())
159 // If the block is not yet defined, we need to emit it at the end of the
160 // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
161 // for the containing Function. Since the block is being deleted, its
162 // parent may already be removed, we have to get the function from 'Entry'.
163 DeletedAddrLabelsNeedingEmission
[Entry
.Fn
].push_back(Sym
);
167 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock
*Old
, BasicBlock
*New
) {
168 // Get the entry for the RAUW'd block and remove it from our map.
169 AddrLabelSymEntry OldEntry
= std::move(AddrLabelSymbols
[Old
]);
170 AddrLabelSymbols
.erase(Old
);
171 assert(!OldEntry
.Symbols
.empty() && "Didn't have a symbol, why a callback?");
173 AddrLabelSymEntry
&NewEntry
= AddrLabelSymbols
[New
];
175 // If New is not address taken, just move our symbol over to it.
176 if (NewEntry
.Symbols
.empty()) {
177 BBCallbacks
[OldEntry
.Index
].setPtr(New
); // Update the callback.
178 NewEntry
= std::move(OldEntry
); // Set New's entry.
182 BBCallbacks
[OldEntry
.Index
] = nullptr; // Update the callback.
184 // Otherwise, we need to add the old symbols to the new block's set.
185 llvm::append_range(NewEntry
.Symbols
, OldEntry
.Symbols
);
188 void MMIAddrLabelMapCallbackPtr::deleted() {
189 Map
->UpdateForDeletedBlock(cast
<BasicBlock
>(getValPtr()));
192 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value
*V2
) {
193 Map
->UpdateForRAUWBlock(cast
<BasicBlock
>(getValPtr()), cast
<BasicBlock
>(V2
));
196 void MachineModuleInfo::initialize() {
197 ObjFileMMI
= nullptr;
200 UsesMSVCFloatingPoint
= UsesMorestackAddr
= false;
201 HasSplitStack
= HasNosplitStack
= false;
202 AddrLabelSymbols
= nullptr;
205 void MachineModuleInfo::finalize() {
206 Personalities
.clear();
208 delete AddrLabelSymbols
;
209 AddrLabelSymbols
= nullptr;
212 // We don't clear the ExternalContext.
215 ObjFileMMI
= nullptr;
218 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo
&&MMI
)
219 : TM(std::move(MMI
.TM
)),
220 Context(MMI
.TM
.getTargetTriple(), MMI
.TM
.getMCAsmInfo(),
221 MMI
.TM
.getMCRegisterInfo(), MMI
.TM
.getMCSubtargetInfo(), nullptr,
223 MachineFunctions(std::move(MMI
.MachineFunctions
)) {
224 Context
.setObjectFileInfo(MMI
.TM
.getObjFileLowering());
225 ObjFileMMI
= MMI
.ObjFileMMI
;
226 CurCallSite
= MMI
.CurCallSite
;
227 UsesMSVCFloatingPoint
= MMI
.UsesMSVCFloatingPoint
;
228 UsesMorestackAddr
= MMI
.UsesMorestackAddr
;
229 HasSplitStack
= MMI
.HasSplitStack
;
230 HasNosplitStack
= MMI
.HasNosplitStack
;
231 AddrLabelSymbols
= MMI
.AddrLabelSymbols
;
232 ExternalContext
= MMI
.ExternalContext
;
233 TheModule
= MMI
.TheModule
;
236 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine
*TM
)
237 : TM(*TM
), Context(TM
->getTargetTriple(), TM
->getMCAsmInfo(),
238 TM
->getMCRegisterInfo(), TM
->getMCSubtargetInfo(),
239 nullptr, nullptr, false) {
240 Context
.setObjectFileInfo(TM
->getObjFileLowering());
244 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine
*TM
,
245 MCContext
*ExtContext
)
246 : TM(*TM
), Context(TM
->getTargetTriple(), TM
->getMCAsmInfo(),
247 TM
->getMCRegisterInfo(), TM
->getMCSubtargetInfo(),
248 nullptr, nullptr, false),
249 ExternalContext(ExtContext
) {
250 Context
.setObjectFileInfo(TM
->getObjFileLowering());
254 MachineModuleInfo::~MachineModuleInfo() { finalize(); }
256 //===- Address of Block Management ----------------------------------------===//
259 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock
*BB
) {
260 // Lazily create AddrLabelSymbols.
261 if (!AddrLabelSymbols
)
262 AddrLabelSymbols
= new MMIAddrLabelMap(getContext());
263 return AddrLabelSymbols
->getAddrLabelSymbolToEmit(const_cast<BasicBlock
*>(BB
));
266 void MachineModuleInfo::
267 takeDeletedSymbolsForFunction(const Function
*F
,
268 std::vector
<MCSymbol
*> &Result
) {
269 // If no blocks have had their addresses taken, we're done.
270 if (!AddrLabelSymbols
) return;
271 return AddrLabelSymbols
->
272 takeDeletedSymbolsForFunction(const_cast<Function
*>(F
), Result
);
275 /// \name Exception Handling
278 void MachineModuleInfo::addPersonality(const Function
*Personality
) {
279 if (!llvm::is_contained(Personalities
, Personality
))
280 Personalities
.push_back(Personality
);
286 MachineModuleInfo::getMachineFunction(const Function
&F
) const {
287 auto I
= MachineFunctions
.find(&F
);
288 return I
!= MachineFunctions
.end() ? I
->second
.get() : nullptr;
291 MachineFunction
&MachineModuleInfo::getOrCreateMachineFunction(Function
&F
) {
292 // Shortcut for the common case where a sequence of MachineFunctionPasses
293 // all query for the same Function.
294 if (LastRequest
== &F
)
297 auto I
= MachineFunctions
.insert(
298 std::make_pair(&F
, std::unique_ptr
<MachineFunction
>()));
301 // No pre-existing machine function, create a new one.
302 const TargetSubtargetInfo
&STI
= *TM
.getSubtargetImpl(F
);
303 MF
= new MachineFunction(F
, TM
, STI
, NextFnNum
++, *this);
304 // Update the set entry.
305 I
.first
->second
.reset(MF
);
307 MF
= I
.first
->second
.get();
315 void MachineModuleInfo::deleteMachineFunctionFor(Function
&F
) {
316 MachineFunctions
.erase(&F
);
317 LastRequest
= nullptr;
318 LastResult
= nullptr;
323 /// This pass frees the MachineFunction object associated with a Function.
324 class FreeMachineFunction
: public FunctionPass
{
328 FreeMachineFunction() : FunctionPass(ID
) {}
330 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
331 AU
.addRequired
<MachineModuleInfoWrapperPass
>();
332 AU
.addPreserved
<MachineModuleInfoWrapperPass
>();
335 bool runOnFunction(Function
&F
) override
{
336 MachineModuleInfo
&MMI
=
337 getAnalysis
<MachineModuleInfoWrapperPass
>().getMMI();
338 MMI
.deleteMachineFunctionFor(F
);
342 StringRef
getPassName() const override
{
343 return "Free MachineFunction";
347 } // end anonymous namespace
349 char FreeMachineFunction::ID
;
351 FunctionPass
*llvm::createFreeMachineFunctionPass() {
352 return new FreeMachineFunction();
355 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
356 const LLVMTargetMachine
*TM
)
357 : ImmutablePass(ID
), MMI(TM
) {
358 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
361 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
362 const LLVMTargetMachine
*TM
, MCContext
*ExtContext
)
363 : ImmutablePass(ID
), MMI(TM
, ExtContext
) {
364 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
367 // Handle the Pass registration stuff necessary to use DataLayout's.
368 INITIALIZE_PASS(MachineModuleInfoWrapperPass
, "machinemoduleinfo",
369 "Machine Module Information", false, false)
370 char MachineModuleInfoWrapperPass::ID
= 0;
372 static unsigned getLocCookie(const SMDiagnostic
&SMD
, const SourceMgr
&SrcMgr
,
373 std::vector
<const MDNode
*> &LocInfos
) {
374 // Look up a LocInfo for the buffer this diagnostic is coming from.
375 unsigned BufNum
= SrcMgr
.FindBufferContainingLoc(SMD
.getLoc());
376 const MDNode
*LocInfo
= nullptr;
377 if (BufNum
> 0 && BufNum
<= LocInfos
.size())
378 LocInfo
= LocInfos
[BufNum
- 1];
380 // If the inline asm had metadata associated with it, pull out a location
381 // cookie corresponding to which line the error occurred on.
382 unsigned LocCookie
= 0;
384 unsigned ErrorLine
= SMD
.getLineNo() - 1;
385 if (ErrorLine
>= LocInfo
->getNumOperands())
388 if (LocInfo
->getNumOperands() != 0)
389 if (const ConstantInt
*CI
=
390 mdconst::dyn_extract
<ConstantInt
>(LocInfo
->getOperand(ErrorLine
)))
391 LocCookie
= CI
->getZExtValue();
397 bool MachineModuleInfoWrapperPass::doInitialization(Module
&M
) {
400 // FIXME: Do this for new pass manager.
401 LLVMContext
&Ctx
= M
.getContext();
402 MMI
.getContext().setDiagnosticHandler(
403 [&Ctx
](const SMDiagnostic
&SMD
, bool IsInlineAsm
, const SourceMgr
&SrcMgr
,
404 std::vector
<const MDNode
*> &LocInfos
) {
405 unsigned LocCookie
= 0;
407 LocCookie
= getLocCookie(SMD
, SrcMgr
, LocInfos
);
408 Ctx
.diagnose(DiagnosticInfoSrcMgr(SMD
, IsInlineAsm
, LocCookie
));
410 MMI
.DbgInfoAvailable
= !M
.debug_compile_units().empty();
414 bool MachineModuleInfoWrapperPass::doFinalization(Module
&M
) {
419 AnalysisKey
MachineModuleAnalysis::Key
;
421 MachineModuleInfo
MachineModuleAnalysis::run(Module
&M
,
422 ModuleAnalysisManager
&) {
423 MachineModuleInfo
MMI(TM
);
425 MMI
.DbgInfoAvailable
= !M
.debug_compile_units().empty();