Skip to content

Commit

Permalink
[DebugInfo] Generate debug information for labels.
Browse files Browse the repository at this point in the history
Generate DILabel metadata and call llvm.dbg.label after label
statement to associate the metadata with the label.

Differential Revision: https://reviews.llvm.org/D45045

Patch by Hsiangkai Wang.

llvm-svn: 331843
  • Loading branch information
ShivaChen committed May 9, 2018
1 parent cd070cd commit 667fbe2
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 2 deletions.
26 changes: 26 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Expand Up @@ -3647,6 +3647,32 @@ CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage,
return EmitDeclare(VD, Storage, llvm::None, Builder);
}

void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
assert(DebugKind >= codegenoptions::LimitedDebugInfo);
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");

if (D->hasAttr<NoDebugAttr>())
return;

auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
llvm::DIFile *Unit = getOrCreateFile(D->getLocation());

// Get location information.
unsigned Line = getLineNumber(D->getLocation());
unsigned Column = getColumnNumber(D->getLocation());

StringRef Name = D->getName();

// Create the descriptor for the label.
auto *L =
DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize);

// Insert an llvm.dbg.label into the current block.
DBuilder.insertLabel(L,
llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
Builder.GetInsertBlock());
}

llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,
llvm::DIType *Ty) {
llvm::DIType *CachedTy = getTypeOrNull(QualTy);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.h
Expand Up @@ -396,6 +396,9 @@ class CGDebugInfo {
llvm::Value *AI,
CGBuilderTy &Builder);

/// Emit call to \c llvm.dbg.label for an label.
void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder);

/// Emit call to \c llvm.dbg.declare for an imported variable
/// declaration in a block.
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable,
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CGStmt.cpp
Expand Up @@ -531,6 +531,16 @@ void CodeGenFunction::EmitLabel(const LabelDecl *D) {
}

EmitBlock(Dest.getBlock());

// Emit debug info for labels.
if (CGDebugInfo *DI = getDebugInfo()) {
if (CGM.getCodeGenOpts().getDebugInfo() >=
codegenoptions::LimitedDebugInfo) {
DI->setLocation(D->getLocation());
DI->EmitLabel(D, Builder);
}
}

incrementProfileCounter(D->getStmt());
}

Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/backend-unsupported-error.ll
Expand Up @@ -30,11 +30,11 @@ attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fp
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2)
!1 = !DIFile(filename: "test.c", directory: "")
!2 = !{}
!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !2)
!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !2)
!5 = !DISubroutineType(types: !6)
!6 = !{!7}
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
!9 = !{i32 2, !"Dwarf Version", i32 4}
!10 = !{i32 2, !"Debug Info Version", i32 3}
!11 = !{!"clang version 3.9.0"}
Expand Down
28 changes: 28 additions & 0 deletions clang/test/CodeGen/debug-label-inline.c
@@ -0,0 +1,28 @@
// This test will test the correctness of generating DILabel and
// llvm.dbg.label when the label is in inlined functions.
//
// RUN: %clang_cc1 -O2 %s -o - -emit-llvm -debug-info-kind=limited | FileCheck %s
inline int f1(int a, int b) {
int sum;

top:
sum = a + b;
return sum;
}

extern int ga, gb;

int f2(void) {
int result;

result = f1(ga, gb);
// CHECK: call void @llvm.dbg.label(metadata [[LABEL_METADATA:!.*]]), !dbg [[LABEL_LOCATION:!.*]]

return result;
}

// CHECK: distinct !DISubprogram(name: "f1", {{.*}}, retainedNodes: [[ELEMENTS:!.*]])
// CHECK: [[ELEMENTS]] = !{{{.*}}, [[LABEL_METADATA]]}
// CHECK: [[LABEL_METADATA]] = !DILabel({{.*}}, name: "top", {{.*}}, line: 8)
// CHECK: [[INLINEDAT:!.*]] = distinct !DILocation(line: 18,
// CHECK: [[LABEL_LOCATION]] = !DILocation(line: 8, {{.*}}, inlinedAt: [[INLINEDAT]])
16 changes: 16 additions & 0 deletions clang/test/CodeGen/debug-label.c
@@ -0,0 +1,16 @@
// This test will test the correstness of generating DILabel and
// llvm.dbg.label for labels.
//
// RUN: %clang_cc1 -emit-llvm %s -o - -emit-llvm -debug-info-kind=limited | FileCheck %s

int f1(int a, int b) {
int sum;

top:
// CHECK: call void @llvm.dbg.label(metadata [[LABEL_METADATA:!.*]]), !dbg [[LABEL_LOCATION:!.*]]
sum = a + b;
return sum;
}

// CHECK: [[LABEL_METADATA]] = !DILabel({{.*}}, name: "top", {{.*}}, line: 9)
// CHECK: [[LABEL_LOCATION]] = !DILocation(line: 9,

0 comments on commit 667fbe2

Please sign in to comment.