Make provision to have floating point constants in .debug_loc expressions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134702 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2011-07-08 16:49:43 +00:00
parent 3492a4af12
commit 80efd4e96b
2 changed files with 81 additions and 44 deletions

View File

@ -1449,11 +1449,20 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
DotDebugLocEntries. DotDebugLocEntries.
push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var)); push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var));
} }
// FIXME: Handle isFPImm also.
else if (Begin->getOperand(0).isImm()) { else if (Begin->getOperand(0).isImm()) {
DotDebugLocEntries. DotDebugLocEntries.
push_back(DotDebugLocEntry(FLabel, SLabel, push_back(DotDebugLocEntry(FLabel, SLabel,
Begin->getOperand(0).getImm())); Begin->getOperand(0).getImm()));
} else if (Begin->getOperand(0).isFPImm()) {
DotDebugLocEntries.
push_back(DotDebugLocEntry(FLabel, SLabel,
Begin->getOperand(0).getFPImm()));
} else if (Begin->getOperand(0).isCImm()) {
DotDebugLocEntries.
push_back(DotDebugLocEntry(FLabel, SLabel,
Begin->getOperand(0).getCImm()));
} else {
assert (0 && "Unexpected 3 operand DBG_VALUE instruction!");
} }
} else { } else {
MLoc = Asm->getDebugValueLocation(Begin); MLoc = Asm->getDebugValueLocation(Begin);
@ -2608,56 +2617,61 @@ void DwarfDebug::emitDebugLoc() {
MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol(); MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
Asm->EmitLabelDifference(end, begin, 2); Asm->EmitLabelDifference(end, begin, 2);
Asm->OutStreamer.EmitLabel(begin); Asm->OutStreamer.EmitLabel(begin);
if (Entry.isConstant()) { if (Entry.isInt()) {
DIBasicType BTy(DV.getType()); DIBasicType BTy(DV.getType());
if (BTy.Verify() && if (BTy.Verify() &&
(BTy.getEncoding() == dwarf::DW_ATE_signed (BTy.getEncoding() == dwarf::DW_ATE_signed
|| BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { || BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
Asm->OutStreamer.AddComment("DW_OP_consts"); Asm->OutStreamer.AddComment("DW_OP_consts");
Asm->EmitInt8(dwarf::DW_OP_consts); Asm->EmitInt8(dwarf::DW_OP_consts);
Asm->EmitSLEB128(Entry.getConstant()); Asm->EmitSLEB128(Entry.getInt());
} else { } else {
Asm->OutStreamer.AddComment("DW_OP_constu"); Asm->OutStreamer.AddComment("DW_OP_constu");
Asm->EmitInt8(dwarf::DW_OP_constu); Asm->EmitInt8(dwarf::DW_OP_constu);
Asm->EmitULEB128(Entry.getConstant()); Asm->EmitULEB128(Entry.getInt());
} }
} else if (DV.hasComplexAddress()) { } else if (Entry.isLocation()) {
unsigned N = DV.getNumAddrElements(); if (!DV.hasComplexAddress())
unsigned i = 0; // Regular entry.
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
if (Entry.Loc.getOffset()) {
i = 2;
Asm->EmitDwarfRegOp(Entry.Loc);
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 Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
Asm->EmitDwarfRegOp(Loc);
i = 2;
}
} else {
Asm->EmitDwarfRegOp(Entry.Loc); Asm->EmitDwarfRegOp(Entry.Loc);
else {
// Complex address entry.
unsigned N = DV.getNumAddrElements();
unsigned i = 0;
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
if (Entry.Loc.getOffset()) {
i = 2;
Asm->EmitDwarfRegOp(Entry.Loc);
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 Loc(Entry.Loc.getReg(), DV.getAddrElement(1));
Asm->EmitDwarfRegOp(Loc);
i = 2;
}
} else {
Asm->EmitDwarfRegOp(Entry.Loc);
}
// 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)
Asm->EmitInt8(dwarf::DW_OP_deref);
else llvm_unreachable("unknown Opcode found in complex address");
}
} }
// 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)
Asm->EmitInt8(dwarf::DW_OP_deref);
else llvm_unreachable("unknown Opcode found in complex address");
}
} else {
// Regular entry.
Asm->EmitDwarfRegOp(Entry.Loc);
} }
// else ... ignore constant fp. There is not any good way to
// to represent them here in dwarf.
Asm->OutStreamer.EmitLabel(end); Asm->OutStreamer.EmitLabel(end);
} }
} }

View File

@ -69,17 +69,35 @@ typedef struct DotDebugLocEntry {
const MDNode *Variable; const MDNode *Variable;
bool Merged; bool Merged;
bool Constant; bool Constant;
int64_t iConstant; enum EntryType {
E_Location,
E_Integer,
E_ConstantFP,
E_ConstantInt
};
enum EntryType EntryKind;
union {
int64_t Int;
const ConstantFP *CFP;
const ConstantInt *CIP;
} Constants;
DotDebugLocEntry() DotDebugLocEntry()
: Begin(0), End(0), Variable(0), Merged(false), : Begin(0), End(0), Variable(0), Merged(false),
Constant(false), iConstant(0) {} Constant(false) { Constants.Int = 0;}
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L, DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L,
const MDNode *V) const MDNode *V)
: Begin(B), End(E), Loc(L), Variable(V), Merged(false), : Begin(B), End(E), Loc(L), Variable(V), Merged(false),
Constant(false), iConstant(0) {} Constant(false) { Constants.Int = 0; EntryKind = E_Location; }
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i) DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i)
: Begin(B), End(E), Variable(0), Merged(false), : Begin(B), End(E), Variable(0), Merged(false),
Constant(true), iConstant(i) {} Constant(true) { Constants.Int = i; EntryKind = E_Integer; }
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr)
: Begin(B), End(E), Variable(0), Merged(false),
Constant(true) { Constants.CFP = FPtr; EntryKind = E_ConstantFP; }
DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantInt *IPtr)
: Begin(B), End(E), Variable(0), Merged(false),
Constant(true) { Constants.CIP = IPtr; EntryKind = E_ConstantInt; }
/// Empty entries are also used as a trigger to emit temp label. Such /// Empty entries are also used as a trigger to emit temp label. Such
/// labels are referenced is used to find debug_loc offset for a given DIE. /// labels are referenced is used to find debug_loc offset for a given DIE.
@ -91,8 +109,13 @@ typedef struct DotDebugLocEntry {
Next->Begin = Begin; Next->Begin = Begin;
Merged = true; Merged = true;
} }
bool isConstant() { return Constant; } bool isLocation() const { return EntryKind == E_Location; }
int64_t getConstant() { return iConstant; } bool isInt() const { return EntryKind == E_Integer; }
bool isConstantFP() const { return EntryKind == E_ConstantFP; }
bool isConstantInt() const { return EntryKind == E_ConstantInt; }
int64_t getInt() { return Constants.Int; }
const ConstantFP *getConstantFP() { return Constants.CFP; }
const ConstantInt *getConstantInt() { return Constants.CIP; }
} DotDebugLocEntry; } DotDebugLocEntry;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//