Implement -gline-tables-only (PR #1861)

As per ldc-developers/ldc#1844 .
This commit is contained in:
Remi Thebault 2016-11-12 20:16:41 +01:00 committed by Johan Engelen
parent 39a5aaecdb
commit 3b63effd3f
6 changed files with 157 additions and 23 deletions

View file

@ -117,7 +117,8 @@ static cl::opt<bool, true> ignoreUnsupportedPragmas(
static cl::opt<ubyte, true> debugInfo( static cl::opt<ubyte, true> debugInfo(
cl::desc("Generating debug information:"), cl::ZeroOrMore, cl::desc("Generating debug information:"), cl::ZeroOrMore,
clEnumValues(clEnumValN(1, "g", "Generate debug information"), clEnumValues(clEnumValN(1, "g", "Generate debug information"),
clEnumValN(2, "gc", "Same as -g, but pretend to be C")), clEnumValN(2, "gc", "Same as -g, but pretend to be C"),
clEnumValN(3, "gline-tables-only", "Generate line-tables-only")),
cl::location(global.params.symdebug), cl::init(0)); cl::location(global.params.symdebug), cl::init(0));
static cl::opt<unsigned, true> static cl::opt<unsigned, true>

View file

@ -74,7 +74,16 @@ llvm::StringRef uniqueIdent(Type* t) {
} // namespace } // namespace
bool ldc::DIBuilder::mustEmitDebugInfo() { return global.params.symdebug; }
bool ldc::DIBuilder::mustEmitFullDebugInfo() {
// only for -g and -gc
return global.params.symdebug == 1 || global.params.symdebug == 2;
}
bool ldc::DIBuilder::mustEmitLocationsDebugInfo() {
// for -g -gc and -gline-tables-only
return global.params.symdebug > 0;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -613,6 +622,19 @@ ldc::DISubroutineType ldc::DIBuilder::CreateFunctionType(Type *type) {
#endif #endif
} }
ldc::DISubroutineType ldc::DIBuilder::CreateEmptyFunctionType() {
#if LDC_LLVM_VER == 305
auto paramsArray = DBuilder.getOrCreateArray(llvm::None);
#else
auto paramsArray = DBuilder.getOrCreateTypeArray(llvm::None);
#endif
#if LDC_LLVM_VER >= 308
return DBuilder.createSubroutineType(paramsArray);
#else
return DBuilder.createSubroutineType(CreateFile(), paramsArray);
#endif
}
ldc::DIType ldc::DIBuilder::CreateDelegateType(Type *type) { ldc::DIType ldc::DIBuilder::CreateDelegateType(Type *type) {
assert(type->toBasetype()->ty == Tdelegate); assert(type->toBasetype()->ty == Tdelegate);
@ -699,8 +721,39 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type, bool derefclass) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#if LDC_LLVM_VER >= 309
using DebugEmissionKind = llvm::DICompileUnit::DebugEmissionKind;
#else
using DebugEmissionKind = llvm::DIBuilder::DebugEmissionKind;
#endif
DebugEmissionKind getDebugEmissionKind()
{
#if LDC_LLVM_VER >= 309
switch (global.params.symdebug)
{
case 0:
return llvm::DICompileUnit::NoDebug;
case 1:
case 2:
return llvm::DICompileUnit::FullDebug;
case 3:
return llvm::DICompileUnit::LineTablesOnly;
default:
llvm_unreachable("unknown DebugEmissionKind");
}
#else
assert(global.params.symdebug != 0);
return global.params.symdebug == 3 ?
llvm::DIBuilder::LineTablesOnly :
llvm::DIBuilder::FullDebug;
#endif
}
void ldc::DIBuilder::EmitCompileUnit(Module *m) { void ldc::DIBuilder::EmitCompileUnit(Module *m) {
if (!mustEmitDebugInfo()) { if (!mustEmitLocationsDebugInfo()) {
return; return;
} }
@ -731,12 +784,20 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
"LDC (http://wiki.dlang.org/LDC)", "LDC (http://wiki.dlang.org/LDC)",
isOptimizationEnabled(), // isOptimized isOptimizationEnabled(), // isOptimized
llvm::StringRef(), // Flags TODO llvm::StringRef(), // Flags TODO
1 // Runtime Version TODO 1, // Runtime Version TODO
llvm::StringRef(), // SplitName
getDebugEmissionKind() // DebugEmissionKind
#if LDC_LLVM_VER > 306
, 0 // DWOId
#endif
#if LDC_LLVM_VER < 309
, mustEmitFullDebugInfo() // EmitDebugInfo
#endif
); );
} }
ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) { ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
if (!mustEmitDebugInfo()) { if (!mustEmitLocationsDebugInfo()) {
#if LDC_LLVM_VER >= 307 #if LDC_LLVM_VER >= 307
return nullptr; return nullptr;
#else #else
@ -754,8 +815,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
ldc::DIFile file = CreateFile(fd); ldc::DIFile file = CreateFile(fd);
// Create subroutine type // Create subroutine type
ldc::DISubroutineType DIFnType = ldc::DISubroutineType DIFnType = mustEmitFullDebugInfo() ?
CreateFunctionType(static_cast<TypeFunction *>(fd->type)); CreateFunctionType(static_cast<TypeFunction *>(fd->type)) :
CreateEmptyFunctionType();
// FIXME: duplicates? // FIXME: duplicates?
auto SP = DBuilder.createFunction( auto SP = DBuilder.createFunction(
@ -784,7 +846,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk, ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
FuncDeclaration *fd) { FuncDeclaration *fd) {
if (!mustEmitDebugInfo()) { if (!mustEmitLocationsDebugInfo()) {
#if LDC_LLVM_VER >= 307 #if LDC_LLVM_VER >= 307
return nullptr; return nullptr;
#else #else
@ -833,7 +895,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn, ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
llvm::StringRef prettyname) { llvm::StringRef prettyname) {
if (!mustEmitDebugInfo()) { if (!mustEmitLocationsDebugInfo()) {
#if LDC_LLVM_VER >= 307 #if LDC_LLVM_VER >= 307
return nullptr; return nullptr;
#else #else
@ -857,10 +919,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
auto paramsArray = DBuilder.getOrCreateArray(params); auto paramsArray = DBuilder.getOrCreateArray(params);
#endif #endif
#if LDC_LLVM_VER >= 308 #if LDC_LLVM_VER >= 308
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(paramsArray); auto DIFnType = DBuilder.createSubroutineType(paramsArray);
#else #else
ldc::DISubroutineType DIFnType = auto DIFnType = DBuilder.createSubroutineType(file, paramsArray);
DBuilder.createSubroutineType(file, paramsArray);
#endif #endif
// FIXME: duplicates? // FIXME: duplicates?
@ -888,7 +949,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
} }
void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) { void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
Logger::println("D to dwarf funcstart"); Logger::println("D to dwarf funcstart");
@ -899,7 +960,7 @@ void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
} }
void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) { void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
Logger::println("D to dwarf funcend"); Logger::println("D to dwarf funcend");
@ -910,7 +971,7 @@ void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
} }
void ldc::DIBuilder::EmitBlockStart(Loc &loc) { void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
Logger::println("D to dwarf block start"); Logger::println("D to dwarf block start");
@ -931,7 +992,7 @@ void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
} }
void ldc::DIBuilder::EmitBlockEnd() { void ldc::DIBuilder::EmitBlockEnd() {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
Logger::println("D to dwarf block end"); Logger::println("D to dwarf block end");
@ -943,7 +1004,7 @@ void ldc::DIBuilder::EmitBlockEnd() {
} }
void ldc::DIBuilder::EmitStopPoint(Loc &loc) { void ldc::DIBuilder::EmitStopPoint(Loc &loc) {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
// If we already have a location set and the current loc is invalid // If we already have a location set and the current loc is invalid
@ -981,7 +1042,7 @@ void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
return; return;
ldc::DILocalVariable debugVariable = sub->second; ldc::DILocalVariable debugVariable = sub->second;
if (!mustEmitDebugInfo() || !debugVariable) if (!mustEmitFullDebugInfo() || !debugVariable)
return; return;
llvm::Instruction *instr = llvm::Instruction *instr =
@ -1005,7 +1066,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
llvm::ArrayRef<llvm::Value *> addr llvm::ArrayRef<llvm::Value *> addr
#endif #endif
) { ) {
if (!mustEmitDebugInfo()) if (!mustEmitFullDebugInfo())
return; return;
Logger::println("D to dwarf local variable"); Logger::println("D to dwarf local variable");
@ -1139,7 +1200,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar, void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
VarDeclaration *vd) { VarDeclaration *vd) {
if (!mustEmitDebugInfo()) if (!mustEmitFullDebugInfo())
return; return;
Logger::println("D to dwarf global_variable"); Logger::println("D to dwarf global_variable");
@ -1174,7 +1235,7 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
} }
void ldc::DIBuilder::Finalize() { void ldc::DIBuilder::Finalize() {
if (!mustEmitDebugInfo()) if (!mustEmitLocationsDebugInfo())
return; return;
DBuilder.finalize(); DBuilder.finalize();

View file

@ -196,10 +196,12 @@ private:
DIType CreateSArrayType(Type *type); DIType CreateSArrayType(Type *type);
DIType CreateAArrayType(Type *type); DIType CreateAArrayType(Type *type);
DISubroutineType CreateFunctionType(Type *type); DISubroutineType CreateFunctionType(Type *type);
DISubroutineType CreateEmptyFunctionType();
DIType CreateDelegateType(Type *type); DIType CreateDelegateType(Type *type);
DIType CreateTypeDescription(Type *type, bool derefclass = false); DIType CreateTypeDescription(Type *type, bool derefclass = false);
bool mustEmitDebugInfo(); bool mustEmitFullDebugInfo();
bool mustEmitLocationsDebugInfo();
public: public:
template <typename T> template <typename T>

View file

@ -0,0 +1,16 @@
// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
// checks that ldc with -gline-tables-only do not emit debug info
// REQUIRES: atleast_llvm309
// reason: different llvm version emits far different metadata in IR code
int main()
{
immutable int fact=6;
int res=1;
for(int i=1; i<=fact; i++) res *= i;
return res;
}
// CHECK-NOT: DW_TAG
// CHECK-NOT: DW_AT

View file

@ -0,0 +1,22 @@
// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
// Checks that ldc with "-gline-tables-only" emits metadata for
// compile unit, subprogram and file.
// Also checks that no type attributes are emitted
// REQUIRES: atleast_llvm309
// reason: different llvm version emits far different metadata in IR code
int main() {
// CHECK: ret i32 0, !dbg
return 0;
}
// CHECK: !llvm.dbg.cu = !{
// CHECK: !DICompileUnit(
// CHECK: !DIFile(
// CHECK: !DISubprogram(
// CHECK-NOT: !DIBasicType(
// CHECK: !DILocation
// CHECK-NOT: !DILocalVariable(
// CHECK-NOT: !DIDerivedType(
// CHECK-NOT: !DIBasicType(

View file

@ -0,0 +1,32 @@
// RUN: %ldc -gline-tables-only --output-ll -c %s -of%t.ll && FileCheck %s < %t.ll
// Checks that ldc with "-gline-tables-only" doesn't emit debug info
// for variables and types.
// CHECK-NOT: DW_TAG_variable
int global = 42;
// CHECK-NOT: DW_TAG_typedef
// CHECK-NOT: DW_TAG_const_type
// CHECK-NOT: DW_TAG_pointer_type
// CHECK-NOT: DW_TAG_array_type
alias constCharPtrArray = const(char)*[10];
// CHECK-NOT: DW_TAG_structure_type
struct S {
// CHECK-NOT: DW_TAG_member
char a;
double b;
constCharPtrArray c;
}
// CHECK-NOT: DW_TAG_enumerator
// CHECK-NOT: DW_TAG_enumeration_type
enum E { ZERO = 0, ONE = 1 }
// CHECK-NOT: DILocalVariable
int sum(int p, int q) {
int r = p + q;
S s;
E e;
return r;
}