summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h3
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp78
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp124
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h4
4 files changed, 106 insertions, 103 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 939324976d..56dae2c514 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -24,6 +24,7 @@
namespace llvm {
class AsmPrinterHandler;
class BlockAddress;
+ class ByteStreamer;
class GCStrategy;
class Constant;
class ConstantArray;
@@ -429,7 +430,7 @@ namespace llvm {
virtual unsigned getISAEncoding() { return 0; }
/// EmitDwarfRegOp - Emit dwarf register operation.
- virtual void EmitDwarfRegOp(const MachineLocation &MLoc,
+ virtual void EmitDwarfRegOp(ByteStreamer &BS, const MachineLocation &MLoc,
bool Indirect) const;
//===------------------------------------------------------------------===//
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 3741ef0398..338ed4cdae 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
+#include "ByteStreamer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/Twine.h"
@@ -185,58 +186,47 @@ void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
}
/// Emit a dwarf register operation.
-static void emitDwarfRegOp(const AsmPrinter &AP, int Reg) {
+static void emitDwarfRegOp(ByteStreamer &Streamer, int Reg) {
assert(Reg >= 0);
if (Reg < 32) {
- AP.OutStreamer.AddComment(
- dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
- AP.EmitInt8(dwarf::DW_OP_reg0 + Reg);
+ Streamer.EmitInt8(dwarf::DW_OP_reg0 + Reg,
+ dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
} else {
- AP.OutStreamer.AddComment("DW_OP_regx");
- AP.EmitInt8(dwarf::DW_OP_regx);
- AP.OutStreamer.AddComment(Twine(Reg));
- AP.EmitULEB128(Reg);
+ Streamer.EmitInt8(dwarf::DW_OP_regx, "DW_OP_regx");
+ Streamer.EmitULEB128(Reg, Twine(Reg));
}
}
/// Emit an (double-)indirect dwarf register operation.
-static void emitDwarfRegOpIndirect(const AsmPrinter &AP, int Reg, int Offset,
+static void emitDwarfRegOpIndirect(ByteStreamer &Streamer, int Reg, int Offset,
bool Deref) {
assert(Reg >= 0);
if (Reg < 32) {
- AP.OutStreamer.AddComment(
- dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
- AP.EmitInt8(dwarf::DW_OP_breg0 + Reg);
+ Streamer.EmitInt8(dwarf::DW_OP_breg0 + Reg,
+ dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
} else {
- AP.OutStreamer.AddComment("DW_OP_bregx");
- AP.EmitInt8(dwarf::DW_OP_bregx);
- AP.OutStreamer.AddComment(Twine(Reg));
- AP.EmitULEB128(Reg);
+ Streamer.EmitInt8(dwarf::DW_OP_bregx, "DW_OP_bregx");
+ Streamer.EmitULEB128(Reg, Twine(Reg));
}
- AP.EmitSLEB128(Offset);
+ Streamer.EmitSLEB128(Offset);
if (Deref)
- AP.EmitInt8(dwarf::DW_OP_deref);
+ Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");
}
/// Emit a dwarf register operation for describing
/// - a small value occupying only part of a register or
/// - a small register representing only part of a value.
-static void emitDwarfOpPiece(const AsmPrinter &AP, unsigned Size,
+static void emitDwarfOpPiece(ByteStreamer &Streamer, unsigned Size,
unsigned Offset) {
assert(Size > 0);
if (Offset > 0) {
- AP.OutStreamer.AddComment("DW_OP_bit_piece");
- AP.EmitInt8(dwarf::DW_OP_bit_piece);
- AP.OutStreamer.AddComment(Twine(Size));
- AP.EmitULEB128(Size);
- AP.OutStreamer.AddComment(Twine(Offset));
- AP.EmitULEB128(Offset);
+ Streamer.EmitInt8(dwarf::DW_OP_bit_piece, "DW_OP_bit_piece");
+ Streamer.EmitULEB128(Size, Twine(Size));
+ Streamer.EmitULEB128(Offset, Twine(Offset));
} else {
- AP.OutStreamer.AddComment("DW_OP_piece");
- AP.EmitInt8(dwarf::DW_OP_piece);
+ Streamer.EmitInt8(dwarf::DW_OP_piece, "DW_OP_piece");
unsigned ByteSize = Size / 8; // Assuming 8 bits per byte.
- AP.OutStreamer.AddComment(Twine(ByteSize));
- AP.EmitULEB128(ByteSize);
+ Streamer.EmitULEB128(ByteSize, Twine(ByteSize));
}
}
@@ -244,7 +234,7 @@ static void emitDwarfOpPiece(const AsmPrinter &AP, unsigned Size,
/// register. This function attempts to emit a dwarf register by
/// emitting a piece of a super-register or by piecing together
/// multiple subregisters that alias the register.
-static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
+static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
const MachineLocation &MLoc) {
assert(!MLoc.isIndirect());
const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
@@ -259,8 +249,8 @@ static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
unsigned Size = TRI->getSubRegIdxSize(Idx);
unsigned Offset = TRI->getSubRegIdxOffset(Idx);
AP.OutStreamer.AddComment("super-register");
- emitDwarfRegOp(AP, Reg);
- emitDwarfOpPiece(AP, Size, Offset);
+ emitDwarfRegOp(Streamer, Reg);
+ emitDwarfOpPiece(Streamer, Size, Offset);
return;
}
}
@@ -292,8 +282,8 @@ static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
// its range, emit a DWARF piece for it.
if (Reg >= 0 && Intersection.any()) {
AP.OutStreamer.AddComment("sub-register");
- emitDwarfRegOp(AP, Reg);
- emitDwarfOpPiece(AP, Size, Offset == CurPos ? 0 : Offset);
+ emitDwarfRegOp(Streamer, Reg);
+ emitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset);
CurPos = Offset + Size;
// Mark it as emitted.
@@ -303,13 +293,14 @@ static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
if (CurPos == 0) {
// FIXME: We have no reasonable way of handling errors in here.
- AP.OutStreamer.AddComment("nop (could not find a dwarf register number)");
- AP.EmitInt8(dwarf::DW_OP_nop);
+ Streamer.EmitInt8(dwarf::DW_OP_nop,
+ "nop (could not find a dwarf register number)");
}
}
/// EmitDwarfRegOp - Emit dwarf register operation.
-void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
+void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
+ const MachineLocation &MLoc,
bool Indirect) const {
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
@@ -320,23 +311,22 @@ void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
// caller might be in the middle of a dwarf expression. We should
// probably assert that Reg >= 0 once debug info generation is more
// mature.
- OutStreamer.AddComment(
- "nop (invalid dwarf register number for indirect loc)");
- EmitInt8(dwarf::DW_OP_nop);
+ Streamer.EmitInt8(dwarf::DW_OP_nop,
+ "nop (invalid dwarf register number for indirect loc)");
return;
}
// Attempt to find a valid super- or sub-register.
if (!Indirect && !MLoc.isIndirect())
- return EmitDwarfRegOpPiece(*this, MLoc);
+ return EmitDwarfRegOpPiece(Streamer, *this, MLoc);
}
if (MLoc.isIndirect())
- emitDwarfRegOpIndirect(*this, Reg, MLoc.getOffset(), Indirect);
+ emitDwarfRegOpIndirect(Streamer, Reg, MLoc.getOffset(), Indirect);
else if (Indirect)
- emitDwarfRegOpIndirect(*this, Reg, 0, false);
+ emitDwarfRegOpIndirect(Streamer, Reg, 0, false);
else
- emitDwarfRegOp(*this, Reg);
+ emitDwarfRegOp(Streamer, Reg);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 81934e1729..dab3c194c1 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dwarfdebug"
+#include "ByteStreamer.h"
#include "DwarfDebug.h"
#include "DIE.h"
#include "DIEHash.h"
@@ -2395,6 +2396,65 @@ void DwarfDebug::emitDebugStr() {
Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection());
}
+void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
+ const DotDebugLocEntry &Entry) {
+ DIVariable DV(Entry.getVariable());
+ if (Entry.isInt()) {
+ DIBasicType BTy(DV.getType());
+ if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
+ BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
+ Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts");
+ Streamer.EmitSLEB128(Entry.getInt());
+ } else {
+ Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu");
+ Streamer.EmitULEB128(Entry.getInt());
+ }
+ } else if (Entry.isLocation()) {
+ MachineLocation Loc = Entry.getLoc();
+ if (!DV.hasComplexAddress())
+ // Regular entry.
+ Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
+ else {
+ // Complex address entry.
+ unsigned N = DV.getNumAddrElements();
+ unsigned i = 0;
+ if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
+ if (Loc.getOffset()) {
+ i = 2;
+ Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
+ Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");
+ Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst");
+ Streamer.EmitSLEB128(DV.getAddrElement(1));
+ } else {
+ // If first address element is OpPlus then emit
+ // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
+ MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1));
+ Asm->EmitDwarfRegOp(Streamer, TLoc, DV.isIndirect());
+ i = 2;
+ }
+ } else {
+ Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
+ }
+
+ // Emit remaining complex address elements.
+ for (; i < N; ++i) {
+ uint64_t Element = DV.getAddrElement(i);
+ if (Element == DIBuilder::OpPlus) {
+ Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst");
+ Streamer.EmitULEB128(DV.getAddrElement(++i));
+ } else if (Element == DIBuilder::OpDeref) {
+ if (!Loc.isReg())
+ Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");
+ } else
+ llvm_unreachable("unknown Opcode found in complex address");
+ }
+ }
+ }
+ // else ... ignore constant fp. There is not any good way to
+ // to represent them here in dwarf.
+ // FIXME: ^
+}
+
// Emit locations into the debug loc section.
void DwarfDebug::emitDebugLoc() {
if (DotDebugLocEntries.empty())
@@ -2422,76 +2482,24 @@ void DwarfDebug::emitDebugLoc() {
const DotDebugLocEntry &Entry = *I;
if (Entry.isMerged())
continue;
+
if (Entry.isEmpty()) {
Asm->OutStreamer.EmitIntValue(0, Size);
Asm->OutStreamer.EmitIntValue(0, Size);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
} else {
+ // Set up the range.
Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size);
Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size);
- DIVariable DV(Entry.getVariable());
Asm->OutStreamer.AddComment("Loc expr size");
MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();
MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
Asm->EmitLabelDifference(end, begin, 2);
Asm->OutStreamer.EmitLabel(begin);
- if (Entry.isInt()) {
- DIBasicType BTy(DV.getType());
- if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
- BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
- Asm->OutStreamer.AddComment("DW_OP_consts");
- Asm->EmitInt8(dwarf::DW_OP_consts);
- Asm->EmitSLEB128(Entry.getInt());
- } else {
- Asm->OutStreamer.AddComment("DW_OP_constu");
- Asm->EmitInt8(dwarf::DW_OP_constu);
- Asm->EmitULEB128(Entry.getInt());
- }
- } else if (Entry.isLocation()) {
- MachineLocation Loc = Entry.getLoc();
- if (!DV.hasComplexAddress())
- // Regular entry.
- Asm->EmitDwarfRegOp(Loc, DV.isIndirect());
- else {
- // Complex address entry.
- unsigned N = DV.getNumAddrElements();
- unsigned i = 0;
- if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
- if (Loc.getOffset()) {
- i = 2;
- Asm->EmitDwarfRegOp(Loc, DV.isIndirect());
- Asm->OutStreamer.AddComment("DW_OP_deref");
- Asm->EmitInt8(dwarf::DW_OP_deref);
- Asm->OutStreamer.AddComment("DW_OP_plus_uconst");
- Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
- Asm->EmitSLEB128(DV.getAddrElement(1));
- } else {
- // If first address element is OpPlus then emit
- // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
- MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1));
- Asm->EmitDwarfRegOp(TLoc, DV.isIndirect());
- i = 2;
- }
- } else {
- Asm->EmitDwarfRegOp(Loc, DV.isIndirect());
- }
-
- // Emit remaining complex address elements.
- for (; i < N; ++i) {
- uint64_t Element = DV.getAddrElement(i);
- if (Element == DIBuilder::OpPlus) {
- Asm->EmitInt8(dwarf::DW_OP_plus_uconst);
- Asm->EmitULEB128(DV.getAddrElement(++i));
- } else if (Element == DIBuilder::OpDeref) {
- if (!Loc.isReg())
- Asm->EmitInt8(dwarf::DW_OP_deref);
- } else
- llvm_unreachable("unknown Opcode found in complex address");
- }
- }
- }
- // else ... ignore constant fp. There is not any good way to
- // to represent them here in dwarf.
+ // Emit the entry.
+ APByteStreamer Streamer(*Asm);
+ emitDebugLocEntry(Streamer, Entry);
+ // Close the range.
Asm->OutStreamer.EmitLabel(end);
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 1373e96d00..0dadb73562 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -31,6 +31,7 @@
namespace llvm {
+class ByteStreamer;
class DwarfUnit;
class DwarfCompileUnit;
class ConstantInt;
@@ -587,6 +588,9 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Emit visible names into a debug str section.
void emitDebugStr();
+ /// \brief Emit an entry for the debug loc section.
+ void emitDebugLocEntry(ByteStreamer &Streamer, const DotDebugLocEntry &Entry);
+
/// \brief Emit visible names into a debug loc section.
void emitDebugLoc();