Skip to content

Commit

Permalink
[DebugInfo] convert btf_tag attrs to DI annotations for DISubprograms
Browse files Browse the repository at this point in the history
Generate btf_tag annotations for DISubprograms. The annotations
are represented as an DINodeArray in DebugInfo.

Differential Revision: https://reviews.llvm.org/D106618
  • Loading branch information
yonghong-song committed Aug 26, 2021
1 parent a8125bf commit 2de051b
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
11 changes: 8 additions & 3 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Expand Up @@ -3951,10 +3951,13 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
unsigned ScopeLine = getLineNumber(ScopeLoc);
llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
llvm::DISubprogram *Decl = nullptr;
if (D)
llvm::DINodeArray Annotations = nullptr;
if (D) {
Decl = isa<ObjCMethodDecl>(D)
? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
: getFunctionDeclaration(D);
Annotations = CollectBTFTagAnnotations(D);
}

// FIXME: The function declaration we're constructing here is mostly reusing
// declarations from CXXMethodDecl and not constructing new ones for arbitrary
Expand All @@ -3963,7 +3966,8 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
// are emitted as CU level entities by the backend.
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl);
FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
Annotations);
Fn->setSubprogram(SP);
// We might get here with a VarDecl in the case we're generating
// code for the initialization of globals. Do not record these decls
Expand Down Expand Up @@ -4022,10 +4026,11 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
if (CGM.getLangOpts().Optimize)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;

llvm::DINodeArray Annotations = CollectBTFTagAnnotations(D);
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo,
getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
TParamsArray.get(), getFunctionDeclaration(D));
TParamsArray.get(), getFunctionDeclaration(D), nullptr, Annotations);

if (IsDeclForCallSite)
Fn->setSubprogram(SP);
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c
@@ -0,0 +1,19 @@
// REQUIRES: x86-registered-target
// RUN: %clang -target x86_64 -g -S -O2 -emit-llvm -o - %s | FileCheck %s

#define __tag1 __attribute__((btf_tag("tag1")))
#define __tag2 __attribute__((btf_tag("tag2")))

struct t1 {
int a;
};

extern int __tag1 __tag2 foo(struct t1 *);
int foo2(struct t1 *arg) {
return foo(arg);
}

// CHECK: ![[#]] = !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: ![[#]], annotations: ![[ANNOT:[0-9]+]])
// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
40 changes: 40 additions & 0 deletions clang/test/CodeGen/attr-btf_tag-disubprogram.c
@@ -0,0 +1,40 @@
// REQUIRES: x86-registered-target
// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s

#define __tag1 __attribute__((btf_tag("tag1")))
#define __tag2 __attribute__((btf_tag("tag2")))

struct t1 {
int a;
};

int __tag1 __tag2 foo(struct t1 *arg) {
return arg->a;
}

// CHECK: distinct !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: ![[#]], retainedNodes: ![[#]], annotations: ![[ANNOT:[0-9]+]])
// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}

int __tag1 __tag2 foo2(struct t1 *arg);
int foo2(struct t1 *arg) {
return arg->a;
}

// CHECK: distinct !DISubprogram(name: "foo2", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: ![[#]], retainedNodes: ![[#]], annotations: ![[ANNOT]])

int __tag1 foo3(struct t1 *arg);
int __tag2 foo3(struct t1 *arg) {
return arg->a;
}

// CHECK: distinct !DISubprogram(name: "foo3", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: ![[#]], retainedNodes: ![[#]], annotations: ![[ANNOT]])

int __tag1 foo4(struct t1 *arg);
int __tag2 foo4(struct t1 *arg);
int foo4(struct t1 *arg) {
return arg->a;
}

// CHECK: distinct !DISubprogram(name: "foo4", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: ![[#]], retainedNodes: ![[#]], annotations: ![[ANNOT]])

0 comments on commit 2de051b

Please sign in to comment.