From 90af134473331095adcf2c7e4a511ac35d9f2f4a Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 7 Apr 2021 11:26:18 -0700 Subject: [PATCH] Revert "[AsmPrinter] Delete dead takeDeletedSymbsForFunction()" This reverts commit 9583a3f2625818b78c0cf6d473cdedb9f23ad82c. This wasn't NFC as initially thought. Needed for D99707. --- llvm/include/llvm/CodeGen/MachineModuleInfo.h | 7 ++++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 10 ++++++ llvm/lib/CodeGen/MachineModuleInfo.cpp | 49 +++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h index fa900af..39939f5 100644 --- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -243,6 +243,13 @@ public: /// to emit them as well, return the whole set. ArrayRef getAddrLabelSymbolToEmit(const BasicBlock *BB); + /// If the specified function has had any references to address-taken blocks + /// generated, but the block got deleted, return the symbol now so we can + /// emit it. This prevents emitting a reference to a symbol that has no + /// definition. + void takeDeletedSymbolsForFunction(const Function *F, + std::vector &Result); + /// \name Exception Handling /// \{ diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index c1416cd..e7a8f1f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -791,6 +791,16 @@ void AsmPrinter::emitFunctionHeader() { // their wild and crazy things as required. emitFunctionEntryLabel(); + // If the function had address-taken blocks that got deleted, then we have + // references to the dangling symbols. Emit them at the start of the function + // so that we don't get references to undefined symbols. + std::vector DeadBlockSyms; + MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms); + for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { + OutStreamer->AddComment("Address taken block that was later removed"); + OutStreamer->emitLabel(DeadBlockSyms[i]); + } + if (CurrentFnBegin) { if (MAI->useAssignmentForEHBegin()) { MCSymbol *CurPos = OutContext.createTempSymbol(); diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp index 8a3aef3..b436633 100644 --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -78,11 +78,25 @@ class MMIAddrLabelMap { /// we get notified if a block is deleted or RAUWd. std::vector BBCallbacks; + /// This is a per-function list of symbols whose corresponding BasicBlock got + /// deleted. These symbols need to be emitted at some point in the file, so + /// AsmPrinter emits them after the function body. + DenseMap, std::vector> + DeletedAddrLabelsNeedingEmission; + public: MMIAddrLabelMap(MCContext &context) : Context(context) {} + ~MMIAddrLabelMap() { + assert(DeletedAddrLabelsNeedingEmission.empty() && + "Some labels for deleted blocks never got emitted"); + } + ArrayRef getAddrLabelSymbolToEmit(BasicBlock *BB); + void takeDeletedSymbolsForFunction(Function *F, + std::vector &Result); + void UpdateForDeletedBlock(BasicBlock *BB); void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); }; @@ -112,6 +126,20 @@ ArrayRef MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { return Entry.Symbols; } +/// If we have any deleted symbols for F, return them. +void MMIAddrLabelMap:: +takeDeletedSymbolsForFunction(Function *F, std::vector &Result) { + DenseMap, std::vector>::iterator I = + DeletedAddrLabelsNeedingEmission.find(F); + + // If there are no entries for the function, just return. + if (I == DeletedAddrLabelsNeedingEmission.end()) return; + + // Otherwise, take the list. + std::swap(Result, I->second); + DeletedAddrLabelsNeedingEmission.erase(I); +} + void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { // If the block got deleted, there is no need for the symbol. If the symbol // was already emitted, we can just forget about it, otherwise we need to @@ -124,8 +152,16 @@ void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && "Block/parent mismatch"); - assert(llvm::all_of(Entry.Symbols, [](MCSymbol *Sym) { - return Sym->isDefined(); })); + for (MCSymbol *Sym : Entry.Symbols) { + if (Sym->isDefined()) + return; + + // If the block is not yet defined, we need to emit it at the end of the + // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list + // for the containing Function. Since the block is being deleted, its + // parent may already be removed, we have to get the function from 'Entry'. + DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); + } } void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { @@ -220,6 +256,15 @@ MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast(BB)); } +void MachineModuleInfo:: +takeDeletedSymbolsForFunction(const Function *F, + std::vector &Result) { + // If no blocks have had their addresses taken, we're done. + if (!AddrLabelSymbols) return; + return AddrLabelSymbols-> + takeDeletedSymbolsForFunction(const_cast(F), Result); +} + /// \name Exception Handling /// \{ -- 2.7.4