Change some methods in MCDwarf.cpp to be able to handle an arbitrary
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 19 Nov 2010 02:26:16 +0000 (02:26 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 19 Nov 2010 02:26:16 +0000 (02:26 +0000)
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

include/llvm/MC/MCDwarf.h
include/llvm/MC/MCStreamer.h
include/llvm/Target/TargetMachine.h
lib/CodeGen/LLVMTargetMachine.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCDwarf.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCMachOStreamer.cpp
lib/Target/TargetMachine.cpp

index 6bcb751a2d1002ae086cfe1c79d49100534e11ac..425535d3648977a107f96a20454573dba2c643a1 100644 (file)
@@ -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.
index 2505d4d53a97f55f42a42eea26cfe64a9bfb7fbe..55dc6f102b6b3b9ea7c80da03923ee8b6879e130 100644 (file)
@@ -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.
   ///
index 01dc1b0c41496515635a70538509435d25a455a8..11d2a142579e575653787be872317893c722c739 100644 (file)
@@ -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();
index 0abbe72e9b3a750214e31944852c37d5839138c3..5954f62da954ec823d95421387b05f29dc9ac1f2 100644 (file)
@@ -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: {
index a9cf4b163dd6dee5ceaf885f12aefce15897f4e3..b3c47367056d3d7ac1e33013625805c0724dcab7 100644 (file)
@@ -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);
 }
index 679f4eeec1f9a43267c90b9d0522ef2504bc610a..1462d5740283eea813b190e9b79bd5d294cb23e5 100644 (file)
@@ -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);
index 75e58de3199ab4ce629d4773ae03cccfc6949527..cac48170642d7fb3b1ab0a7bea279003c01098d2 100644 (file)
@@ -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(),
index 67a144a3412062ab7b79edcec016ecdaed239cc1..3236432fb8d8962dae899f2f0850077836176750 100644 (file)
@@ -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
index 705b1c097e55fcfb6f70cfb2029182dba20121b9..c4790a289937f8deae6cbdc91fb7054e0476e99a 100644 (file)
@@ -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)