mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-09 10:31:14 +00:00
-Move the DwarfWriter::ValidDebugInfo check to a static DIDescriptor::ValidDebugInfo
-Create DebugLocs without the need to have a DwarfWriter around git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70682 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f9a77b77c2
commit
77eaa6880b
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_ANALYSIS_DEBUGINFO_H
|
||||
#define LLVM_ANALYSIS_DEBUGINFO_H
|
||||
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
@ -70,6 +71,9 @@ namespace llvm {
|
||||
return getUnsignedField(0) & ~LLVMDebugVersionMask;
|
||||
}
|
||||
|
||||
/// ValidDebugInfo - Return true if V represents valid debug info value.
|
||||
static bool ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel);
|
||||
|
||||
};
|
||||
|
||||
/// DIAnchor - A wrapper for various anchor descriptors.
|
||||
|
@ -82,9 +82,6 @@ public:
|
||||
///
|
||||
void EndFunction(MachineFunction *MF);
|
||||
|
||||
/// ValidDebugInfo - Return true if V represents valid debug info value.
|
||||
bool ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel);
|
||||
|
||||
/// RecordSourceLine - Register a source line with debug info. Returns a
|
||||
/// unique label ID used to generate a label and provide correspondence to
|
||||
/// the source line list.
|
||||
|
@ -20,13 +20,57 @@
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
using namespace llvm;
|
||||
using namespace llvm::dwarf;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIDescriptor
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// ValidDebugInfo - Return true if V represents valid debug info value.
|
||||
bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) {
|
||||
if (!V)
|
||||
return false;
|
||||
|
||||
GlobalVariable *GV = dyn_cast<GlobalVariable>(V->stripPointerCasts());
|
||||
if (!GV)
|
||||
return false;
|
||||
|
||||
if (!GV->hasInternalLinkage () && !GV->hasLinkOnceLinkage())
|
||||
return false;
|
||||
|
||||
DIDescriptor DI(GV);
|
||||
|
||||
// Check current version. Allow Version6 for now.
|
||||
unsigned Version = DI.getVersion();
|
||||
if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
|
||||
return false;
|
||||
|
||||
unsigned Tag = DI.getTag();
|
||||
switch (Tag) {
|
||||
case DW_TAG_variable:
|
||||
assert(DIVariable(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_compile_unit:
|
||||
assert(DICompileUnit(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_subprogram:
|
||||
assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_lexical_block:
|
||||
/// FIXME. This interfers with the quality of generated code when
|
||||
/// during optimization.
|
||||
if (OptLevel != CodeGenOpt::None)
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DIDescriptor::DIDescriptor(GlobalVariable *gv, unsigned RequiredTag) {
|
||||
GV = gv;
|
||||
|
||||
|
@ -69,28 +69,6 @@ static const unsigned InitValuesSetSize = 9; // log2(512)
|
||||
class DIE;
|
||||
class DIEValue;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// Utility routines.
|
||||
///
|
||||
/// getGlobalVariable - Return either a direct or cast Global value.
|
||||
///
|
||||
static GlobalVariable *getGlobalVariable(Value *V) {
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
||||
return GV;
|
||||
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||
if (CE->getOpcode() == Instruction::BitCast) {
|
||||
return dyn_cast<GlobalVariable>(CE->getOperand(0));
|
||||
} else if (CE->getOpcode() == Instruction::GetElementPtr) {
|
||||
for (unsigned int i=1; i<CE->getNumOperands(); i++) {
|
||||
if (!CE->getOperand(i)->isNullValue())
|
||||
return NULL;
|
||||
}
|
||||
return dyn_cast<GlobalVariable>(CE->getOperand(0));
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// DWLabel - Labels are used to track locations in the assembler file.
|
||||
/// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim,
|
||||
@ -3349,61 +3327,6 @@ public:
|
||||
DebugTimer->stopTimer();
|
||||
}
|
||||
|
||||
/// ValidDebugInfo - Return true if V represents valid debug info value.
|
||||
bool ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) {
|
||||
if (!V)
|
||||
return false;
|
||||
|
||||
if (!shouldEmit)
|
||||
return false;
|
||||
|
||||
GlobalVariable *GV = getGlobalVariable(V);
|
||||
if (!GV)
|
||||
return false;
|
||||
|
||||
if (!GV->hasInternalLinkage () && !GV->hasLinkOnceLinkage())
|
||||
return false;
|
||||
|
||||
if (TimePassesIsEnabled)
|
||||
DebugTimer->startTimer();
|
||||
|
||||
DIDescriptor DI(GV);
|
||||
|
||||
// Check current version. Allow Version6 for now.
|
||||
unsigned Version = DI.getVersion();
|
||||
if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6) {
|
||||
if (TimePassesIsEnabled)
|
||||
DebugTimer->stopTimer();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned Tag = DI.getTag();
|
||||
switch (Tag) {
|
||||
case DW_TAG_variable:
|
||||
assert(DIVariable(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_compile_unit:
|
||||
assert(DICompileUnit(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_subprogram:
|
||||
assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value");
|
||||
break;
|
||||
case DW_TAG_lexical_block:
|
||||
/// FIXME. This interfers with the qualitfy of generated code when
|
||||
/// during optimization.
|
||||
if (OptLevel != CodeGenOpt::None)
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (TimePassesIsEnabled)
|
||||
DebugTimer->stopTimer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// RecordSourceLine - Records location information and associates it with a
|
||||
/// label. Returns a unique label ID used to generate a label and provide
|
||||
/// correspondence to the source line list.
|
||||
@ -4752,11 +4675,6 @@ void DwarfWriter::EndFunction(MachineFunction *MF) {
|
||||
MMI->EndFunction();
|
||||
}
|
||||
|
||||
/// ValidDebugInfo - Return true if V represents valid debug info value.
|
||||
bool DwarfWriter::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) {
|
||||
return DD && DD->ValidDebugInfo(V, OptLevel);
|
||||
}
|
||||
|
||||
/// RecordSourceLine - Records location information and associates it with a
|
||||
/// label. Returns a unique label ID used to generate a label and provide
|
||||
/// correspondence to the source line list.
|
||||
@ -4790,7 +4708,7 @@ void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
|
||||
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
|
||||
/// be emitted.
|
||||
bool DwarfWriter::ShouldEmitDwarfDebug() const {
|
||||
return DD->ShouldEmitDwarfDebug();
|
||||
return DD && DD->ShouldEmitDwarfDebug();
|
||||
}
|
||||
|
||||
//// RecordInlinedFnStart - Global variable GV is inlined at the location marked
|
||||
|
@ -327,21 +327,24 @@ bool FastISel::SelectCall(User *I) {
|
||||
default: break;
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(SPI->getContext(), CodeGenOpt::None)) {
|
||||
if (DIDescriptor::ValidDebugInfo(SPI->getContext(), CodeGenOpt::None)) {
|
||||
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
|
||||
unsigned Line = SPI->getLine();
|
||||
unsigned Col = SPI->getColumn();
|
||||
unsigned ID = DW->RecordSourceLine(Line, Col, CU);
|
||||
unsigned Idx = MF.getOrCreateDebugLocID(CU.getGV(), Line, Col);
|
||||
setCurDebugLoc(DebugLoc::get(Idx));
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, DL, II).addImm(ID);
|
||||
if (DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned ID = DW->RecordSourceLine(Line, Col, CU);
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, DL, II).addImm(ID);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_region_start: {
|
||||
DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(RSI->getContext(), CodeGenOpt::None)) {
|
||||
if (DIDescriptor::ValidDebugInfo(RSI->getContext(), CodeGenOpt::None) &&
|
||||
DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned ID =
|
||||
DW->RecordRegionStart(cast<GlobalVariable>(RSI->getContext()));
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
@ -351,7 +354,8 @@ bool FastISel::SelectCall(User *I) {
|
||||
}
|
||||
case Intrinsic::dbg_region_end: {
|
||||
DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(REI->getContext(), CodeGenOpt::None)) {
|
||||
if (DIDescriptor::ValidDebugInfo(REI->getContext(), CodeGenOpt::None) &&
|
||||
DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned ID = 0;
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(REI->getContext()));
|
||||
if (!Subprogram.isNull() && !Subprogram.describes(MF.getFunction())) {
|
||||
@ -373,43 +377,46 @@ bool FastISel::SelectCall(User *I) {
|
||||
return true;
|
||||
}
|
||||
case Intrinsic::dbg_func_start: {
|
||||
if (!DW) return true;
|
||||
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
|
||||
Value *SP = FSI->getSubprogram();
|
||||
if (!DIDescriptor::ValidDebugInfo(SP, CodeGenOpt::None))
|
||||
return true;
|
||||
|
||||
if (DW->ValidDebugInfo(SP, CodeGenOpt::None)) {
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
|
||||
// (most?) gdb expects.
|
||||
DebugLoc PrevLoc = DL;
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
|
||||
// (most?) gdb expects.
|
||||
DebugLoc PrevLoc = DL;
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
|
||||
if (!Subprogram.describes(MF.getFunction())) {
|
||||
// This is a beginning of an inlined function.
|
||||
|
||||
// If llvm.dbg.func.start is seen in a new block before any
|
||||
// llvm.dbg.stoppoint intrinsic then the location info is unknown.
|
||||
// FIXME : Why DebugLoc is reset at the beginning of each block ?
|
||||
if (PrevLoc.isUnknown())
|
||||
return true;
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
if (!Subprogram.describes(MF.getFunction())) {
|
||||
// This is a beginning of an inlined function.
|
||||
|
||||
// If llvm.dbg.func.start is seen in a new block before any
|
||||
// llvm.dbg.stoppoint intrinsic then the location info is unknown.
|
||||
// FIXME : Why DebugLoc is reset at the beginning of each block ?
|
||||
if (PrevLoc.isUnknown())
|
||||
return true;
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
|
||||
CompileUnit.getGV(), Line, 0)));
|
||||
|
||||
if (DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit);
|
||||
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
|
||||
CompileUnit.getGV(), Line, 0)));
|
||||
|
||||
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
|
||||
BuildMI(MBB, DL, II).addImm(LabelID);
|
||||
DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
|
||||
DW->RecordInlinedFnStart(FSI, Subprogram, LabelID,
|
||||
DW->RecordInlinedFnStart(FSI, Subprogram, LabelID,
|
||||
DICompileUnit(PrevLocTpl.CompileUnit),
|
||||
PrevLocTpl.Line,
|
||||
PrevLocTpl.Col);
|
||||
} else {
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
|
||||
CompileUnit.getGV(), Line, 0)));
|
||||
}
|
||||
} else {
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(
|
||||
CompileUnit.getGV(), Line, 0)));
|
||||
if (DW && DW->ShouldEmitDwarfDebug()) {
|
||||
DW->RecordSourceLine(Line, 0, CompileUnit);
|
||||
// llvm.dbg.func_start also defines beginning of function scope.
|
||||
DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
|
||||
@ -421,7 +428,8 @@ bool FastISel::SelectCall(User *I) {
|
||||
case Intrinsic::dbg_declare: {
|
||||
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
|
||||
Value *Variable = DI->getVariable();
|
||||
if (DW && DW->ValidDebugInfo(Variable, CodeGenOpt::None)) {
|
||||
if (DIDescriptor::ValidDebugInfo(Variable, CodeGenOpt::None) &&
|
||||
DW && DW->ShouldEmitDwarfDebug()) {
|
||||
// Determine the address of the declared object.
|
||||
Value *Address = DI->getAddress();
|
||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
|
||||
|
@ -331,11 +331,10 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
|
||||
switch (F->getIntrinsicID()) {
|
||||
default: break;
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
|
||||
|
||||
if (DW && DW->ValidDebugInfo(SPI->getContext(),
|
||||
CodeGenOpt::Default)) {
|
||||
if (DIDescriptor::ValidDebugInfo(SPI->getContext(),
|
||||
CodeGenOpt::Default)) {
|
||||
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
|
||||
unsigned idx = MF->getOrCreateDebugLocID(CU.getGV(),
|
||||
SPI->getLine(),
|
||||
@ -346,18 +345,15 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
|
||||
break;
|
||||
}
|
||||
case Intrinsic::dbg_func_start: {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
if (DW) {
|
||||
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
|
||||
Value *SP = FSI->getSubprogram();
|
||||
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
|
||||
Value *SP = FSI->getSubprogram();
|
||||
|
||||
if (DW->ValidDebugInfo(SP, CodeGenOpt::Default)) {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CU(Subprogram.getCompileUnit());
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
DL = DebugLoc::get(MF->getOrCreateDebugLocID(CU.getGV(),
|
||||
Line, 0));
|
||||
}
|
||||
if (DIDescriptor::ValidDebugInfo(SP, CodeGenOpt::Default)) {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CU(Subprogram.getCompileUnit());
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
DL = DebugLoc::get(MF->getOrCreateDebugLocID(CU.getGV(),
|
||||
Line, 0));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -3890,9 +3886,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::dbg_stoppoint: {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
|
||||
if (DW && DW->ValidDebugInfo(SPI.getContext(), OptLevel)) {
|
||||
if (DIDescriptor::ValidDebugInfo(SPI.getContext(), OptLevel)) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
if (OptLevel == CodeGenOpt::None)
|
||||
DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
|
||||
@ -3910,7 +3905,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
|
||||
|
||||
if (DW && DW->ValidDebugInfo(RSI.getContext(), OptLevel)) {
|
||||
if (DIDescriptor::ValidDebugInfo(RSI.getContext(), OptLevel) &&
|
||||
DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned LabelID =
|
||||
DW->RecordRegionStart(cast<GlobalVariable>(RSI.getContext()));
|
||||
DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
|
||||
@ -3923,7 +3919,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
|
||||
|
||||
if (DW && DW->ValidDebugInfo(REI.getContext(), OptLevel)) {
|
||||
if (DIDescriptor::ValidDebugInfo(REI.getContext(), OptLevel) &&
|
||||
DW && DW->ShouldEmitDwarfDebug()) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext()));
|
||||
std::string SPName;
|
||||
@ -3955,84 +3952,87 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
}
|
||||
case Intrinsic::dbg_func_start: {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
if (!DW) return 0;
|
||||
DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
|
||||
Value *SP = FSI.getSubprogram();
|
||||
if (SP && DW->ValidDebugInfo(SP, OptLevel)) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
if (OptLevel == CodeGenOpt::None) {
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
|
||||
// (most?) gdb expects.
|
||||
DebugLoc PrevLoc = CurDebugLoc;
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
|
||||
if (!Subprogram.describes(MF.getFunction())) {
|
||||
// This is a beginning of an inlined function.
|
||||
if (!DIDescriptor::ValidDebugInfo(SP, OptLevel))
|
||||
return 0;
|
||||
|
||||
// If llvm.dbg.func.start is seen in a new block before any
|
||||
// llvm.dbg.stoppoint intrinsic then the location info is unknown.
|
||||
// FIXME : Why DebugLoc is reset at the beginning of each block ?
|
||||
if (PrevLoc.isUnknown())
|
||||
return 0;
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
if (OptLevel == CodeGenOpt::None) {
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
|
||||
// (most?) gdb expects.
|
||||
DebugLoc PrevLoc = CurDebugLoc;
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
if (!Subprogram.describes(MF.getFunction())) {
|
||||
// This is a beginning of an inlined function.
|
||||
|
||||
// If llvm.dbg.func.start is seen in a new block before any
|
||||
// llvm.dbg.stoppoint intrinsic then the location info is unknown.
|
||||
// FIXME : Why DebugLoc is reset at the beginning of each block ?
|
||||
if (PrevLoc.isUnknown())
|
||||
return 0;
|
||||
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
|
||||
if (DW && DW->ShouldEmitDwarfDebug()) {
|
||||
unsigned LabelID = DW->RecordSourceLine(Line, 0, CompileUnit);
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
|
||||
DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
|
||||
getRoot(), LabelID));
|
||||
DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
|
||||
DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID,
|
||||
DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID,
|
||||
DICompileUnit(PrevLocTpl.CompileUnit),
|
||||
PrevLocTpl.Line,
|
||||
PrevLocTpl.Col);
|
||||
} else {
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
}
|
||||
} else {
|
||||
// Record the source line.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
if (DW && DW->ShouldEmitDwarfDebug()) {
|
||||
DW->RecordSourceLine(Line, 0, CompileUnit);
|
||||
// llvm.dbg.func_start also defines beginning of function scope.
|
||||
DW->RecordRegionStart(cast<GlobalVariable>(FSI.getSubprogram()));
|
||||
}
|
||||
} else {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
|
||||
std::string SPName;
|
||||
Subprogram.getLinkageName(SPName);
|
||||
if (!SPName.empty()
|
||||
&& strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
|
||||
// This is beginning of inlined function. Debugging information for
|
||||
// inlined function is not handled yet (only supported by FastISel).
|
||||
return 0;
|
||||
}
|
||||
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
|
||||
// what (most?) gdb expects.
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
|
||||
// Record the source line but does not create a label for the normal
|
||||
// function start. It will be emitted at asm emission time. However,
|
||||
// create a label if this is a beginning of inlined function.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
// FIXME - Start new region because llvm.dbg.func_start also defines
|
||||
// beginning of function scope.
|
||||
}
|
||||
} else {
|
||||
DISubprogram Subprogram(cast<GlobalVariable>(SP));
|
||||
|
||||
std::string SPName;
|
||||
Subprogram.getLinkageName(SPName);
|
||||
if (!SPName.empty()
|
||||
&& strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
|
||||
// This is beginning of inlined function. Debugging information for
|
||||
// inlined function is not handled yet (only supported by FastISel).
|
||||
return 0;
|
||||
}
|
||||
|
||||
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
|
||||
// what (most?) gdb expects.
|
||||
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
|
||||
|
||||
// Record the source line but does not create a label for the normal
|
||||
// function start. It will be emitted at asm emission time. However,
|
||||
// create a label if this is a beginning of inlined function.
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
setCurDebugLoc(DebugLoc::get(
|
||||
MF.getOrCreateDebugLocID(CompileUnit.getGV(), Line, 0)));
|
||||
// FIXME - Start new region because llvm.dbg.func_start also defines
|
||||
// beginning of function scope.
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::dbg_declare: {
|
||||
if (OptLevel == CodeGenOpt::None) {
|
||||
DwarfWriter *DW = DAG.getDwarfWriter();
|
||||
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
|
||||
Value *Variable = DI.getVariable();
|
||||
if (DW && DW->ValidDebugInfo(Variable, OptLevel))
|
||||
if (DIDescriptor::ValidDebugInfo(Variable, OptLevel))
|
||||
DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(),
|
||||
getValue(DI.getAddress()), getValue(Variable)));
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user