mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
[MMI] Use TinyPtrVector instead of PointerUnion with vector.
Also simplify duplicated code a bit. No functionality change intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240990 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -284,12 +284,14 @@ public:
|
|||||||
/// getAddrLabelSymbol - Return the symbol to be used for the specified basic
|
/// getAddrLabelSymbol - Return the symbol to be used for the specified basic
|
||||||
/// block when its address is taken. This cannot be its normal LBB label
|
/// block when its address is taken. This cannot be its normal LBB label
|
||||||
/// because the block may be accessed outside its containing function.
|
/// because the block may be accessed outside its containing function.
|
||||||
MCSymbol *getAddrLabelSymbol(const BasicBlock *BB);
|
MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) {
|
||||||
|
return getAddrLabelSymbolToEmit(BB).front();
|
||||||
|
}
|
||||||
|
|
||||||
/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
|
/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
|
||||||
/// basic block when its address is taken. If other blocks were RAUW'd to
|
/// basic block when its address is taken. If other blocks were RAUW'd to
|
||||||
/// this one, we may have to emit them as well, return the whole set.
|
/// this one, we may have to emit them as well, return the whole set.
|
||||||
std::vector<MCSymbol*> getAddrLabelSymbolToEmit(const BasicBlock *BB);
|
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB);
|
||||||
|
|
||||||
/// takeDeletedSymbolsForFunction - If the specified function has had any
|
/// takeDeletedSymbolsForFunction - If the specified function has had any
|
||||||
/// references to address-taken blocks generated, but the block got deleted,
|
/// references to address-taken blocks generated, but the block got deleted,
|
||||||
|
@ -2390,8 +2390,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
|
|||||||
if (isVerbose())
|
if (isVerbose())
|
||||||
OutStreamer->AddComment("Block address taken");
|
OutStreamer->AddComment("Block address taken");
|
||||||
|
|
||||||
std::vector<MCSymbol*> Symbols = MMI->getAddrLabelSymbolToEmit(BB);
|
for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB))
|
||||||
for (auto *Sym : Symbols)
|
|
||||||
OutStreamer->EmitLabel(Sym);
|
OutStreamer->EmitLabel(Sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +54,8 @@ public:
|
|||||||
class MMIAddrLabelMap {
|
class MMIAddrLabelMap {
|
||||||
MCContext &Context;
|
MCContext &Context;
|
||||||
struct AddrLabelSymEntry {
|
struct AddrLabelSymEntry {
|
||||||
/// Symbols - The symbols for the label. This is a pointer union that is
|
/// Symbols - The symbols for the label.
|
||||||
/// either one symbol (the common case) or a list of symbols.
|
TinyPtrVector<MCSymbol *> Symbols;
|
||||||
PointerUnion<MCSymbol *, std::vector<MCSymbol*>*> Symbols;
|
|
||||||
|
|
||||||
Function *Fn; // The containing function of the BasicBlock.
|
Function *Fn; // The containing function of the BasicBlock.
|
||||||
unsigned Index; // The index in BBCallbacks for the BasicBlock.
|
unsigned Index; // The index in BBCallbacks for the BasicBlock.
|
||||||
@ -80,16 +79,9 @@ public:
|
|||||||
~MMIAddrLabelMap() {
|
~MMIAddrLabelMap() {
|
||||||
assert(DeletedAddrLabelsNeedingEmission.empty() &&
|
assert(DeletedAddrLabelsNeedingEmission.empty() &&
|
||||||
"Some labels for deleted blocks never got emitted");
|
"Some labels for deleted blocks never got emitted");
|
||||||
|
|
||||||
// Deallocate any of the 'list of symbols' case.
|
|
||||||
for (DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry>::iterator
|
|
||||||
I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I)
|
|
||||||
if (I->second.Symbols.is<std::vector<MCSymbol*>*>())
|
|
||||||
delete I->second.Symbols.get<std::vector<MCSymbol*>*>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MCSymbol *getAddrLabelSymbol(BasicBlock *BB);
|
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
|
||||||
std::vector<MCSymbol*> getAddrLabelSymbolToEmit(BasicBlock *BB);
|
|
||||||
|
|
||||||
void takeDeletedSymbolsForFunction(Function *F,
|
void takeDeletedSymbolsForFunction(Function *F,
|
||||||
std::vector<MCSymbol*> &Result);
|
std::vector<MCSymbol*> &Result);
|
||||||
@ -99,17 +91,15 @@ public:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) {
|
ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
|
||||||
assert(BB->hasAddressTaken() &&
|
assert(BB->hasAddressTaken() &&
|
||||||
"Shouldn't get label for block without address taken");
|
"Shouldn't get label for block without address taken");
|
||||||
AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
|
AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
|
||||||
|
|
||||||
// If we already had an entry for this block, just return it.
|
// If we already had an entry for this block, just return it.
|
||||||
if (!Entry.Symbols.isNull()) {
|
if (!Entry.Symbols.empty()) {
|
||||||
assert(BB->getParent() == Entry.Fn && "Parent changed");
|
assert(BB->getParent() == Entry.Fn && "Parent changed");
|
||||||
if (Entry.Symbols.is<MCSymbol*>())
|
return Entry.Symbols;
|
||||||
return Entry.Symbols.get<MCSymbol*>();
|
|
||||||
return (*Entry.Symbols.get<std::vector<MCSymbol*>*>())[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, this is a new entry, create a new symbol for it and add an
|
// Otherwise, this is a new entry, create a new symbol for it and add an
|
||||||
@ -118,30 +108,10 @@ MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) {
|
|||||||
BBCallbacks.back().setMap(this);
|
BBCallbacks.back().setMap(this);
|
||||||
Entry.Index = BBCallbacks.size() - 1;
|
Entry.Index = BBCallbacks.size() - 1;
|
||||||
Entry.Fn = BB->getParent();
|
Entry.Fn = BB->getParent();
|
||||||
MCSymbol *Result = Context.createTempSymbol();
|
Entry.Symbols.push_back(Context.createTempSymbol());
|
||||||
Entry.Symbols = Result;
|
return Entry.Symbols;
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MCSymbol*>
|
|
||||||
MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
|
|
||||||
assert(BB->hasAddressTaken() &&
|
|
||||||
"Shouldn't get label for block without address taken");
|
|
||||||
AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
|
|
||||||
|
|
||||||
std::vector<MCSymbol*> Result;
|
|
||||||
|
|
||||||
// If we already had an entry for this block, just return it.
|
|
||||||
if (Entry.Symbols.isNull())
|
|
||||||
Result.push_back(getAddrLabelSymbol(BB));
|
|
||||||
else if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>())
|
|
||||||
Result.push_back(Sym);
|
|
||||||
else
|
|
||||||
Result = *Entry.Symbols.get<std::vector<MCSymbol*>*>();
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
|
/// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
|
||||||
/// them.
|
/// them.
|
||||||
void MMIAddrLabelMap::
|
void MMIAddrLabelMap::
|
||||||
@ -162,16 +132,15 @@ void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
|
|||||||
// If the block got deleted, there is no need for the symbol. If the symbol
|
// 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
|
// was already emitted, we can just forget about it, otherwise we need to
|
||||||
// queue it up for later emission when the function is output.
|
// queue it up for later emission when the function is output.
|
||||||
AddrLabelSymEntry Entry = AddrLabelSymbols[BB];
|
AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
|
||||||
AddrLabelSymbols.erase(BB);
|
AddrLabelSymbols.erase(BB);
|
||||||
assert(!Entry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
|
assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
|
||||||
BBCallbacks[Entry.Index] = nullptr; // Clear the callback.
|
BBCallbacks[Entry.Index] = nullptr; // Clear the callback.
|
||||||
|
|
||||||
assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
|
assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
|
||||||
"Block/parent mismatch");
|
"Block/parent mismatch");
|
||||||
|
|
||||||
// Handle both the single and the multiple symbols cases.
|
for (MCSymbol *Sym : Entry.Symbols) {
|
||||||
if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>()) {
|
|
||||||
if (Sym->isDefined())
|
if (Sym->isDefined())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -180,64 +149,29 @@ void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
|
|||||||
// for the containing Function. Since the block is being deleted, its
|
// for the containing Function. Since the block is being deleted, its
|
||||||
// parent may already be removed, we have to get the function from 'Entry'.
|
// parent may already be removed, we have to get the function from 'Entry'.
|
||||||
DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
|
DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
|
||||||
} else {
|
|
||||||
std::vector<MCSymbol*> *Syms = Entry.Symbols.get<std::vector<MCSymbol*>*>();
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = Syms->size(); i != e; ++i) {
|
|
||||||
MCSymbol *Sym = (*Syms)[i];
|
|
||||||
if (Sym->isDefined()) continue; // Ignore already emitted labels.
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The entry is deleted, free the memory associated with the symbol list.
|
|
||||||
delete Syms;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
|
void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
|
||||||
// Get the entry for the RAUW'd block and remove it from our map.
|
// Get the entry for the RAUW'd block and remove it from our map.
|
||||||
AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old];
|
AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
|
||||||
AddrLabelSymbols.erase(Old);
|
AddrLabelSymbols.erase(Old);
|
||||||
assert(!OldEntry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
|
assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
|
||||||
|
|
||||||
AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
|
AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
|
||||||
|
|
||||||
// If New is not address taken, just move our symbol over to it.
|
// If New is not address taken, just move our symbol over to it.
|
||||||
if (NewEntry.Symbols.isNull()) {
|
if (NewEntry.Symbols.empty()) {
|
||||||
BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
|
BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
|
||||||
NewEntry = OldEntry; // Set New's entry.
|
NewEntry = std::move(OldEntry); // Set New's entry.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
|
BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
|
||||||
|
|
||||||
// Otherwise, we need to add the old symbol to the new block's set. If it is
|
// Otherwise, we need to add the old symbols to the new block's set.
|
||||||
// just a single entry, upgrade it to a symbol list.
|
NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(),
|
||||||
if (MCSymbol *PrevSym = NewEntry.Symbols.dyn_cast<MCSymbol*>()) {
|
OldEntry.Symbols.end());
|
||||||
std::vector<MCSymbol*> *SymList = new std::vector<MCSymbol*>();
|
|
||||||
SymList->push_back(PrevSym);
|
|
||||||
NewEntry.Symbols = SymList;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<MCSymbol*> *SymList =
|
|
||||||
NewEntry.Symbols.get<std::vector<MCSymbol*>*>();
|
|
||||||
|
|
||||||
// If the old entry was a single symbol, add it.
|
|
||||||
if (MCSymbol *Sym = OldEntry.Symbols.dyn_cast<MCSymbol*>()) {
|
|
||||||
SymList->push_back(Sym);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, concatenate the list.
|
|
||||||
std::vector<MCSymbol*> *Syms =OldEntry.Symbols.get<std::vector<MCSymbol*>*>();
|
|
||||||
SymList->insert(SymList->end(), Syms->begin(), Syms->end());
|
|
||||||
delete Syms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -320,22 +254,11 @@ void MachineModuleInfo::EndFunction() {
|
|||||||
|
|
||||||
//===- Address of Block Management ----------------------------------------===//
|
//===- Address of Block Management ----------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
/// getAddrLabelSymbol - Return the symbol to be used for the specified basic
|
|
||||||
/// block when its address is taken. This cannot be its normal LBB label
|
|
||||||
/// because the block may be accessed outside its containing function.
|
|
||||||
MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) {
|
|
||||||
// Lazily create AddrLabelSymbols.
|
|
||||||
if (!AddrLabelSymbols)
|
|
||||||
AddrLabelSymbols = new MMIAddrLabelMap(Context);
|
|
||||||
return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
|
/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
|
||||||
/// basic block when its address is taken. If other blocks were RAUW'd to
|
/// basic block when its address is taken. If other blocks were RAUW'd to
|
||||||
/// this one, we may have to emit them as well, return the whole set.
|
/// this one, we may have to emit them as well, return the whole set.
|
||||||
std::vector<MCSymbol*> MachineModuleInfo::
|
ArrayRef<MCSymbol *>
|
||||||
getAddrLabelSymbolToEmit(const BasicBlock *BB) {
|
MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
|
||||||
// Lazily create AddrLabelSymbols.
|
// Lazily create AddrLabelSymbols.
|
||||||
if (!AddrLabelSymbols)
|
if (!AddrLabelSymbols)
|
||||||
AddrLabelSymbols = new MMIAddrLabelMap(Context);
|
AddrLabelSymbols = new MMIAddrLabelMap(Context);
|
||||||
|
Reference in New Issue
Block a user