aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-11-19 02:26:16 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-11-19 02:26:16 +0000
commit195a0ce484cd12a5adae9184188f6d0fb52b84c0 (patch)
tree75909dd2fcd8778aaf56da67446bf1b6f4615d9c /lib
parent602890dd8ef53c6e8d60a2752b97940f7a58de1a (diff)
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.cpp28
-rw-r--r--lib/MC/MCAsmStreamer.cpp48
-rw-r--r--lib/MC/MCDwarf.cpp59
-rw-r--r--lib/MC/MCELFStreamer.cpp5
-rw-r--r--lib/MC/MCMachOStreamer.cpp5
-rw-r--r--lib/Target/TargetMachine.cpp3
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)