akhuang created this revision. akhuang added reviewers: rnk, dblaikie. Herald added a subscriber: hiraditya. akhuang requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
In line-tables-only mode, we used to emit qualified function names since the function name was the only thing differentiating different functions. If we switch to emitting forward declarations for the types that appear in function scopes, the total object file size becomes slightly smaller and the display name also becomes more consistent. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D94639 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp clang/test/CodeGenCXX/debug-info-codeview-scopes.cpp llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp llvm/test/DebugInfo/COFF/function-display-name.ll
Index: llvm/test/DebugInfo/COFF/function-display-name.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/COFF/function-display-name.ll @@ -0,0 +1,51 @@ +; RUN: llc -mtriple=i686-pc-win32 -o - -O0 -filetype=obj < %s \ +; RUN: | llvm-readobj --codeview - | FileCheck %s + +; Check that we removed templated args from the display name in full debug mode +; but not with line tables only. + +; CHECK: FuncId (0x1002) { +; CHECK-NEXT: TypeLeafKind: LF_FUNC_ID ({{.*}}) +; CHECK-NEXT: ParentScope: 0x0 +; CHECK-NEXT: FunctionType: void () ({{.*}}) +; CHECK-NEXT: Name: Test()<int> + +; CHECK: FuncId (0x1003) { +; CHECK-NEXT: TypeLeafKind: LF_FUNC_ID ({{.*}}) +; CHECK-NEXT: ParentScope: 0x0 +; CHECK-NEXT: FunctionType: void () ({{.*}}) +; CHECK-NEXT: Name: Test + +; ModuleID = 't.cpp' +source_filename = "t.cpp" +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +define i32 @"?Test1"() !dbg !7 { +entry: + ret i32 0, !dbg !10 +} + +define i32 @"?Test2"() !dbg !13 { +entry: + ret i32 0, !dbg !12 +} + +!llvm.dbg.cu = !{!0, !11} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git b93410cbeaa48fec9a15a23e4770be10abc04d4e)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "<stdin>", directory: "C:\\src\\tests", checksumkind: CSK_MD5, checksum: "a28f11090424d4b37acdde65a98985a1") +!2 = !{} +!3 = !{i32 2, !"CodeView", i32 1} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 2} +!6 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git b93410cbeaa48fec9a15a23e4770be10abc04d4e)"} +!7 = distinct !DISubprogram(name: "Test()<int>", scope: !8, file: !8, line: 19, type: !9, scopeLine: 19, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!8 = !DIFile(filename: "t.cpp", directory: "C:\\src\\tests", checksumkind: CSK_MD5, checksum: "a28f11090424d4b37acdde65a98985a1") +!9 = !DISubroutineType(types: !2) +!10 = !DILocation(line: 25, column: 3, scope: !7) +!11 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!12 = !DILocation(line: 0, column: 0, scope: !13) +!13 = distinct !DISubprogram(name: "Test<int>", scope: !8, file: !8, line: 1, type: !9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !11, retainedNodes: !2) Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -367,8 +367,10 @@ return I->second; // The display name includes function template arguments. Drop them to match - // MSVC. - StringRef DisplayName = SP->getName().split('<').first; + // MSVC, if not using line tables only. + StringRef DisplayName = SP->getName(); + if (SP->getUnit()->getEmissionKind() != DICompileUnit::LineTablesOnly) + DisplayName = SP->getName().split('<').first; const DIScope *Scope = SP->getScope(); TypeIndex TI; Index: clang/test/CodeGenCXX/debug-info-codeview-scopes.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-codeview-scopes.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -debug-info-kind=line-tables-only -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix LINUX %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=line-tables-only -gcodeview -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix MSVC %s + +// Check that we emit type information for function scopes in line tables for +// CodeView. + +namespace A { +void f() {} + +struct S { + static void m() {} +}; +} + +int main() { + A::f(); + A::S::m(); + return 0; + // MSVC: !{{[0-9]+}} = distinct !DISubprogram(name: "f" + // MSVC-SAME: scope: [[SCOPE1:![0-9]+]] + // MSVC-SAME: ) + // MSVC: [[SCOPE1]] = !DINamespace(name: "A", {{.*}}) + // MSVC: !{{[0-9]+}} = distinct !DISubprogram(name: "m" + // MSVC-SAME: scope: [[SCOPE2:![0-9]+]] + // MSVC-SAME: ) + // MSVC: [[SCOPE2]] = !DICompositeType(tag: DW_TAG_structure_type, + // MSVC-SAME: name: "S", + // MSVC-SAME: scope: [[SCOPE1]] + // MSVC-SAME: ) + + // LINUX-NOT: !DINamespace + // LINUX-NOT: !DICompositeType + return 0; +} Index: clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp +++ clang/test/CodeGenCXX/debug-info-codeview-display-name.cpp @@ -20,11 +20,9 @@ namespace N { int b() { return 0; } -// UNQUAL-DAG: "b" -// QUAL-DAG: "N::b" +// CHECK-DAG: "b" namespace { void func() { } } -// UNQUAL-DAG: "func" -// QUAL-DAG: "N::`anonymous namespace'::func" +// CHECK-DAG: "func" } void _c(void) { @@ -35,24 +33,19 @@ struct foo { int operator+(int); foo(){} -// UNQUAL-DAG: "foo" -// QUAL-DAG: "foo::foo" +// CHECK-DAG: "foo" ~foo(){} -// UNQUAL-DAG: "~foo" -// QUAL-DAG: "foo::~foo" +// CHECK-DAG: "~foo" foo(int i){} -// UNQUAL-DAG: "foo" -// QUAL-DAG: "foo::foo" +// CHECK-DAG: "foo" foo(char *q){} -// UNQUAL-DAG: "foo" -// QUAL-DAG: "foo::foo" +// CHECK-DAG: "foo" static foo* static_method() { return 0; } -// UNQUAL-DAG: "static_method" -// QUAL-DAG: "foo::static_method" +// CHECK-DAG: "static_method" }; @@ -61,8 +54,7 @@ foo::static_method(); } -// UNQUAL-DAG: "operator+" -// QUAL-DAG: "foo::operator+" +// CHECK-DAG: "operator+" int foo::operator+(int a) { return a; } // PR17371 @@ -82,17 +74,11 @@ void OverloadedNewDelete::operator delete[](void *) { } int OverloadedNewDelete::operator+(int x) { return x; }; -// UNQUAL-DAG: "operator new" -// UNQUAL-DAG: "operator new[]" -// UNQUAL-DAG: "operator delete" -// UNQUAL-DAG: "operator delete[]" -// UNQUAL-DAG: "operator+" -// QUAL-DAG: "OverloadedNewDelete::operator new" -// QUAL-DAG: "OverloadedNewDelete::operator new[]" -// QUAL-DAG: "OverloadedNewDelete::operator delete" -// QUAL-DAG: "OverloadedNewDelete::operator delete[]" -// QUAL-DAG: "OverloadedNewDelete::operator+" - +// CHECK-DAG: "operator new" +// CHECK-DAG: "operator new[]" +// CHECK-DAG: "operator delete" +// CHECK-DAG: "operator delete[]" +// CHECK-DAG: "operator+" template <typename T, void (*)(void)> void fn_tmpl() {} Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -254,24 +254,12 @@ FunctionTemplateSpecializationInfo *Info = FD->getTemplateSpecializationInfo(); - // Emit the unqualified name in normal operation. LLVM and the debugger can - // compute the fully qualified name from the scope chain. If we're only - // emitting line table info, there won't be any scope chains, so emit the - // fully qualified name here so that stack traces are more accurate. - // FIXME: Do this when emitting DWARF as well as when emitting CodeView after - // evaluating the size impact. - bool UseQualifiedName = DebugKind == codegenoptions::DebugLineTablesOnly && - CGM.getCodeGenOpts().EmitCodeView; - - if (!Info && FII && !UseQualifiedName) + if (!Info && FII) return FII->getName(); SmallString<128> NS; llvm::raw_svector_ostream OS(NS); - if (!UseQualifiedName) - FD->printName(OS); - else - FD->printQualifiedName(OS, getPrintingPolicy()); + FD->printName(OS); // Add any template specialization args. if (Info) { @@ -1058,7 +1046,10 @@ Flags |= llvm::DINode::FlagNonTrivial; // Create the type. - SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); + SmallString<256> Identifier; + // Don't include a linkage name in line tables only. + if (CGM.getCodeGenOpts().hasReducedDebugInfo()) + Identifier = getTypeIdentifier(Ty, CGM, TheCU); llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType( getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align, Flags, Identifier); @@ -2326,6 +2317,9 @@ if (ES->hasExternalDefinitions(RD) == ExternalASTSource::EK_Always) return true; + if (DebugKind == codegenoptions::DebugLineTablesOnly) + return true; + if (DebugKind > codegenoptions::LimitedDebugInfo) return false; @@ -3473,7 +3467,11 @@ DebugKind <= codegenoptions::DebugLineTablesOnly)) LinkageName = StringRef(); - if (CGM.getCodeGenOpts().hasReducedDebugInfo()) { + // Emit the function scope in line tables only mode (if CodeView) to + // differentiate between function names. + if (CGM.getCodeGenOpts().hasReducedDebugInfo() || + (DebugKind == codegenoptions::DebugLineTablesOnly && + CGM.getCodeGenOpts().EmitCodeView)) { if (const NamespaceDecl *NSDecl = dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext())) FDContext = getOrCreateNamespace(NSDecl); @@ -3482,6 +3480,8 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } + } + if (CGM.getCodeGenOpts().hasReducedDebugInfo()) { // Check if it is a noreturn-marked function if (FD->isNoReturn()) Flags |= llvm::DINode::FlagNoReturn;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits