Handle debug info for i128 constants.

llvm-svn: 133821
This commit is contained in:
Devang Patel 2011-06-24 20:46:11 +00:00
parent e862d59eee
commit f071d72c44
13 changed files with 166 additions and 63 deletions

View File

@ -77,6 +77,11 @@ public:
return *this;
}
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
MI->addOperand(MachineOperand::CreateCImm(Val));
return *this;
}
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
MI->addOperand(MachineOperand::CreateFPImm(Val));
return *this;

View File

@ -21,6 +21,7 @@ namespace llvm {
class BlockAddress;
class ConstantFP;
class ConstantInt;
class GlobalValue;
class MachineBasicBlock;
class MachineInstr;
@ -38,6 +39,7 @@ public:
enum MachineOperandType {
MO_Register, ///< Register operand.
MO_Immediate, ///< Immediate operand
MO_CImmediate, ///< Immediate >64bit operand
MO_FPImmediate, ///< Floating-point immediate operand
MO_MachineBasicBlock, ///< MachineBasicBlock reference
MO_FrameIndex, ///< Abstract Stack Frame Index
@ -111,6 +113,7 @@ private:
union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
const ConstantFP *CFP; // For MO_FPImmediate.
const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
int64_t ImmVal; // For MO_Immediate.
const MDNode *MD; // For MO_Metadata.
MCSymbol *Sym; // For MO_MCSymbol
@ -173,6 +176,8 @@ public:
bool isReg() const { return OpKind == MO_Register; }
/// isImm - Tests if this is a MO_Immediate operand.
bool isImm() const { return OpKind == MO_Immediate; }
/// isCImm - Test if t his is a MO_CImmediate operand.
bool isCImm() const { return OpKind == MO_CImmediate; }
/// isFPImm - Tests if this is a MO_FPImmediate operand.
bool isFPImm() const { return OpKind == MO_FPImmediate; }
/// isMBB - Tests if this is a MO_MachineBasicBlock operand.
@ -333,6 +338,11 @@ public:
return Contents.ImmVal;
}
const ConstantInt *getCImm() const {
assert(isCImm() && "Wrong MachineOperand accessor");
return Contents.CI;
}
const ConstantFP *getFPImm() const {
assert(isFPImm() && "Wrong MachineOperand accessor");
return Contents.CFP;
@ -440,6 +450,12 @@ public:
return Op;
}
static MachineOperand CreateCImm(const ConstantInt *CI) {
MachineOperand Op(MachineOperand::MO_CImmediate);
Op.Contents.CI = CI;
return Op;
}
static MachineOperand CreateFPImm(const ConstantFP *CFP) {
MachineOperand Op(MachineOperand::MO_FPImmediate);
Op.Contents.CFP = CFP;

View File

@ -575,6 +575,8 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
}
} else if (MI->getOperand(0).isImm()) {
OS << MI->getOperand(0).getImm();
} else if (MI->getOperand(0).isCImm()) {
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
} else {
assert(MI->getOperand(0).isReg() && "Unknown operand type");
if (MI->getOperand(0).getReg() == 0) {

View File

@ -491,7 +491,7 @@ bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
}
/// addConstantValue - Add constant value entry in variable DIE.
bool CompileUnit::addConstantValue(DIE *Die, ConstantInt *CI,
bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
bool Unsigned) {
unsigned CIBitWidth = CI->getBitWidth();
if (CIBitWidth <= 64) {

View File

@ -181,7 +181,7 @@ public:
/// addConstantValue - Add constant value entry in variable DIE.
bool addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty);
bool addConstantValue(DIE *Die, ConstantInt *CI, bool Unsigned);
bool addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned);
/// addConstantFPValue - Add constant value entry in variable DIE.
bool addConstantFPValue(DIE *Die, const MachineOperand &MO);

View File

@ -618,6 +618,21 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
return ScopeDIE;
}
/// isUnsignedDIType - Return true if type encoding is unsigned.
static bool isUnsignedDIType(DIType Ty) {
DIDerivedType DTy(Ty);
if (DTy.Verify())
return isUnsignedDIType(DTy.getTypeDerivedFrom());
DIBasicType BTy(Ty);
if (BTy.Verify()) {
unsigned Encoding = BTy.getEncoding();
if (Encoding == dwarf::DW_ATE_unsigned ||
Encoding == dwarf::DW_ATE_unsigned_char)
return true;
}
return false;
}
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
@ -718,6 +733,11 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
else if (DVInsn->getOperand(0).isFPImm())
updated =
VariableCU->addConstantFPValue(VariableDie, DVInsn->getOperand(0));
else if (DVInsn->getOperand(0).isCImm())
updated =
VariableCU->addConstantValue(VariableDie,
DVInsn->getOperand(0).getCImm(),
isUnsignedDIType(DV->getType()));
} else {
VariableCU->addVariableAddress(DV, VariableDie,
Asm->getDebugValueLocation(DVInsn));
@ -913,22 +933,6 @@ CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const {
return I->second;
}
/// isUnsignedDIType - Return true if type encoding is unsigned.
static bool isUnsignedDIType(DIType Ty) {
DIDerivedType DTy(Ty);
if (DTy.Verify())
return isUnsignedDIType(DTy.getTypeDerivedFrom());
DIBasicType BTy(Ty);
if (BTy.Verify()) {
unsigned Encoding = BTy.getEncoding();
if (Encoding == dwarf::DW_ATE_unsigned ||
Encoding == dwarf::DW_ATE_unsigned_char)
return true;
}
return false;
}
// Return const exprssion if value is a GEP to access merged global
// constant. e.g.
// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
@ -1017,7 +1021,7 @@ void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {
} else {
TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
}
} else if (ConstantInt *CI =
} else if (const ConstantInt *CI =
dyn_cast_or_null<ConstantInt>(GV.getConstant()))
TheCU->addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy));
else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {

View File

@ -267,6 +267,9 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
case MachineOperand::MO_Immediate:
OS << getImm();
break;
case MachineOperand::MO_CImmediate:
getCImm()->getValue().print(OS, false);
break;
case MachineOperand::MO_FPImmediate:
if (getFPImm()->getType()->isFloatTy())
OS << getFPImm()->getValueAPF().convertToFloat();

View File

@ -556,9 +556,14 @@ bool FastISel::SelectCall(const User *I) {
.addReg(0U).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
.addImm(CI->getZExtValue()).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
if (CI->getBitWidth() > 64)
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
.addCImm(CI).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
else
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
.addImm(CI->getZExtValue()).addImm(DI->getOffset())
.addMetadata(DI->getVariable());
} else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
.addFPImm(CF).addImm(DI->getOffset())

View File

@ -616,12 +616,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
} else if (SD->getKind() == SDDbgValue::CONST) {
const Value *V = SD->getConst();
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
// FIXME: SDDbgValue constants aren't updated with legalization, so it's
// possible to have i128 constants in them at this point. Dwarf writer
// does not handle i128 constants at the moment so, as a crude workaround,
// just drop the debug info if this happens.
if (!CI->getValue().isSignedIntN(64))
MIB.addReg(0U);
if (CI->getBitWidth() > 64)
MIB.addCImm(CI);
else
MIB.addImm(CI->getSExtValue());
} else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {

View File

@ -32,6 +32,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
@ -41,6 +42,11 @@
#include <cctype>
using namespace llvm;
static cl::opt<bool>
EnableDebugInfoComment("enable-debug-info-comment", cl::Hidden,
cl::desc("Enable debug info comments"));
// Make virtual table appear in this compilation unit.
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
@ -1761,6 +1767,18 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
}
/// printDebugLoc - Print DebugLoc.
static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
OS << DL.getLine() << ":" << DL.getCol();
if (MDNode *N = DL.getInlinedAt(getGlobalContext())) {
DebugLoc IDL = DebugLoc::getFromDILocation(N);
if (!IDL.isUnknown()) {
OS << "@";
printDebugLoc(IDL,OS);
}
}
}
/// printInfoComment - Print a little comment after the instruction indicating
/// which slot it occupies.
///
@ -1768,6 +1786,43 @@ void AssemblyWriter::printInfoComment(const Value &V) {
if (AnnotationWriter) {
AnnotationWriter->printInfoComment(V, Out);
return;
} else if (EnableDebugInfoComment) {
bool Padded = false;
if (const Instruction *I = dyn_cast<Instruction>(&V)) {
const DebugLoc &DL = I->getDebugLoc();
if (!DL.isUnknown()) {
if (!Padded) {
Out.PadToColumn(50);
Padded = true;
Out << ";";
}
Out << " [debug line = ";
printDebugLoc(DL,Out);
Out << "]";
}
if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
const MDNode *Var = DDI->getVariable();
if (!Padded) {
Out.PadToColumn(50);
Padded = true;
Out << ";";
}
if (Var && Var->getNumOperands() >= 2)
if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
Out << " [debug variable = " << MDS->getString() << "]";
}
else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
const MDNode *Var = DVI->getVariable();
if (!Padded) {
Out.PadToColumn(50);
Padded = true;
Out << ";";
}
if (Var && Var->getNumOperands() >= 2)
if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2)))
Out << " [debug variable = " << MDS->getString() << "]";
}
}
}
}

View File

@ -53,6 +53,7 @@ namespace llvm {
Function *TheFn;
std::set<MDNode *> DbgVariables;
std::set<Instruction *> MissingDebugLoc;
std::set<unsigned> LineNos;
};
}
@ -66,14 +67,19 @@ void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
DbgVariables.clear();
MissingDebugLoc.clear();
LineNos.clear();
TheFn = &F;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown())
MissingDebugLoc.insert(BI);
if (!isa<DbgInfoIntrinsic>(BI)) continue;
DebugLoc DL = BI->getDebugLoc();
if (DL.isUnknown()) {
if (!isa<PHINode>(BI))
MissingDebugLoc.insert(BI);
} else
LineNos.insert(DL.getLine());
if (!isa<DbgInfoIntrinsic>(BI)) continue;
Value *Addr = NULL;
MDNode *Node = NULL;
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
@ -114,16 +120,20 @@ void DebugInfoProbeImpl::finalize(Function &F) {
assert (TheFn == &F && "Invalid function to measure!");
std::set<MDNode *>DbgVariables2;
std::set<unsigned>LineNos2;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() &&
MissingDebugLoc.count(BI) == 0) {
++NumDbgLineLost;
DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
DEBUG(BI->print(dbgs()));
DEBUG(dbgs() << "\n");
}
DebugLoc DL = BI->getDebugLoc();
if (DL.isUnknown()) {
if (!isa<PHINode>(BI) && MissingDebugLoc.count(BI) == 0) {
++NumDbgLineLost;
DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
DEBUG(BI->print(dbgs()));
DEBUG(dbgs() << "\n");
}
} else
LineNos2.insert(DL.getLine());
if (!isa<DbgInfoIntrinsic>(BI)) continue;
Value *Addr = NULL;
MDNode *Node = NULL;
@ -138,6 +148,12 @@ void DebugInfoProbeImpl::finalize(Function &F) {
DbgVariables2.insert(Node);
}
for (std::set<unsigned>::iterator I = LineNos.begin(),
E = LineNos.end(); I != E; ++I) {
unsigned LNO = *I;
if (LineNos2.count(LNO) == 0)
DEBUG(dbgs() << "DebugInfoProbe dropping line number " << LNO << "\n");
}
for (std::set<MDNode *>::iterator I = DbgVariables.begin(),
E = DbgVariables.end(); I != E; ++I) {
if (DbgVariables2.count(*I) == 0 && (*I)->getNumOperands() >= 2) {

View File

@ -1,25 +0,0 @@
; RUN: llc < %s -o /dev/null
; llvm.dbg.value instructions can have types which are not legal for the
; target. CodeGen should handle this.
define i128 @__mulvti3(i128 %a, i128 %b) nounwind {
entry:
tail call void @llvm.dbg.value(metadata !0, i64 0, metadata !1), !dbg !11
unreachable
}
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
!0 = metadata !{i128 170141183460469231731687303715884105727}
!1 = metadata !{i32 524544, metadata !2, metadata !"MAX", metadata !4, i32 29, metadata !8} ; [ DW_TAG_auto_variable ]
!2 = metadata !{i32 524299, metadata !3, i32 26, i32 0} ; [ DW_TAG_lexical_block ]
!3 = metadata !{i32 524334, i32 0, metadata !4, metadata !"__mulvti3", metadata !"__mulvti3", metadata !"__mulvti3", metadata !4, i32 26, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
!4 = metadata !{i32 524329, metadata !"mulvti3.c", metadata !"/Volumes/Sandbox/llvm/swb/Libcompiler_rt-6.roots/Libcompiler_rt-6/lib", metadata !5} ; [ DW_TAG_file_type ]
!5 = metadata !{i32 524305, i32 0, i32 1, metadata !"mulvti3.c", metadata !"/Volumes/Sandbox/llvm/swb/Libcompiler_rt-6.roots/Libcompiler_rt-6/lib", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2328)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!6 = metadata !{i32 524309, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ]
!7 = metadata !{metadata !8, metadata !8, metadata !8}
!8 = metadata !{i32 524310, metadata !4, metadata !"ti_int", metadata !9, i32 78, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ]
!9 = metadata !{i32 524329, metadata !"int_lib.h", metadata !"/Volumes/Sandbox/llvm/swb/Libcompiler_rt-6.roots/Libcompiler_rt-6/lib", metadata !5} ; [ DW_TAG_file_type ]
!10 = metadata !{i32 524324, metadata !4, metadata !"", metadata !4, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!11 = metadata !{i32 29, i32 0, metadata !2, null}

View File

@ -0,0 +1,26 @@
; RUN: llc < %s | FileCheck %s
; CHECK: DW_AT_const_value
; CHECK-NEXT: 42
define i128 @__foo(i128 %a, i128 %b) nounwind {
entry:
tail call void @llvm.dbg.value(metadata !0, i64 0, metadata !1), !dbg !11
%add = add i128 %a, %b, !dbg !11
ret i128 %add, !dbg !11
}
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
!0 = metadata !{i128 42 }
!1 = metadata !{i32 524544, metadata !2, metadata !"MAX", metadata !4, i32 29, metadata !8} ; [ DW_TAG_auto_variable ]
!2 = metadata !{i32 524299, metadata !3, i32 26, i32 0} ; [ DW_TAG_lexical_block ]
!3 = metadata !{i32 524334, i32 0, metadata !4, metadata !"__foo", metadata !"__foo", metadata !"__foo", metadata !4, i32 26, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ]
!4 = metadata !{i32 524329, metadata !"foo.c", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ]
!5 = metadata !{i32 524305, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!6 = metadata !{i32 524309, metadata !4, metadata !"", metadata !4, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ]
!7 = metadata !{metadata !8, metadata !8, metadata !8}
!8 = metadata !{i32 524310, metadata !4, metadata !"ti_int", metadata !9, i32 78, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ]
!9 = metadata !{i32 524329, metadata !"myint.h", metadata !"/tmp", metadata !5} ; [ DW_TAG_file_type ]
!10 = metadata !{i32 524324, metadata !4, metadata !"", metadata !4, i32 0, i64 128, i64 128, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!11 = metadata !{i32 29, i32 0, metadata !2, null}