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.
push_back(DotDebugLocEntry(FLabel, SLabel, MLoc, Var));
}
// FIXME: Handle isFPImm also.
else if (Begin->getOperand(0).isImm()) {
DotDebugLocEntries.
push_back(DotDebugLocEntry(FLabel, SLabel,
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 {
MLoc = Asm->getDebugValueLocation(Begin);
@ -2608,56 +2617,61 @@ void DwarfDebug::emitDebugLoc() {
MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
Asm->EmitLabelDifference(end, begin, 2);
Asm->OutStreamer.EmitLabel(begin);
if (Entry.isConstant()) {
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.getConstant());
Asm->EmitSLEB128(Entry.getInt());
} else {
Asm->OutStreamer.AddComment("DW_OP_constu");
Asm->EmitInt8(dwarf::DW_OP_constu);
Asm->EmitULEB128(Entry.getConstant());
Asm->EmitULEB128(Entry.getInt());
}
} else if (DV.hasComplexAddress()) {
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 {
} else if (Entry.isLocation()) {
if (!DV.hasComplexAddress())
// Regular entry.
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);
}
}

View File

@ -69,17 +69,35 @@ typedef struct DotDebugLocEntry {
const MDNode *Variable;
bool Merged;
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()
: 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,
const MDNode *V)
: 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)
: 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
/// labels are referenced is used to find debug_loc offset for a given DIE.
@ -91,8 +109,13 @@ typedef struct DotDebugLocEntry {
Next->Begin = Begin;
Merged = true;
}
bool isConstant() { return Constant; }
int64_t getConstant() { return iConstant; }
bool isLocation() const { return EntryKind == E_Location; }
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;
//===----------------------------------------------------------------------===//