diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-19 02:26:16 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-11-19 02:26:16 +0000 |
commit | 195a0ce484cd12a5adae9184188f6d0fb52b84c0 (patch) | |
tree | 75909dd2fcd8778aaf56da67446bf1b6f4615d9c /lib | |
parent | 602890dd8ef53c6e8d60a2752b97940f7a58de1a (diff) | |
download | llvm-195a0ce484cd12a5adae9184188f6d0fb52b84c0.tar.gz llvm-195a0ce484cd12a5adae9184188f6d0fb52b84c0.tar.bz2 llvm-195a0ce484cd12a5adae9184188f6d0fb52b84c0.tar.xz |
Change some methods in MCDwarf.cpp to be able to handle an arbitrary
MCStreamer instead of just MCObjectStreamer. Address changes cannot
be as efficient as we have to use DW_LNE_set_addres, but at least
most of the logic is shared.
This will be used so that, with CodeGen still using EmitDwarfLocDirective,
llvm-gcc is able to produce debug_line sections without needing an
assembler that supports .loc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119777 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 28 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 48 | ||||
-rw-r--r-- | lib/MC/MCDwarf.cpp | 59 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 5 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 5 | ||||
-rw-r--r-- | lib/Target/TargetMachine.cpp | 3 |
6 files changed, 108 insertions, 40 deletions
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 0abbe72e9b..5954f62da9 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCStreamer.h" @@ -144,11 +145,28 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, if (ShowMCEncoding) MCE = getTarget().createCodeEmitter(*this, *Context); - AsmStreamer.reset(getTarget().createAsmStreamer(*Context, Out, - getTargetData()->isLittleEndian(), - getVerboseAsm(), - InstPrinter, MCE, - ShowMCInst)); + const TargetLoweringObjectFile &TLOF = + getTargetLowering()->getObjFileLowering(); + int PointerSize = getTargetData()->getPointerSize(); + + MCStreamer *S; + if (hasMCUseLoc()) + S = getTarget().createAsmStreamer(*Context, Out, + getTargetData()->isLittleEndian(), + getVerboseAsm(), + InstPrinter, + MCE, + ShowMCInst); + else + S = createAsmStreamerNoLoc(*Context, Out, + getTargetData()->isLittleEndian(), + getVerboseAsm(), + &TLOF, + PointerSize, + InstPrinter, + MCE, + ShowMCInst); + AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index a9cf4b163d..b3c4736705 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetLoweringObjectFile.h" using namespace llvm; namespace { @@ -36,16 +37,21 @@ class MCAsmStreamer : public MCStreamer { SmallString<128> CommentToEmit; raw_svector_ostream CommentStream; + const TargetLoweringObjectFile *TLOF; + int PointerSize; + unsigned IsLittleEndian : 1; unsigned IsVerboseAsm : 1; unsigned ShowInst : 1; public: MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, - bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer, - MCCodeEmitter *emitter, bool showInst) + bool isLittleEndian, bool isVerboseAsm, + const TargetLoweringObjectFile *tlof, int pointerSize, + MCInstPrinter *printer, MCCodeEmitter *emitter, bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), CommentStream(CommentToEmit), + TLOF(tlof), PointerSize(pointerSize), IsLittleEndian(isLittleEndian), IsVerboseAsm(isVerboseAsm), ShowInst(showInst) { if (InstPrinter && IsVerboseAsm) @@ -637,9 +643,11 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { } bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){ - OS << "\t.file\t" << FileNo << ' '; - PrintQuotedString(Filename, OS); - EmitEOL(); + if (!TLOF) { + OS << "\t.file\t" << FileNo << ' '; + PrintQuotedString(Filename, OS); + EmitEOL(); + } return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename); } @@ -647,6 +655,11 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator) { + this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, + Isa, Discriminator); + if (TLOF) + return; + OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; if (Flags & DWARF2_FLAG_BASIC_BLOCK) OS << " basic_block"; @@ -670,8 +683,6 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, if (Discriminator) OS << "discriminator " << Discriminator; EmitEOL(); - return this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, - Isa, Discriminator); } void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { @@ -755,6 +766,9 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { assert(CurSection && "Cannot emit contents before setting section!"); + if (TLOF) + MCLineEntry::Make(this, getCurrentSection()); + // Show the encoding in a comment if we have a code emitter. if (Emitter) AddEncodingComment(Inst); @@ -784,6 +798,11 @@ void MCAsmStreamer::EmitRawText(StringRef String) { } void MCAsmStreamer::Finish() { + // Dump out the dwarf file & directory tables and line tables. + if (getContext().hasDwarfFiles() && TLOF) { + MCDwarfFileTable::Emit(this, TLOF->getDwarfLineSection(), NULL, + PointerSize); + } } MCStreamer *llvm::createAsmStreamer(MCContext &Context, @@ -792,5 +811,18 @@ MCStreamer *llvm::createAsmStreamer(MCContext &Context, bool isVerboseAsm, MCInstPrinter *IP, MCCodeEmitter *CE, bool ShowInst) { return new MCAsmStreamer(Context, OS, isLittleEndian, isVerboseAsm, - IP, CE, ShowInst); + NULL, 0, IP, CE, ShowInst); +} + + +MCStreamer *llvm::createAsmStreamerNoLoc(MCContext &Context, + formatted_raw_ostream &OS, + bool isLittleEndian, + bool isVerboseAsm, + const TargetLoweringObjectFile *TLOF, + int PointerSize, + MCInstPrinter *IP, + MCCodeEmitter *CE, bool ShowInst) { + return new MCAsmStreamer(Context, OS, isLittleEndian, isVerboseAsm, + TLOF, PointerSize, IP, CE, ShowInst); } diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 679f4eeec1..1462d57402 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -60,7 +60,7 @@ static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta) // and if there is information from the last .loc directive that has yet to have // a line entry made for it is made. // -void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { +void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) { if (!MCOS->getContext().getDwarfLocSeen()) return; @@ -99,7 +99,7 @@ void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { // // This helper routine returns an expression of End - Start + IntVal . // -static inline const MCExpr *MakeStartMinusEndExpr(MCObjectStreamer *MCOS, +static inline const MCExpr *MakeStartMinusEndExpr(MCStreamer *MCOS, MCSymbol *Start, MCSymbol *End, int IntVal) { MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; @@ -120,33 +120,33 @@ static inline const MCExpr *MakeStartMinusEndExpr(MCObjectStreamer *MCOS, // This emits an "absolute" address used in the start of a dwarf line number // table. This will result in a relocatation entry for the address. // -static inline void EmitDwarfSetAddress(MCObjectStreamer *MCOS, - MCSymbol *Symbol) { +static inline void EmitDwarfSetAddress(MCStreamer *MCOS, + MCSymbol *Symbol, + int PointerSize) { MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); - int sizeof_address = MCOS->getAssembler().getBackend().getPointerSize(); - MCOS->EmitULEB128IntValue(sizeof_address + 1); + MCOS->EmitULEB128IntValue(PointerSize + 1); MCOS->EmitIntValue(dwarf::DW_LNE_set_address, 1); - MCOS->EmitSymbolValue(Symbol, sizeof_address); + MCOS->EmitSymbolValue(Symbol, PointerSize); } // // This emits the Dwarf line table for the specified section from the entries // in the LineSection. // -static inline void EmitDwarfLineTable(MCObjectStreamer *MCOS, +static inline void EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, MCLineSection *LineSection, - const MCSection *DwarfLineSection) { + const MCSection *DwarfLineSection, + MCSectionData *DLS, + int PointerSize) { unsigned FileNum = 1; unsigned LastLine = 1; unsigned Column = 0; unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; unsigned Isa = 0; MCSymbol *LastLabel = NULL; - MCSectionData &DLS = - MCOS->getAssembler().getOrCreateSectionData(*DwarfLineSection); // Loop through each MCLineEntry and encode the dwarf line number table. for (MCLineSection::iterator @@ -185,9 +185,9 @@ static inline void EmitDwarfLineTable(MCObjectStreamer *MCOS, // At this point we want to emit/create the sequence to encode the delta in // line numbers and the increment of the address from the previous Label // and the current Label. - if (LastLabel == NULL) { + if (LastLabel == NULL || DLS == NULL) { // emit the sequence to set the address - EmitDwarfSetAddress(MCOS, Label); + EmitDwarfSetAddress(MCOS, Label, PointerSize); // emit the sequence for the LineDelta (from 1) and a zero address delta. MCDwarfLineAddr::Emit(MCOS, LineDelta, 0); } @@ -196,7 +196,7 @@ static inline void EmitDwarfLineTable(MCObjectStreamer *MCOS, // this Label (plus 0). const MCExpr *AddrDelta = MakeStartMinusEndExpr(MCOS, LastLabel, Label,0); // Create a Dwarf Line fragment for the LineDelta and AddrDelta. - new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, &DLS); + new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, DLS); } LastLine = it->getLine(); @@ -218,19 +218,29 @@ static inline void EmitDwarfLineTable(MCObjectStreamer *MCOS, // Switch back the the dwarf line section. MCOS->SwitchSection(DwarfLineSection); - // Create an expression for the address delta from the LastLabel and this - // SectionEnd label. - const MCExpr *AddrDelta = MakeStartMinusEndExpr(MCOS, LastLabel, SectionEnd, - 0); - // Create a Dwarf Line fragment for the LineDelta and AddrDelta. - new MCDwarfLineAddrFragment(INT64_MAX, *AddrDelta, &DLS); + + if (DLS == NULL) { + // emit the sequence to set the address + EmitDwarfSetAddress(MCOS, SectionEnd, PointerSize); + // emit the sequence for the LineDelta (from 1) and a zero address delta. + MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0); + } else { + // Create an expression for the address delta from the LastLabel and this + // SectionEnd label. + const MCExpr *AddrDelta = MakeStartMinusEndExpr(MCOS, LastLabel, SectionEnd, + 0); + // Create a Dwarf Line fragment for the LineDelta and AddrDelta. + new MCDwarfLineAddrFragment(INT64_MAX, *AddrDelta, DLS); + } } // // This emits the Dwarf file and the line tables. // -void MCDwarfFileTable::Emit(MCObjectStreamer *MCOS, - const MCSection *DwarfLineSection) { +void MCDwarfFileTable::Emit(MCStreamer *MCOS, + const MCSection *DwarfLineSection, + MCSectionData *DLS, + int PointerSize) { // Switch to the section where the table will be emitted into. MCOS->SwitchSection(DwarfLineSection); @@ -315,7 +325,8 @@ void MCDwarfFileTable::Emit(MCObjectStreamer *MCOS, MCOS->getContext().getMCLineSections(); for (DenseMap<const MCSection *, MCLineSection *>::iterator it = MCLineSections.begin(), ie = MCLineSections.end(); it != ie; ++it) { - EmitDwarfLineTable(MCOS, it->first, it->second, DwarfLineSection); + EmitDwarfLineTable(MCOS, it->first, it->second, DwarfLineSection, DLS, + PointerSize); // Now delete the MCLineSections that were created in MCLineEntry::Make() // and used to emit the line table. @@ -345,7 +356,7 @@ void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta, } /// Utility function to emit the encoding to a streamer. -void MCDwarfLineAddr::Emit(MCObjectStreamer *MCOS, int64_t LineDelta, +void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta) { SmallString<256> Tmp; raw_svector_ostream OS(Tmp); diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 75e58de319..cac4817064 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -490,7 +490,10 @@ void MCELFStreamer::Finish() { const MCSection *DwarfLineSection = getContext().getELFSection(".debug_line", 0, 0, SectionKind::getDataRelLocal()); - MCDwarfFileTable::Emit(this, DwarfLineSection); + MCSectionData &DLS = + getAssembler().getOrCreateSectionData(*DwarfLineSection); + int PointerSize = getAssembler().getBackend().getPointerSize(); + MCDwarfFileTable::Emit(this, DwarfLineSection, &DLS, PointerSize); } for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 67a144a341..3236432fb8 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -414,7 +414,10 @@ void MCMachOStreamer::Finish() { "__debug_line", MCSectionMachO::S_ATTR_DEBUG, 0, SectionKind::getDataRelLocal()); - MCDwarfFileTable::Emit(this, DwarfLineSection); + MCSectionData &DLS = + getAssembler().getOrCreateSectionData(*DwarfLineSection); + int PointerSize = getAssembler().getBackend().getPointerSize(); + MCDwarfFileTable::Emit(this, DwarfLineSection, &DLS, PointerSize); } // We have to set the fragment atom associations so we can relax properly for diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 705b1c097e..c4790a2899 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -219,7 +219,8 @@ FunctionSections("ffunction-sections", TargetMachine::TargetMachine(const Target &T) : TheTarget(T), AsmInfo(0), - MCRelaxAll(false) { + MCRelaxAll(false), + MCUseLoc(true) { // Typically it will be subtargets that will adjust FloatABIType from Default // to Soft or Hard. if (UseSoftFloat) |