Separate out the DWARF address pool into its own type/files.

llvm-svn: 207022
This commit is contained in:
David Blaikie 2014-04-23 21:04:59 +00:00
parent be55888849
commit e226b08ee9
7 changed files with 87 additions and 54 deletions

View File

@ -0,0 +1,36 @@
#include "AddressPool.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
using namespace llvm;
class MCExpr;
unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
auto IterBool =
Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS)));
return IterBool.first->second.Number;
}
// Emit addresses into the section given.
void AddressPool::emit(AsmPrinter &Asm, const MCSection *AddrSection) {
if (Pool.empty())
return;
// Start the dwarf addr section.
Asm.OutStreamer.SwitchSection(AddrSection);
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(Pool.size());
for (const auto &I : Pool)
Entries[I.second.Number] =
I.second.TLS
? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
: MCSymbolRefExpr::Create(I.first, Asm.OutContext);
for (const MCExpr *Entry : Entries)
Asm.OutStreamer.EmitValue(Entry, Asm.getDataLayout().getPointerSize());
}

View File

@ -0,0 +1,39 @@
//===-- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -----*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef CODEGEN_ASMPRINTER_ADDRESSPOOL_H__
#define CODEGEN_ASMPRINTER_ADDRESSPOOL_H__
#include "llvm/ADT/DenseMap.h"
namespace llvm {
class MCSection;
class MCSymbol;
class AsmPrinter;
// Collection of addresses for this unit and assorted labels.
// A Symbol->unsigned mapping of addresses used by indirect
// references.
class AddressPool {
struct AddressPoolEntry {
unsigned Number;
bool TLS;
AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
};
DenseMap<const MCSymbol *, AddressPoolEntry> Pool;
public:
/// \brief Returns the index into the address pool with the given
/// label/symbol.
unsigned getIndex(const MCSymbol *Sym, bool TLS = false);
void emit(AsmPrinter &Asm, const MCSection *AddrSection);
bool isEmpty() { return Pool.empty(); }
};
}
#endif

View File

@ -1,4 +1,5 @@
add_llvm_library(LLVMAsmPrinter add_llvm_library(LLVMAsmPrinter
AddressPool.cpp
ARMException.cpp ARMException.cpp
AsmPrinter.cpp AsmPrinter.cpp
AsmPrinterDwarf.cpp AsmPrinterDwarf.cpp

View File

@ -888,7 +888,7 @@ void DwarfDebug::finalizeModuleInfo() {
// We don't keep track of which addresses are used in which CU so this // We don't keep track of which addresses are used in which CU so this
// is a bit pessimistic under LTO. // is a bit pessimistic under LTO.
if (!InfoHolder.getAddrPool()->empty()) if (!InfoHolder.getAddressPool().isEmpty())
addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(), addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(),
dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym, dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym,
DwarfAddrSectionSym); DwarfAddrSectionSym);
@ -1019,7 +1019,8 @@ void DwarfDebug::endModule() {
emitDebugAbbrevDWO(); emitDebugAbbrevDWO();
emitDebugLineDWO(); emitDebugLineDWO();
// Emit DWO addresses. // Emit DWO addresses.
InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection()); InfoHolder.getAddressPool().emit(
*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
emitDebugLocDWO(); emitDebugLocDWO();
} else } else
// Emit info into a debug loc section. // Emit info into a debug loc section.
@ -2204,7 +2205,7 @@ void DwarfDebug::emitDebugLocDWO() {
// address we know we've emitted elsewhere (the start of the function? // address we know we've emitted elsewhere (the start of the function?
// The start of the CU or CU subrange that encloses this range?) // The start of the CU or CU subrange that encloses this range?)
Asm->EmitInt8(dwarf::DW_LLE_start_length_entry); Asm->EmitInt8(dwarf::DW_LLE_start_length_entry);
unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym()); unsigned idx = InfoHolder.getAddressPool().getIndex(Entry.getBeginSym());
Asm->EmitULEB128(idx); Asm->EmitULEB128(idx);
Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4); Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4);

View File

