[clang] [Coverage] Suppress covmap and profdata for system headers. (PR #97952)

NAKAMURA Takumi via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 7 07:21:22 PDT 2024


https://github.com/chapuni created https://github.com/llvm/llvm-project/pull/97952

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.

>From 0d87f3b0be84230e40025f221c501f9104fdc261 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 7 Jul 2024 22:48:20 +0900
Subject: [PATCH 1/3] Update clang/test/system_macro.cpp for both
 -system-headers-coverage=true/false

---
 clang/test/CoverageMapping/system_macro.cpp | 32 ++++++++++++++++++---
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/clang/test/CoverageMapping/system_macro.cpp b/clang/test/CoverageMapping/system_macro.cpp
index 725752553bcf7..3909c17a9b5c6 100644
--- a/clang/test/CoverageMapping/system_macro.cpp
+++ b/clang/test/CoverageMapping/system_macro.cpp
@@ -1,4 +1,15 @@
-// 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_WOSYS: [[PROFC:@.*__profc_.*SysTmpl.*]] =
+// LL_W_SYS: @{{.*}}__profd_{{.*}}SysTmpl{{.*}} =
+// LL_WOSYS: @{{.*}}__profd_{{.*}}SysTmpl{{.*}} =
+
+// LL_CHECK: @llvm.used =
 
 #ifdef IS_SYSHEADER
 
@@ -6,6 +17,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: load i64, ptr [[PROFC]],
+
 #else
 
 #define IS_SYSHEADER
@@ -13,15 +30,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

>From 4ca64544720bbbb2fe08877d88bca630bd2fc1ac Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 7 Jul 2024 19:05:59 +0900
Subject: [PATCH 2/3] Move `SystemHeadersCoverage` into `llvm::coverage` in
 CoverageMappingGen.h

---
 clang/lib/CodeGen/CodeGenPGO.cpp         | 4 +---
 clang/lib/CodeGen/CoverageMappingGen.cpp | 8 +++++---
 clang/lib/CodeGen/CoverageMappingGen.h   | 5 +++++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index ea726b5708a4a..6e6dfc4d5a642 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;
 
@@ -1118,7 +1116,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;

>From ccf10c44bf4a90009163a7c54694c8e38ab0dc2d Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 7 Jul 2024 19:17:57 +0900
Subject: [PATCH 3/3] [Coverage] Suppress covmap and profdata for system
 headers.

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.
---
 clang/lib/CodeGen/CodeGenModule.cpp         | 3 +++
 clang/lib/CodeGen/CodeGenPGO.cpp            | 6 +++++-
 clang/test/CoverageMapping/system_macro.cpp | 5 ++---
 3 files changed, 10 insertions(+), 4 deletions(-)

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 6e6dfc4d5a642..cfcdb5911b581 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1044,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);
diff --git a/clang/test/CoverageMapping/system_macro.cpp b/clang/test/CoverageMapping/system_macro.cpp
index 3909c17a9b5c6..38bbb2efb7075 100644
--- a/clang/test/CoverageMapping/system_macro.cpp
+++ b/clang/test/CoverageMapping/system_macro.cpp
@@ -5,9 +5,8 @@
 
 // LL_CHECK: @__covrec_
 // LL_W_SYS: [[PROFC:@.*__profc_.*SysTmpl.*]] =
-// LL_WOSYS: [[PROFC:@.*__profc_.*SysTmpl.*]] =
 // LL_W_SYS: @{{.*}}__profd_{{.*}}SysTmpl{{.*}} =
-// LL_WOSYS: @{{.*}}__profd_{{.*}}SysTmpl{{.*}} =
+// LL_WOSYS-NOT: SysTmpl
 
 // LL_CHECK: @llvm.used =
 
@@ -21,7 +20,7 @@
 template <bool f> bool SysTmpl() { return f; }
 // Check SysTmpl() is instrumented or not.
 // LL_W_SYS: load i64, ptr [[PROFC]],
-// LL_WOSYS: load i64, ptr [[PROFC]],
+// LL_WOSYS-NOT: load i64, ptr @__profc_
 
 #else
 



More information about the cfe-commits mailing list