Skip to content

Commit 9209a51

Browse files
committed
MachineModuleInfo: Move AddrLabelSymbols to AsmPrinter
This was tracking global state only used by the AsmPrinter, which can store its own module global state.
1 parent cce7951 commit 9209a51

File tree

4 files changed

+204
-207
lines changed

4 files changed

+204
-207
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
namespace llvm {
3232

33+
class AddrLabelMap;
3334
class BasicBlock;
3435
class BlockAddress;
3536
class Constant;
@@ -174,6 +175,10 @@ class AsmPrinter : public MachineFunctionPass {
174175
// function. This is used to calculate the size of the BB section.
175176
MCSymbol *CurrentSectionBeginSym = nullptr;
176177

178+
/// This map keeps track of which symbol is being used for the specified basic
179+
/// block's address of label.
180+
std::unique_ptr<AddrLabelMap> AddrLabelSymbols;
181+
177182
// The garbage collection metadata printer table.
178183
void *GCMetadataPrinters = nullptr; // Really a DenseMap.
179184

@@ -262,6 +267,25 @@ class AsmPrinter : public MachineFunctionPass {
262267
// given basic block.
263268
MCSymbol *getMBBExceptionSym(const MachineBasicBlock &MBB);
264269

270+
/// Return the symbol to be used for the specified basic block when its
271+
/// address is taken. This cannot be its normal LBB label because the block
272+
/// may be accessed outside its containing function.
273+
MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) {
274+
return getAddrLabelSymbolToEmit(BB).front();
275+
}
276+
277+
/// Return the symbol to be used for the specified basic block when its
278+
/// address is taken. If other blocks were RAUW'd to this one, we may have
279+
/// to emit them as well, return the whole set.
280+
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB);
281+
282+
/// If the specified function has had any references to address-taken blocks
283+
/// generated, but the block got deleted, return the symbol now so we can
284+
/// emit it. This prevents emitting a reference to a symbol that has no
285+
/// definition.
286+
void takeDeletedSymbolsForFunction(const Function *F,
287+
std::vector<MCSymbol *> &Result);
288+
265289
/// Return information about object file lowering.
266290
const TargetLoweringObjectFile &getObjFileLowering() const;
267291

llvm/include/llvm/CodeGen/MachineModuleInfo.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ namespace llvm {
4545
class BasicBlock;
4646
class Function;
4747
class LLVMTargetMachine;
48-
class MMIAddrLabelMap;
4948
class MachineFunction;
5049
class Module;
5150
class MCSymbol;
@@ -106,10 +105,6 @@ class MachineModuleInfo {
106105

107106
/// \}
108107

109-
/// This map keeps track of which symbol is being used for the specified
110-
/// basic block's address of label.
111-
MMIAddrLabelMap *AddrLabelSymbols;
112-
113108
// TODO: Ideally, what we'd like is to have a switch that allows emitting
114109
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
115110
// even under this switch, we'd like .debug_frame to be precise when using
@@ -189,25 +184,6 @@ class MachineModuleInfo {
189184

190185
void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }
191186

192-
/// Return the symbol to be used for the specified basic block when its
193-
/// address is taken. This cannot be its normal LBB label because the block
194-
/// may be accessed outside its containing function.
195-
MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) {
196-
return getAddrLabelSymbolToEmit(BB).front();
197-
}
198-
199-
/// Return the symbol to be used for the specified basic block when its
200-
/// address is taken. If other blocks were RAUW'd to this one, we may have
201-
/// to emit them as well, return the whole set.
202-
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB);
203-
204-
/// If the specified function has had any references to address-taken blocks
205-
/// generated, but the block got deleted, return the symbol now so we can
206-
/// emit it. This prevents emitting a reference to a symbol that has no
207-
/// definition.
208-
void takeDeletedSymbolsForFunction(const Function *F,
209-
std::vector<MCSymbol*> &Result);
210-
211187
/// \name Exception Handling
212188
/// \{
213189

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,178 @@ static gcp_map_type &getGCMap(void *&P) {
153153
return *(gcp_map_type*)P;
154154
}
155155

156+
namespace {
157+
class AddrLabelMapCallbackPtr final : CallbackVH {
158+
AddrLabelMap *Map = nullptr;
159+
160+
public:
161+
AddrLabelMapCallbackPtr() = default;
162+
AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}
163+
164+
void setPtr(BasicBlock *BB) {
165+
ValueHandleBase::operator=(BB);
166+
}
167+
168+
void setMap(AddrLabelMap *map) { Map = map; }
169+
170+
void deleted() override;
171+
void allUsesReplacedWith(Value *V2) override;
172+
};
173+
} // namespace
174+
175+
class llvm::AddrLabelMap {
176+
MCContext &Context;
177+
struct AddrLabelSymEntry {
178+
/// The symbols for the label.
179+
TinyPtrVector<MCSymbol *> Symbols;
180+
181+
Function *Fn; // The containing function of the BasicBlock.
182+
unsigned Index; // The index in BBCallbacks for the BasicBlock.
183+
};
184+
185+
DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
186+
187+
/// Callbacks for the BasicBlock's that we have entries for. We use this so
188+
/// we get notified if a block is deleted or RAUWd.
189+
std::vector<AddrLabelMapCallbackPtr> BBCallbacks;
190+
191+
/// This is a per-function list of symbols whose corresponding BasicBlock got
192+
/// deleted. These symbols need to be emitted at some point in the file, so
193+
/// AsmPrinter emits them after the function body.
194+
DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>
195+
DeletedAddrLabelsNeedingEmission;
196+
197+
public:
198+
AddrLabelMap(MCContext &context) : Context(context) {}
199+
200+
~AddrLabelMap() {
201+
assert(DeletedAddrLabelsNeedingEmission.empty() &&
202+
"Some labels for deleted blocks never got emitted");
203+
}
204+
205+
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
206+
207+
void takeDeletedSymbolsForFunction(Function *F,
208+
std::vector<MCSymbol *> &Result);
209+
210+
void UpdateForDeletedBlock(BasicBlock *BB);
211+
void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
212+
};
213+
214+
ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
215+
assert(BB->hasAddressTaken() &&
216+
"Shouldn't get label for block without address taken");
217+
AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
218+
219+
// If we already had an entry for this block, just return it.
220+
if (!Entry.Symbols.empty()) {
221+
assert(BB->getParent() == Entry.Fn && "Parent changed");
222+
return Entry.Symbols;
223+
}
224+
225+
// Otherwise, this is a new entry, create a new symbol for it and add an
226+
// entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
227+
BBCallbacks.emplace_back(BB);
228+
BBCallbacks.back().setMap(this);
229+
Entry.Index = BBCallbacks.size() - 1;
230+
Entry.Fn = BB->getParent();
231+
MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()
232+
: Context.createTempSymbol();
233+
Entry.Symbols.push_back(Sym);
234+
return Entry.Symbols;
235+
}
236+
237+
/// If we have any deleted symbols for F, return them.
238+
void AddrLabelMap::takeDeletedSymbolsForFunction(
239+
Function *F, std::vector<MCSymbol *> &Result) {
240+
DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I =
241+
DeletedAddrLabelsNeedingEmission.find(F);
242+
243+
// If there are no entries for the function, just return.
244+
if (I == DeletedAddrLabelsNeedingEmission.end())
245+
return;
246+
247+
// Otherwise, take the list.
248+
std::swap(Result, I->second);
249+
DeletedAddrLabelsNeedingEmission.erase(I);
250+
}
251+
252+
//===- Address of Block Management ----------------------------------------===//
253+
254+
ArrayRef<MCSymbol *>
255+
AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
256+
// Lazily create AddrLabelSymbols.
257+
if (!AddrLabelSymbols)
258+
AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext);
259+
return AddrLabelSymbols->getAddrLabelSymbolToEmit(
260+
const_cast<BasicBlock *>(BB));
261+
}
262+
263+
void AsmPrinter::takeDeletedSymbolsForFunction(
264+
const Function *F, std::vector<MCSymbol *> &Result) {
265+
// If no blocks have had their addresses taken, we're done.
266+
if (!AddrLabelSymbols)
267+
return;
268+
return AddrLabelSymbols->takeDeletedSymbolsForFunction(
269+
const_cast<Function *>(F), Result);
270+
}
271+
272+
void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
273+
// If the block got deleted, there is no need for the symbol. If the symbol
274+
// was already emitted, we can just forget about it, otherwise we need to
275+
// queue it up for later emission when the function is output.
276+
AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
277+
AddrLabelSymbols.erase(BB);
278+
assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
279+
BBCallbacks[Entry.Index] = nullptr; // Clear the callback.
280+
281+
#if !LLVM_MEMORY_SANITIZER_BUILD
282+
// BasicBlock is destroyed already, so this access is UB detectable by msan.
283+
assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
284+
"Block/parent mismatch");
285+
#endif
286+
287+
for (MCSymbol *Sym : Entry.Symbols) {
288+
if (Sym->isDefined())
289+
return;
290+
291+
// If the block is not yet defined, we need to emit it at the end of the
292+
// function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
293+
// for the containing Function. Since the block is being deleted, its
294+
// parent may already be removed, we have to get the function from 'Entry'.
295+
DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
296+
}
297+
}
298+
299+
void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
300+
// Get the entry for the RAUW'd block and remove it from our map.
301+
AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
302+
AddrLabelSymbols.erase(Old);
303+
assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
304+
305+
AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
306+
307+
// If New is not address taken, just move our symbol over to it.
308+
if (NewEntry.Symbols.empty()) {
309+
BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
310+
NewEntry = std::move(OldEntry); // Set New's entry.
311+
return;
312+
}
313+
314+
BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
315+
316+
// Otherwise, we need to add the old symbols to the new block's set.
317+
llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);
318+
}
319+
320+
void AddrLabelMapCallbackPtr::deleted() {
321+
Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
322+
}
323+
324+
void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
325+
Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
326+
}
327+
156328
/// getGVAlignment - Return the alignment to use for the specified global
157329
/// value. This rounds up to the preferred alignment if possible and legal.
158330
Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
@@ -260,6 +432,8 @@ bool AsmPrinter::doInitialization(Module &M) {
260432
HasSplitStack = false;
261433
HasNoSplitStack = false;
262434

435+
AddrLabelSymbols = nullptr;
436+
263437
// Initialize TargetLoweringObjectFile.
264438
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
265439
.Initialize(OutContext, TM);
@@ -802,7 +976,7 @@ void AsmPrinter::emitFunctionHeader() {
802976
// references to the dangling symbols. Emit them at the start of the function
803977
// so that we don't get references to undefined symbols.
804978
std::vector<MCSymbol*> DeadBlockSyms;
805-
MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
979+
takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
806980
for (MCSymbol *DeadBlockSym : DeadBlockSyms) {
807981
OutStreamer->AddComment("Address taken block that was later removed");
808982
OutStreamer->emitLabel(DeadBlockSym);
@@ -1956,6 +2130,7 @@ bool AsmPrinter::doFinalization(Module &M) {
19562130
emitEndOfAsmFile(M);
19572131

19582132
MMI = nullptr;
2133+
AddrLabelSymbols = nullptr;
19592134

19602135
OutStreamer->Finish();
19612136
OutStreamer->reset();
@@ -3140,11 +3315,12 @@ MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const {
31403315
}
31413316

31423317
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
3143-
return MMI->getAddrLabelSymbol(BA->getBasicBlock());
3318+
return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(
3319+
BA->getBasicBlock());
31443320
}
31453321

31463322
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {
3147-
return MMI->getAddrLabelSymbol(BB);
3323+
return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB);
31483324
}
31493325

31503326
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
@@ -3303,7 +3479,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
33033479
// MBBs can have their address taken as part of CodeGen without having
33043480
// their corresponding BB's address taken in IR
33053481
if (BB && BB->hasAddressTaken())
3306-
for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB))
3482+
for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
33073483
OutStreamer->emitLabel(Sym);
33083484
}
33093485

0 commit comments

Comments
 (0)