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/Instructions.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/IR/Value.h"
22 #include "llvm/IR/ValueHandle.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Target/TargetLoweringObjectFile.h"
29 #include "llvm/Target/TargetMachine.h"
37 using namespace llvm::dwarf
;
39 // Out of line virtual method.
40 MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;
44 class MMIAddrLabelMapCallbackPtr final
: CallbackVH
{
45 MMIAddrLabelMap
*Map
= nullptr;
48 MMIAddrLabelMapCallbackPtr() = default;
49 MMIAddrLabelMapCallbackPtr(Value
*V
) : CallbackVH(V
) {}
51 void setPtr(BasicBlock
*BB
) {
52 ValueHandleBase::operator=(BB
);
55 void setMap(MMIAddrLabelMap
*map
) { Map
= map
; }
57 void deleted() override
;
58 void allUsesReplacedWith(Value
*V2
) override
;
61 class MMIAddrLabelMap
{
63 struct AddrLabelSymEntry
{
64 /// The symbols for the label.
65 TinyPtrVector
<MCSymbol
*> Symbols
;
67 Function
*Fn
; // The containing function of the BasicBlock.
68 unsigned Index
; // The index in BBCallbacks for the BasicBlock.
71 DenseMap
<AssertingVH
<BasicBlock
>, AddrLabelSymEntry
> AddrLabelSymbols
;
73 /// Callbacks for the BasicBlock's that we have entries for. We use this so
74 /// we get notified if a block is deleted or RAUWd.
75 std::vector
<MMIAddrLabelMapCallbackPtr
> BBCallbacks
;
77 /// This is a per-function list of symbols whose corresponding BasicBlock got
78 /// deleted. These symbols need to be emitted at some point in the file, so
79 /// AsmPrinter emits them after the function body.
80 DenseMap
<AssertingVH
<Function
>, std::vector
<MCSymbol
*>>
81 DeletedAddrLabelsNeedingEmission
;
84 MMIAddrLabelMap(MCContext
&context
) : Context(context
) {}
87 assert(DeletedAddrLabelsNeedingEmission
.empty() &&
88 "Some labels for deleted blocks never got emitted");
91 ArrayRef
<MCSymbol
*> getAddrLabelSymbolToEmit(BasicBlock
*BB
);
93 void takeDeletedSymbolsForFunction(Function
*F
,
94 std::vector
<MCSymbol
*> &Result
);
96 void UpdateForDeletedBlock(BasicBlock
*BB
);
97 void UpdateForRAUWBlock(BasicBlock
*Old
, BasicBlock
*New
);
100 } // end namespace llvm
102 ArrayRef
<MCSymbol
*> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock
*BB
) {
103 assert(BB
->hasAddressTaken() &&
104 "Shouldn't get label for block without address taken");
105 AddrLabelSymEntry
&Entry
= AddrLabelSymbols
[BB
];
107 // If we already had an entry for this block, just return it.
108 if (!Entry
.Symbols
.empty()) {
109 assert(BB
->getParent() == Entry
.Fn
&& "Parent changed");
110 return Entry
.Symbols
;
113 // Otherwise, this is a new entry, create a new symbol for it and add an
114 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
115 BBCallbacks
.emplace_back(BB
);
116 BBCallbacks
.back().setMap(this);
117 Entry
.Index
= BBCallbacks
.size() - 1;
118 Entry
.Fn
= BB
->getParent();
119 Entry
.Symbols
.push_back(Context
.createTempSymbol(!BB
->hasAddressTaken()));
120 return Entry
.Symbols
;
123 /// If we have any deleted symbols for F, return them.
124 void MMIAddrLabelMap::
125 takeDeletedSymbolsForFunction(Function
*F
, std::vector
<MCSymbol
*> &Result
) {
126 DenseMap
<AssertingVH
<Function
>, std::vector
<MCSymbol
*>>::iterator I
=
127 DeletedAddrLabelsNeedingEmission
.find(F
);
129 // If there are no entries for the function, just return.
130 if (I
== DeletedAddrLabelsNeedingEmission
.end()) return;
132 // Otherwise, take the list.
133 std::swap(Result
, I
->second
);
134 DeletedAddrLabelsNeedingEmission
.erase(I
);
137 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock
*BB
) {
138 // If the block got deleted, there is no need for the symbol. If the symbol
139 // was already emitted, we can just forget about it, otherwise we need to
140 // queue it up for later emission when the function is output.
141 AddrLabelSymEntry Entry
= std::move(AddrLabelSymbols
[BB
]);
142 AddrLabelSymbols
.erase(BB
);
143 assert(!Entry
.Symbols
.empty() && "Didn't have a symbol, why a callback?");
144 BBCallbacks
[Entry
.Index
] = nullptr; // Clear the callback.
146 assert((BB
->getParent() == nullptr || BB
->getParent() == Entry
.Fn
) &&
147 "Block/parent mismatch");
149 for (MCSymbol
*Sym
: Entry
.Symbols
) {
150 if (Sym
->isDefined())
153 // If the block is not yet defined, we need to emit it at the end of the
154 // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
155 // for the containing Function. Since the block is being deleted, its
156 // parent may already be removed, we have to get the function from 'Entry'.
157 DeletedAddrLabelsNeedingEmission
[Entry
.Fn
].push_back(Sym
);
161 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock
*Old
, BasicBlock
*New
) {
162 // Get the entry for the RAUW'd block and remove it from our map.
163 AddrLabelSymEntry OldEntry
= std::move(AddrLabelSymbols
[Old
]);
164 AddrLabelSymbols
.erase(Old
);
165 assert(!OldEntry
.Symbols
.empty() && "Didn't have a symbol, why a callback?");
167 AddrLabelSymEntry
&NewEntry
= AddrLabelSymbols
[New
];
169 // If New is not address taken, just move our symbol over to it.
170 if (NewEntry
.Symbols
.empty()) {
171 BBCallbacks
[OldEntry
.Index
].setPtr(New
); // Update the callback.
172 NewEntry
= std::move(OldEntry
); // Set New's entry.
176 BBCallbacks
[OldEntry
.Index
] = nullptr; // Update the callback.
178 // Otherwise, we need to add the old symbols to the new block's set.
179 NewEntry
.Symbols
.insert(NewEntry
.Symbols
.end(), OldEntry
.Symbols
.begin(),
180 OldEntry
.Symbols
.end());
183 void MMIAddrLabelMapCallbackPtr::deleted() {
184 Map
->UpdateForDeletedBlock(cast
<BasicBlock
>(getValPtr()));
187 void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value
*V2
) {
188 Map
->UpdateForRAUWBlock(cast
<BasicBlock
>(getValPtr()), cast
<BasicBlock
>(V2
));
191 void MachineModuleInfo::initialize() {
192 ObjFileMMI
= nullptr;
194 UsesMSVCFloatingPoint
= UsesMorestackAddr
= false;
195 HasSplitStack
= HasNosplitStack
= false;
196 AddrLabelSymbols
= nullptr;
199 void MachineModuleInfo::finalize() {
200 Personalities
.clear();
202 delete AddrLabelSymbols
;
203 AddrLabelSymbols
= nullptr;
208 ObjFileMMI
= nullptr;
211 MachineModuleInfo::MachineModuleInfo(MachineModuleInfo
&&MMI
)
212 : TM(std::move(MMI
.TM
)),
213 Context(MMI
.TM
.getMCAsmInfo(), MMI
.TM
.getMCRegisterInfo(),
214 MMI
.TM
.getObjFileLowering(), nullptr, nullptr, false) {
215 ObjFileMMI
= MMI
.ObjFileMMI
;
216 CurCallSite
= MMI
.CurCallSite
;
217 UsesMSVCFloatingPoint
= MMI
.UsesMSVCFloatingPoint
;
218 UsesMorestackAddr
= MMI
.UsesMorestackAddr
;
219 HasSplitStack
= MMI
.HasSplitStack
;
220 HasNosplitStack
= MMI
.HasNosplitStack
;
221 AddrLabelSymbols
= MMI
.AddrLabelSymbols
;
222 TheModule
= MMI
.TheModule
;
225 MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine
*TM
)
226 : TM(*TM
), Context(TM
->getMCAsmInfo(), TM
->getMCRegisterInfo(),
227 TM
->getObjFileLowering(), nullptr, nullptr, false) {
231 MachineModuleInfo::~MachineModuleInfo() { finalize(); }
233 //===- Address of Block Management ----------------------------------------===//
236 MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock
*BB
) {
237 // Lazily create AddrLabelSymbols.
238 if (!AddrLabelSymbols
)
239 AddrLabelSymbols
= new MMIAddrLabelMap(Context
);
240 return AddrLabelSymbols
->getAddrLabelSymbolToEmit(const_cast<BasicBlock
*>(BB
));
243 void MachineModuleInfo::
244 takeDeletedSymbolsForFunction(const Function
*F
,
245 std::vector
<MCSymbol
*> &Result
) {
246 // If no blocks have had their addresses taken, we're done.
247 if (!AddrLabelSymbols
) return;
248 return AddrLabelSymbols
->
249 takeDeletedSymbolsForFunction(const_cast<Function
*>(F
), Result
);
252 /// \name Exception Handling
255 void MachineModuleInfo::addPersonality(const Function
*Personality
) {
256 for (unsigned i
= 0; i
< Personalities
.size(); ++i
)
257 if (Personalities
[i
] == Personality
)
259 Personalities
.push_back(Personality
);
265 MachineModuleInfo::getMachineFunction(const Function
&F
) const {
266 auto I
= MachineFunctions
.find(&F
);
267 return I
!= MachineFunctions
.end() ? I
->second
.get() : nullptr;
271 MachineModuleInfo::getOrCreateMachineFunction(const Function
&F
) {
272 // Shortcut for the common case where a sequence of MachineFunctionPasses
273 // all query for the same Function.
274 if (LastRequest
== &F
)
277 auto I
= MachineFunctions
.insert(
278 std::make_pair(&F
, std::unique_ptr
<MachineFunction
>()));
281 // No pre-existing machine function, create a new one.
282 const TargetSubtargetInfo
&STI
= *TM
.getSubtargetImpl(F
);
283 MF
= new MachineFunction(F
, TM
, STI
, NextFnNum
++, *this);
284 // Update the set entry.
285 I
.first
->second
.reset(MF
);
287 MF
= I
.first
->second
.get();
295 void MachineModuleInfo::deleteMachineFunctionFor(Function
&F
) {
296 MachineFunctions
.erase(&F
);
297 LastRequest
= nullptr;
298 LastResult
= nullptr;
303 /// This pass frees the MachineFunction object associated with a Function.
304 class FreeMachineFunction
: public FunctionPass
{
308 FreeMachineFunction() : FunctionPass(ID
) {}
310 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
311 AU
.addRequired
<MachineModuleInfoWrapperPass
>();
312 AU
.addPreserved
<MachineModuleInfoWrapperPass
>();
315 bool runOnFunction(Function
&F
) override
{
316 MachineModuleInfo
&MMI
=
317 getAnalysis
<MachineModuleInfoWrapperPass
>().getMMI();
318 MMI
.deleteMachineFunctionFor(F
);
322 StringRef
getPassName() const override
{
323 return "Free MachineFunction";
327 } // end anonymous namespace
329 char FreeMachineFunction::ID
;
331 FunctionPass
*llvm::createFreeMachineFunctionPass() {
332 return new FreeMachineFunction();
335 MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(
336 const LLVMTargetMachine
*TM
)
337 : ImmutablePass(ID
), MMI(TM
) {
338 initializeMachineModuleInfoWrapperPassPass(*PassRegistry::getPassRegistry());
341 // Handle the Pass registration stuff necessary to use DataLayout's.
342 INITIALIZE_PASS(MachineModuleInfoWrapperPass
, "machinemoduleinfo",
343 "Machine Module Information", false, false)
344 char MachineModuleInfoWrapperPass::ID
= 0;
346 bool MachineModuleInfoWrapperPass::doInitialization(Module
&M
) {
349 MMI
.DbgInfoAvailable
= !M
.debug_compile_units().empty();
353 bool MachineModuleInfoWrapperPass::doFinalization(Module
&M
) {
358 AnalysisKey
MachineModuleAnalysis::Key
;
360 MachineModuleInfo
MachineModuleAnalysis::run(Module
&M
,
361 ModuleAnalysisManager
&) {
362 MachineModuleInfo
MMI(TM
);
364 MMI
.DbgInfoAvailable
= !M
.debug_compile_units().empty();