@ -48,12 +48,6 @@ unsigned DwarfFile::getStringPoolIndex(StringRef Str) {
return Entry.second; return Entry.second;
} }
unsigned DwarfFile::getAddrPoolIndex(const MCSymbol *Sym, bool TLS) {
std::pair<AddrPool::iterator, bool> P = AddressPool.insert(
std::make_pair(Sym, AddressPoolEntry(AddressPool.size(), TLS)));
return P.first->second.Number;
}
// Define a unique number for the abbreviation. // Define a unique number for the abbreviation.
// //
void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) { void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) {
@ -218,26 +212,4 @@ void DwarfFile::emitStrings(const MCSection *StrSection,
} }
} }
} }
// Emit addresses into the section given.
void DwarfFile::emitAddresses(const MCSection *AddrSection) {
if (AddressPool.empty())
return;
// Start the dwarf addr section.
Asm->OutStreamer.SwitchSection(AddrSection);
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(AddressPool.size());
for (const auto &I : AddressPool)
Entries[I.second.Number] =
I.second.TLS
? Asm->getObjFileLowering().getDebugThreadLocalSymbol(I.first)
: MCSymbolRefExpr::Create(I.first, Asm->OutContext);
for (const MCExpr *Entry : Entries)
Asm->OutStreamer.EmitValue(Entry, Asm->getDataLayout().getPointerSize());
}
} }

View File

@ -15,6 +15,7 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "AddressPool.h"
#include <vector> #include <vector>
#include <string> #include <string>
@ -51,17 +52,7 @@ class DwarfFile {
unsigned NextStringPoolNumber; unsigned NextStringPoolNumber;
std::string StringPref; std::string StringPref;
struct AddressPoolEntry { AddressPool AddrPool;
unsigned Number;
bool TLS;
AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
};
// Collection of addresses for this unit and assorted labels.
// A Symbol->unsigned mapping of addresses used by indirect
// references.
typedef DenseMap<const MCSymbol *, AddressPoolEntry> AddrPool;
AddrPool AddressPool;
public: public:
DwarfFile(AsmPrinter *AP, const char *Pref, BumpPtrAllocator &DA); DwarfFile(AsmPrinter *AP, const char *Pref, BumpPtrAllocator &DA);
@ -93,9 +84,6 @@ public:
const MCSection *OffsetSection = nullptr, const MCSection *OffsetSection = nullptr,
const MCSymbol *StrSecSym = nullptr); const MCSymbol *StrSecSym = nullptr);
/// \brief Emit all of the addresses to the section given.
void emitAddresses(const MCSection *AddrSection);
/// \brief Returns the entry into the start of the pool. /// \brief Returns the entry into the start of the pool.
MCSymbol *getStringPoolSym(); MCSymbol *getStringPoolSym();
@ -110,12 +98,7 @@ public:
/// \brief Returns the string pool. /// \brief Returns the string pool.
StrPool *getStringPool() { return &StringPool; } StrPool *getStringPool() { return &StringPool; }
/// \brief Returns the index into the address pool with the given AddressPool &getAddressPool() { return AddrPool; }
/// label/symbol.
unsigned getAddrPoolIndex(const MCSymbol *Sym, bool TLS = false);
/// \brief Returns the address pool.
AddrPool *getAddrPool() { return &AddressPool; }
}; };
} }
#endif #endif

View File

@ -290,7 +290,7 @@ void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
if (Label) if (Label)
DD->addArangeLabel(SymbolCU(this, Label)); DD->addArangeLabel(SymbolCU(this, Label));
unsigned idx = DU->getAddrPoolIndex(Label); unsigned idx = DU->getAddressPool().getIndex(Label);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx); DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value); Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
} }
@ -335,7 +335,8 @@ void DwarfUnit::addOpAddress(DIELoc *Die, const MCSymbol *Sym) {
addLabel(Die, dwarf::DW_FORM_udata, Sym); addLabel(Die, dwarf::DW_FORM_udata, Sym);
} else { } else {
addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index); addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
addUInt(Die, dwarf::DW_FORM_GNU_addr_index, DU->getAddrPoolIndex(Sym)); addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
DU->getAddressPool().getIndex(Sym));
} }
} }
@ -1668,7 +1669,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
} else { } else {
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index); addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
addUInt(Loc, dwarf::DW_FORM_udata, addUInt(Loc, dwarf::DW_FORM_udata,
DU->getAddrPoolIndex(Sym, /* TLS */ true)); DU->getAddressPool().getIndex(Sym, /* TLS */ true));
} }
// 3) followed by a custom OP to make the debugger do a TLS lookup. // 3) followed by a custom OP to make the debugger do a TLS lookup.
addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);