Skip to content

[Coverage] Suppress covmap and profdata for system headers. #97952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 10, 2024

Conversation

chapuni
Copy link
Contributor

@chapuni chapuni commented Jul 7, 2024

With system-headers-coverage=false, functions defined in system headers was not instrumented but corresponding covmap was emitted. It caused wasting covmap and profraw.

This change improves:

  • Reduce object size (due to reduced covmap)
  • Reduce size of profraw (uninstrumented system headers occupied counters)
  • Smarter view of coverage report. Stubs of uninstrumented system headers will be no longer seen.

chapuni added 3 commits July 7, 2024 22:48
With `system-headers-coverage=false`, functions defined in system
headers was not instrumented but corresponding covmap was emitted. It
caused wasting covmap and profraw.

This change improves:

- Reduce object size (due to reduced covmap)
- Reduce size of profraw (uninstrumented system headers occupied counters)
- Smarter view of coverage report. Stubs of uninstrumented system headers
  will be no longer seen.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Jul 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 7, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: NAKAMURA Takumi (chapuni)

Changes

With system-headers-coverage=false, functions defined in system headers was not instrumented but corresponding covmap was emitted. It caused wasting covmap and profraw.

This change improves:

  • Reduce object size (due to reduced covmap)
  • Reduce size of profraw (uninstrumented system headers occupied counters)
  • Smarter view of coverage report. Stubs of uninstrumented system headers will be no longer seen.

Full diff: https://github.com/llvm/llvm-project/pull/97952.diff

5 Files Affected:

  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+3)
  • (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+6-4)
  • (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+5-3)
  • (modified) clang/lib/CodeGen/CoverageMappingGen.h (+5)
  • (modified) clang/test/CoverageMapping/system_macro.cpp (+27-4)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 652f519d82488..b181342b37c3b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -7127,6 +7127,9 @@ void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) {
     SourceManager &SM = getContext().getSourceManager();
     if (LimitedCoverage && SM.getMainFileID() != SM.getFileID(D->getBeginLoc()))
       break;
+    if (!llvm::coverage::SystemHeadersCoverage &&
+        SM.isInSystemHeader(D->getBeginLoc()))
+      break;
     DeferredEmptyCoverageMappingDecls.try_emplace(D, true);
     break;
   }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index ea726b5708a4a..cfcdb5911b581 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -32,8 +32,6 @@ static llvm::cl::opt<bool>
                          llvm::cl::desc("Enable value profiling"),
                          llvm::cl::Hidden, llvm::cl::init(false));
 
-extern llvm::cl::opt<bool> SystemHeadersCoverage;
-
 using namespace clang;
 using namespace CodeGen;
 
@@ -1046,13 +1044,17 @@ void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
   if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
     return;
 
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  if (!llvm::coverage::SystemHeadersCoverage &&
+      SM.isInSystemHeader(D->getLocation()))
+    return;
+
   setFuncName(Fn);
 
   mapRegionCounters(D);
   if (CGM.getCodeGenOpts().CoverageMapping)
     emitCounterRegionMapping(D);
   if (PGOReader) {
-    SourceManager &SM = CGM.getContext().getSourceManager();
     loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
     computeRegionCounts(D);
     applyFunctionAttributes(PGOReader, Fn);
@@ -1118,7 +1120,7 @@ bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
   // Don't map the functions in system headers.
   const auto &SM = CGM.getContext().getSourceManager();
   auto Loc = D->getBody()->getBeginLoc();
-  return !SystemHeadersCoverage && SM.isInSystemHeader(Loc);
+  return !llvm::coverage::SystemHeadersCoverage && SM.isInSystemHeader(Loc);
 }
 
 void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index ba483d857d5f4..67a9caf8b4ec4 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -46,10 +46,12 @@ static llvm::cl::opt<bool> EmptyLineCommentCoverage(
                    "disable it on test)"),
     llvm::cl::init(true), llvm::cl::Hidden);
 
-llvm::cl::opt<bool> SystemHeadersCoverage(
+namespace llvm::coverage {
+cl::opt<bool> SystemHeadersCoverage(
     "system-headers-coverage",
-    llvm::cl::desc("Enable collecting coverage from system headers"),
-    llvm::cl::init(false), llvm::cl::Hidden);
+    cl::desc("Enable collecting coverage from system headers"), cl::init(false),
+    cl::Hidden);
+}
 
 using namespace clang;
 using namespace CodeGen;
diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h
index f7c59c48c1839..fe4b93f3af856 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.h
+++ b/clang/lib/CodeGen/CoverageMappingGen.h
@@ -19,8 +19,13 @@
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/GlobalValue.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 
+namespace llvm::coverage {
+extern cl::opt<bool> SystemHeadersCoverage;
+}
+
 namespace clang {
 
 class LangOptions;
diff --git a/clang/test/CoverageMapping/system_macro.cpp b/clang/test/CoverageMapping/system_macro.cpp
index 725752553bcf7..38bbb2efb7075 100644
--- a/clang/test/CoverageMapping/system_macro.cpp
+++ b/clang/test/CoverageMapping/system_macro.cpp
@@ -1,4 +1,14 @@
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -mllvm -system-headers-coverage -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name system_macro.cpp -o - %s | FileCheck %s
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -mllvm -system-headers-coverage=true -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm -main-file-name system_macro.cpp -o %t.w_sys.ll %s | FileCheck %s --check-prefixes=CHECK,W_SYS
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -mllvm -system-headers-coverage=false -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm -main-file-name system_macro.cpp -o %t.wosys.ll %s | FileCheck %s --check-prefixes=CHECK,WOSYS
+// RUN: FileCheck %s --check-prefixes=LL_CHECK,LL_W_SYS < %t.w_sys.ll
+// RUN: FileCheck %s --check-prefixes=LL_CHECK,LL_WOSYS < %t.wosys.ll
+
+// LL_CHECK: @__covrec_
+// LL_W_SYS: [[PROFC:@.*__profc_.*SysTmpl.*]] =
+// LL_W_SYS: @{{.*}}__profd_{{.*}}SysTmpl{{.*}} =
+// LL_WOSYS-NOT: SysTmpl
+
+// LL_CHECK: @llvm.used =
 
 #ifdef IS_SYSHEADER
 
@@ -6,6 +16,12 @@
 #define Func(x) if (x) {}
 #define SomeType int
 
+// LL_CHECK: define {{.*}} i1 @{{.*}}SysTmpl
+template <bool f> bool SysTmpl() { return f; }
+// Check SysTmpl() is instrumented or not.
+// LL_W_SYS: load i64, ptr [[PROFC]],
+// LL_WOSYS-NOT: load i64, ptr @__profc_
+
 #else
 
 #define IS_SYSHEADER
@@ -13,15 +29,22 @@
 
 // CHECK-LABEL: doSomething
 void doSomething(int x) { // CHECK: File 0, [[@LINE]]:25 -> {{[0-9:]+}} = #0
-  Func(x); // CHECK: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:7
+  // WOSYS-NOT: Expansion,
+  // W_SYS: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:7
+  Func(x);
+  // CHECK: Gap,File 0, [[@LINE+1]]:10
   return;
-  // CHECK: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:11
+  // WOSYS-NOT: Expansion,
+  // W_SYS: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:11
   SomeType *f; // CHECK: File 0, [[@LINE]]:11 -> {{[0-9:]+}} = 0
 }
 
 // CHECK-LABEL: main
 int main() { // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:2 = #0
-  Func([] { return true; }());
+  Func([] { return SysTmpl<true>(); }());
 }
 
+// W_SYS: SysTmpl
+// WOSYS-NOT: SysTmpl
+
 #endif

Copy link
Contributor

@hanickadot hanickadot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link

@ornata ornata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

chapuni added a commit that referenced this pull request Jul 9, 2024
chapuni added a commit that referenced this pull request Jul 9, 2024
Conflicts:
	clang/test/CoverageMapping/system_macro.cpp
@chapuni chapuni merged commit da31b68 into llvm:main Jul 10, 2024
7 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 10, 2024

LLVM Buildbot has detected a new failure on builder clang-x86_64-debian-fast running on gribozavr4 while building clang at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/1996

Here is the relevant piece of the build log for the reference:

Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'Clang :: CodeGen/aarch64-targetattr.c' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 2: /b/1/clang-x86_64-debian-fast/llvm.obj/bin/clang -cc1 -internal-isystem /b/1/clang-x86_64-debian-fast/llvm.obj/lib/clang/19/include -nostdsysteminc -triple aarch64 -emit-llvm /b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c -o - | /b/1/clang-x86_64-debian-fast/llvm.obj/bin/FileCheck /b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c
+ /b/1/clang-x86_64-debian-fast/llvm.obj/bin/FileCheck /b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c
+ /b/1/clang-x86_64-debian-fast/llvm.obj/bin/clang -cc1 -internal-isystem /b/1/clang-x86_64-debian-fast/llvm.obj/lib/clang/19/include -nostdsysteminc -triple aarch64 -emit-llvm /b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c -o -
/b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c:210:11: error: CHECK: expected string not found in input
// CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="true" "guarded-control-stack"="true" "no-trapping-math"="true" "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
          ^
<stdin>:176:367: note: scanning from here
attributes #14 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
                                                                                                                                                                                                                                                                                                                                                                              ^
<stdin>:176:367: note: with "ATTR15" equal to "15"
attributes #14 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" }
                                                                                                                                                                                                                                                                                                                                                                              ^

Input file: <stdin>
Check file: /b/1/clang-x86_64-debian-fast/llvm.src/clang/test/CodeGen/aarch64-targetattr.c

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             .
             .
             .
           171: attributes #9 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+sve" "tune-cpu"="cortex-a710" } 
           172: attributes #10 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" } 
           173: attributes #11 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-v1" "target-features"="+aes,+bf16,+ccdp,+complxnum,+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+rand,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+spe,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a,-sve" } 
           174: attributes #12 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+sve" } 
           175: attributes #13 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16" } 
           176: attributes #14 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } 
check:210'0                                                                                                                                                                                                                                                                                                                                                                                   X error: no match found
check:210'1                                                                                                                                                                                                                                                                                                                                                                                     with "ATTR15" equal to "15"
           177: attributes #15 = { noinline nounwind optnone "branch-target-enforcement" "guarded-control-stack" "no-trapping-math"="true" "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" "target-features"="+aes,+bf16,+complxnum,+crc,+dotprod,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+ras,+rcpc,+rdm,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a" "tune-cpu"="cortex-a710" } 
check:210'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           178: attributes #16 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } 
check:210'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           179: attributes #17 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.3a" } 
check:210'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           180:  
check:210'0     ~
           181: !llvm.module.flags = !{!0} 
check:210'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
             .
             .
             .
>>>>>>
...

aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
With `system-headers-coverage=false`, functions defined in system
headers were not instrumented but corresponding covmaps were emitted. It
caused wasting covmap and profraw.

This change improves:

- Reduce object size (due to reduced covmap)
- Reduce size of profraw (uninstrumented system headers occupied
counters)
- Smarter view of coverage report. Stubs of uninstrumented system
headers will be no longer seen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants