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

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


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: NAKAMURA Takumi (chapuni)

<details>
<summary>Changes</summary>

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
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

``````````

</details>


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


More information about the cfe-commits mailing list