aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--include/llvm/MC/MCDwarf.h7
-rw-r--r--include/llvm/MC/MCStreamer.h9
-rw-r--r--include/llvm/Target/TargetMachine.h7
-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
9 files changed, 128 insertions, 43 deletions
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 6bcb751a2d..425535d364 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -167,7 +167,7 @@ namespace llvm {
// This is called when an instruction is assembled into the specified
// section and if there is information from the last .loc directive that
// has yet to have a line entry made for it is made.
- static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
+ static void Make(MCStreamer *MCOS, const MCSection *Section);
};
/// MCLineSection - Instances of this class represent the line information
@@ -205,7 +205,8 @@ namespace llvm {
//
// This emits the Dwarf file and the line tables.
//
- static void Emit(MCObjectStreamer *MCOS, const MCSection *DwarfLineSection);
+ static void Emit(MCStreamer *MCOS, const MCSection *DwarfLineSection,
+ MCSectionData *DLS, int PointerSize);
};
class MCDwarfLineAddr {
@@ -214,7 +215,7 @@ namespace llvm {
static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
/// Utility function to emit the encoding to a streamer.
- static void Emit(MCObjectStreamer *MCOS,
+ static void Emit(MCStreamer *MCOS,
int64_t LineDelta,uint64_t AddrDelta);
/// Utility function to compute the size of the encoding.
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 2505d4d53a..55dc6f102b 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -28,6 +28,7 @@ namespace llvm {
class MCSymbol;
class StringRef;
class TargetAsmBackend;
+ class TargetLoweringObjectFile;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
@@ -388,6 +389,14 @@ namespace llvm {
MCCodeEmitter *CE = 0,
bool ShowInst = false);
+ MCStreamer *createAsmStreamerNoLoc(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isLittleEndian, bool isVerboseAsm,
+ const TargetLoweringObjectFile *TLOF,
+ int PointerSize,
+ MCInstPrinter *InstPrint = 0,
+ MCCodeEmitter *CE = 0,
+ bool ShowInst = false);
+
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
///
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 01dc1b0c41..11d2a14257 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -104,6 +104,7 @@ protected: // Can only create subclasses.
const MCAsmInfo *AsmInfo;
unsigned MCRelaxAll : 1;
+ unsigned MCUseLoc : 1;
public:
virtual ~TargetMachine();
@@ -169,6 +170,12 @@ public:
/// relaxed.
void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
+ /// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
+ bool hasMCUseLoc() const { return MCUseLoc; }
+
+ /// setMCUseLoc - Set whether all we should use dwarf's .loc directive.
+ void setMCUseLoc(bool Value) { MCUseLoc = Value; }
+
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
static Reloc::Model getRelocationModel();
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)