[PATCH] D49916: [CodeGen] Add to emitted DebugLoc information about coverage when it's required

2018-08-29 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 163062.
calixte added a comment.

- Use ImplicitCode instead of Covered
- Set Artificial location as ImplicitCode to avoid coverage on landing pads


Repository:
  rC Clang

https://reviews.llvm.org/D49916

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h

Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -786,7 +786,7 @@
   // If we should perform a cleanup, force them now.  Note that
   // this ends the cleanup scope before rescoping any labels.
   if (PerformCleanup) {
-ApplyDebugLocation DL(CGF, Range.getEnd());
+ApplyDebugLocation DL(CGF, Range.getEnd(), true /* ImplicitCode */);
 ForceCleanup();
   }
 }
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1179,7 +1179,7 @@
   }
   // Emit a location at the end of the prologue.
   if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitLocation(Builder, StartLoc);
+DI->EmitLocation(Builder, StartLoc, true /* ImplicitCode */);
 
   // TODO: Do we need to handle this in two places like we do with
   // target-features/target-cpu?
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -377,7 +377,9 @@
   /// Emit metadata to indicate a change in line/column information in
   /// the source file. If the location is invalid, the previous
   /// location will be reused.
-  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
+  /// \param ImplicitCode  True if the Loc must have coverage information
+  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
+bool ImplicitCode = false);
 
   /// Emit a call to llvm.dbg.function.start to indicate
   /// start of a new function.
@@ -657,16 +659,19 @@
 /// location or preferred location of the specified Expr.
 class ApplyDebugLocation {
 private:
-  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false);
+  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false,
+bool ImplicitCode = false);
   ApplyDebugLocation(CodeGenFunction &CGF, bool DefaultToEmpty,
- SourceLocation TemporaryLocation);
+ SourceLocation TemporaryLocation,
+ bool ImplicitCode = false);
 
   llvm::DebugLoc OriginalLocation;
   CodeGenFunction *CGF;
 
 public:
   /// Set the location to the (valid) TemporaryLocation.
-  ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation);
+  ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation,
+ bool ImplicitCode = false);
   ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E);
   ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc);
   ApplyDebugLocation(ApplyDebugLocation &&Other) : CGF(Other.CGF) {
@@ -687,15 +692,17 @@
   /// SourceLocation to CGDebugInfo::setLocation() will result in the
   /// last valid location being reused.
   static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF) {
-return ApplyDebugLocation(CGF, false, SourceLocation());
+return ApplyDebugLocation(CGF, false, SourceLocation(),
+  true /* ImplicitCode */);
   }
   /// Apply TemporaryLocation if it is valid. Otherwise switch
   /// to an artificial debug location that has a valid scope, but no
   /// line information.
   static ApplyDebugLocation
   CreateDefaultArtificial(CodeGenFunction &CGF,
   SourceLocation TemporaryLocation) {
-return ApplyDebugLocation(CGF, false, TemporaryLocation);
+return ApplyDebugLocation(CGF, false, TemporaryLocation,
+  true /* ImplicitCode */);
   }
 
   /// Set the IRBuilder to not attach debug locations.  Note that
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -76,20 +76,22 @@
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
-   SourceLocation TemporaryLocation)
+   SourceLocation TemporaryLocation,
+   bool ImplicitCode)
 : CGF(&CGF) {
-  init(TemporaryLocation);
+  init(TemporaryLocation, false /* DefaultToEmpty */, ImplicitCode);
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
bool DefaultToEmpty,
-   SourceLocation TemporaryLocation)
+   SourceLocation TemporaryLocation,
+   

[PATCH] D49916: [CodeGen] Add to emitted DebugLoc information about coverage when it's required

2018-09-11 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 164851.
calixte added a comment.

- Add some ImplicitCode when there is some stuff at the end of a function
- Fix the tests


Repository:
  rC Clang

https://reviews.llvm.org/D49916

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/debug-info-scope-file.c
  test/CodeGenCXX/debug-info-inheriting-constructor.cpp
  test/CodeGenCXX/debug-info-nested-exprs.cpp
  test/CodeGenCXX/linetable-virtual-variadic.cpp
  test/CodeGenObjC/arc-linetable.m
  test/CodeGenObjC/debug-info-blocks.m

Index: test/CodeGenObjC/debug-info-blocks.m
===
--- test/CodeGenObjC/debug-info-blocks.m
+++ test/CodeGenObjC/debug-info-blocks.m
@@ -18,11 +18,9 @@
 // CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[COPY_LINE:[0-9]+]]
-// CHECK: ret void, !dbg ![[COPY_LINE]]
 // CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*)
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
-// CHECK: ret void, !dbg ![[DESTROY_LINE]]
 
 typedef unsigned int NSUInteger;
 
Index: test/CodeGenObjC/arc-linetable.m
===
--- test/CodeGenObjC/arc-linetable.m
+++ test/CodeGenObjC/arc-linetable.m
@@ -60,7 +60,8 @@
 - (int)testNoSideEffect:(NSString *)foo {
   int x = 1;
   return 1; // Return expression
-  // CHECK: ![[RET1]] = !DILocation(line: [[@LINE+1]], scope: ![[TESTNOSIDEEFFECT]])
+  // CHECK: ![[RET1]] = !DILocation(line: [[@LINE+1]], scope:
+  // ![[TESTNOSIDEEFFECT]], isImplicitCode: true)
 }   // Cleanup + Ret
 
 - (int)testNoCleanup {
Index: test/CodeGenCXX/linetable-virtual-variadic.cpp
===
--- test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -11,12 +11,12 @@
 
 void Derived::VariadicFunction(...) { }
 
-// CHECK: define void @_ZN7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP:[0-9]+]]
-// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
-// CHECK: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP_I:[0-9]+]]
-// CHECK: ret void, !dbg ![[LOC_I:[0-9]+]]
+// CHECK: define void @_ZN7Derived16VariadicFunctionEz({{.*}} !dbg
+// ![[SP:[0-9]+]] CHECK: ret void, !dbg ![[LOC:[0-9]+]] CHECK: define void
+// @_ZT{{.+}}N7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP_I:[0-9]+]] CHECK:
+// ret void, !dbg ![[LOC_I:[0-9]+]]
 //
 // CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
-// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
+// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]], isImplicitCode: true)
 // CHECK: ![[SP_I]] = distinct !DISubprogram(name: "VariadicFunction"
-// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]])
+// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]], isImplicitCode: true)
Index: test/CodeGenCXX/debug-info-nested-exprs.cpp
===
--- test/CodeGenCXX/debug-info-nested-exprs.cpp
+++ test/CodeGenCXX/debug-info-nested-exprs.cpp
@@ -37,7 +37,6 @@
   // NESTED: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
   // NESTED: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
   // NESTED: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
-  // NESTED: store i32 {{.*}}, i32* %a,{{.*}} !dbg ![[BAR]]
   // COLUMNS: call i32 @{{.*}}bar{{.*}}, !dbg ![[BAR:[0-9]+]]
   // COLUMNS: call i32 @{{.*}}baz{{.*}}, !dbg ![[BAZ:[0-9]+]]
   // COLUMNS: call i32 @{{.*}}qux{{.*}}, !dbg ![[QUX:[0-9]+]]
@@ -98,7 +97,6 @@
   // NONEST: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
   // NESTED: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
   // NESTED: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DECLD:[0-9]+]]
-  // NESTED: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD]]
   // COLUMNS: call i32 @{{.*}}noargs{{.*}}, !dbg ![[DNOARGS:[0-9]+]]
   // COLUMNS: call i32 @{{.*}}onearg{{.*}}, !dbg ![[DONEARG:[0-9]+]]
   // COLUMNS: store i32 %{{[^,]+}}, i32* %d,{{.*}} !dbg ![[DECLD:[0-9]+]]
@@ -178,16 +176,16 @@
 // NESTED: ![[RETSUB]] = !DILocation(
 // NESTED: ![[RETMUL]] = !DILocation(
 
-// COLUMNS: ![[DECLA]] = !DILocation(
 // COLUMNS: ![[BAR]] = !DILocation(
 // COLUMNS: ![[BAZ]] = !DILocation(
 // COLUMNS: ![[QUX]] = !DILocation(
+// COLUMNS: ![[DECLA]] = !DILocation(
 // COLUMNS: ![[ILOC]] = !DILocation(
 // COLUMNS: ![[BLOC]] = !DILocation(
 // COLUMNS: ![[CLOC]] = !DILocation(
-// COLUMNS: ![[DECLD]] = !DILocation(
 // COLUMNS: ![[DNOARGS]] = !DILocation(
 // COLUMNS: ![[DONEARG]] = !DILocation(
+// COLUMNS: ![[DECLD]] = !DILocation(
 // COLUMNS: ![[SETDNOARGS]] = !DILocation(
 // COLUMNS: ![[SETDONEARG]] = !DILocation(
 // COLUMNS: ![[SETD]] = !DILocation(
Index: test/CodeGenCXX/debug-info-inheriting-constructor.cpp
===
--- test/CodeGenCXX/de

[PATCH] D49916: [CodeGen] Add to emitted DebugLoc information about coverage when it's required

2018-09-11 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 164860.
calixte added a comment.

- only put an ImplicitCode for EmitLandingPad
- fix tests (were broken with clanf-format-diff)


Repository:
  rC Clang

https://reviews.llvm.org/D49916

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/debug-info-scope-file.c
  test/CodeGenCXX/debug-info-inheriting-constructor.cpp
  test/CodeGenCXX/linetable-virtual-variadic.cpp
  test/CodeGenObjC/arc-linetable.m
  test/CodeGenObjC/debug-info-blocks.m

Index: test/CodeGenObjC/debug-info-blocks.m
===
--- test/CodeGenObjC/debug-info-blocks.m
+++ test/CodeGenObjC/debug-info-blocks.m
@@ -18,11 +18,9 @@
 // CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[COPY_LINE:[0-9]+]]
-// CHECK: ret void, !dbg ![[COPY_LINE]]
 // CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*)
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
-// CHECK: ret void, !dbg ![[DESTROY_LINE]]
 
 typedef unsigned int NSUInteger;
 
Index: test/CodeGenObjC/arc-linetable.m
===
--- test/CodeGenObjC/arc-linetable.m
+++ test/CodeGenObjC/arc-linetable.m
@@ -60,7 +60,7 @@
 - (int)testNoSideEffect:(NSString *)foo {
   int x = 1;
   return 1; // Return expression
-  // CHECK: ![[RET1]] = !DILocation(line: [[@LINE+1]], scope: ![[TESTNOSIDEEFFECT]])
+  // CHECK: ![[RET1]] = !DILocation(line: [[@LINE+1]], scope: ![[TESTNOSIDEEFFECT]], isImplicitCode: true)
 }   // Cleanup + Ret
 
 - (int)testNoCleanup {
Index: test/CodeGenCXX/linetable-virtual-variadic.cpp
===
--- test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -17,6 +17,6 @@
 // CHECK: ret void, !dbg ![[LOC_I:[0-9]+]]
 //
 // CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
-// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
+// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]], isImplicitCode: true)
 // CHECK: ![[SP_I]] = distinct !DISubprogram(name: "VariadicFunction"
-// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]])
+// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]], isImplicitCode: true)
Index: test/CodeGenCXX/debug-info-inheriting-constructor.cpp
===
--- test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -21,5 +21,5 @@
 // CHECK-DAG: ![[LOC]] = !DILocation(line: 0, scope: ![[A]], inlinedAt: ![[INL:[0-9]+]])
 // CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], scope: ![[FOO]])
   B b(0);
-// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}})
+  // CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}}, isImplicitCode: true)
 }
Index: test/CodeGen/debug-info-scope-file.c
===
--- test/CodeGen/debug-info-scope-file.c
+++ test/CodeGen/debug-info-scope-file.c
@@ -5,10 +5,11 @@
 
 // CHECK: ret void, !dbg [[F1_LINE:![0-9]*]]
 // CHECK: ret void, !dbg [[F2_LINE:![0-9]*]]
-// CHECK: [[F1:![0-9]*]] = distinct !DISubprogram(name: "f1",{{.*}} isDefinition: true
-// CHECK: [[F1_LINE]] = !DILocation({{.*}}, scope: [[F1]])
-// CHECK: [[F2:![0-9]*]] = distinct !DISubprogram(name: "f2",{{.*}} isDefinition: true
-// CHECK: [[F2_LINE]] = !DILocation({{.*}}, scope: [[F2]])
+// CHECK: [[F1:![0-9]*]] = distinct !DISubprogram(name: "f1",{{.*}}
+// isDefinition: true CHECK: [[F1_LINE]] = !DILocation({{.*}}, scope: [[F1]],
+// isImplicitCode: true) CHECK: [[F2:![0-9]*]] = distinct !DISubprogram(name:
+// "f2",{{.*}} isDefinition: true CHECK: [[F2_LINE]] = !DILocation({{.*}},
+// scope: [[F2]], isImplicitCode: true)
 
 void f1() {
 }
Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -786,7 +786,7 @@
   // If we should perform a cleanup, force them now.  Note that
   // this ends the cleanup scope before rescoping any labels.
   if (PerformCleanup) {
-ApplyDebugLocation DL(CGF, Range.getEnd());
+ApplyDebugLocation DL(CGF, Range.getEnd(), true /* ImplicitCode */);
 ForceCleanup();
   }
 }
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -317,7 +317,7 @@
 if (OnlySimpleReturnStmts)
   DI->EmitLocation(Builder, LastStopPoint);
 else
-  DI->EmitLocation(Builder, EndLoc);
+  DI->EmitLocation(Builder, EndLoc, true /* ImplicitCode */);
   }
 
   // Pop any cleanups that might have be

[PATCH] D51945: [Clang] Fix test to followup https://reviews.llvm.org/rL341977

2018-09-11 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: vsk.
Herald added a subscriber: cfe-commits.

In the previous patch, __llvm_gcov_indirect_counter_increment has been removed.


Repository:
  rC Clang

https://reviews.llvm.org/D51945

Files:
  test/CodeGen/code-coverage.c


Index: test/CodeGen/code-coverage.c
===
--- test/CodeGen/code-coverage.c
+++ test/CodeGen/code-coverage.c
@@ -40,8 +40,7 @@
 
 // Check that the noredzone flag is set on the generated functions.
 
-// CHECK: void @__llvm_gcov_indirect_counter_increment(i32* %{{.*}}, i64** 
%{{.*}}) unnamed_addr [[NRZ:#[0-9]+]]
-// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ]]
+// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ:#[0-9]+]]
 // CHECK: void @__llvm_gcov_flush() unnamed_addr [[NRZ]]
 // CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]]
 


Index: test/CodeGen/code-coverage.c
===
--- test/CodeGen/code-coverage.c
+++ test/CodeGen/code-coverage.c
@@ -40,8 +40,7 @@
 
 // Check that the noredzone flag is set on the generated functions.
 
-// CHECK: void @__llvm_gcov_indirect_counter_increment(i32* %{{.*}}, i64** %{{.*}}) unnamed_addr [[NRZ:#[0-9]+]]
-// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ]]
+// CHECK: void @__llvm_gcov_writeout() unnamed_addr [[NRZ:#[0-9]+]]
 // CHECK: void @__llvm_gcov_flush() unnamed_addr [[NRZ]]
 // CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]]
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51945: [Clang] Fix test to followup https://reviews.llvm.org/rL341977

2018-09-11 Thread calixte via Phabricator via cfe-commits
calixte added a comment.

My bad, I missed that


Repository:
  rC Clang

https://reviews.llvm.org/D51945



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-09-13 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added reviewers: marco-c, vsk.
Herald added a subscriber: cfe-commits.

These options are taking regex separated by colons to filter files.

- if both are empty then all files are instrumented
- if -coverage-filter is empty then all the filenames matching any of the regex 
from exclude are not instrumented
- if -coverage-exclude is empty then all the filenames matching any of the 
regex from filter are instrumented
- if both aren't empty then all the filenames which match any of the regex in 
filter and which don't match all the regex in filter are instrumented
- this patch is a follow-up of https://reviews.llvm.org/D52033


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-exclude=.*\\.h %s -o - \
+// RUN:| FileCheck -check-prefix=NOH %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-filter=.*\\.c %s -o - \
+// RUN:| FileCheck -check-prefix=NOH %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-filter=.*\\.c %s -o - \
+// RUN:| FileCheck -check-prefix=NOH %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-filter=.*\\.c:.*1\\.h %s -o - \
+// RUN:| FileCheck -check-prefix=NOH2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-exclude=.*2\\.h:.*1\\.h %s -o - \
+// RUN:| FileCheck -check-prefix=C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-exclude=.*code\\-coverage\\-filter\\.c %s -o - \
+// RUN:| FileCheck -check-prefix=H %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-filter=.*\\.c -coverage-exclude=.*\\.c %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -coverage-filter=.*\\.c -coverage-exclude=.*\\.h %s -o - \
+// RUN:| FileCheck -check-prefix=C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+int test(int a) {
+int x = 0;
+if (a == 1) {
+x = test1(a) + test2(a);
+}
+
+return x;
+}
+
+// ALL: define i32 @test1(i32 %x) #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret i32 {{.*}}
+// ALL: define i32 @test2(i32 %x) #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret i32 {{.*}}
+// ALL: define i32 @test(i32 %a) #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret i32 {{.*}}
+
+// NOH: define i32 @test1(i32 %x) #0 {{.*}}
+// NOH-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH: ret i32 {{.*}}
+// NOH: define i32 @test2(i32 %x) #0 {{.*}}
+// NOH-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH: ret i32 {{.*}}
+// NOH: define i32 @test(i32 %a) #0 {{.*}}
+// NOH: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH: ret i32 {{.*}}
+
+// NOH2: define i32 @test1(i32 %x) #0 {{.*}}
+// NOH2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH2: ret i32 {{.*}}
+// NOH2: define i32 @test2(i32 %x) #0 {{.*}}
+// NOH2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH2: ret i32 {{.*}}
+// NOH2: define i32 @test(i32 %a) #0 {{.*}}
+// NOH2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NOH2: ret i32 {{.*}}
+
+// C: define i32 @test1(i32 %x) #0 {{.*}}
+// C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// C: ret i32 {{.*}}
+// C: define i32 @test2(i32 %x) #0 {{.*}}
+// C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// C: ret i32 {{.*}}
+// C: define i32 @test(i32 %a) #0 {{.*}}
+// C: {{.*}}__llvm_gcov_ctr{{.*}}
+// C: ret i32 {{.*}}
+
+// H: define i32 @test1(i32 %x) #0 {{.*}}
+// H: {{.*}}__llvm_gcov_ctr{{.*}}
+// H: ret i32 {{.*}}
+// H: define i32 @test2(i32 %x) #0 {{.*}}
+// H: {{.*}}__llvm_gcov_ctr{{.*}}
+// H: ret i32 {{.*}}
+// H: define i32 @test(i32 %a) #0 {{.*}}
+// H-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// H: ret i32 {{.*}}
+
+// NONE: define i32 @test1(i32 %x) #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret i32 {{.*}}
+// NONE: define i32 @test2(i32 %x) #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret i32 {{.*}}
+// NONE: define i32 @test(i32 %a) #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret i32 {{.*}}
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1,6 @@
+int test2(int x) {
+if (x >= 1) {
+return x + 1;
+}
+return x;
+}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ 

[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-09-13 Thread calixte via Phabricator via cfe-commits
calixte added inline comments.



Comment at: include/clang/Driver/CC1Options.td:236
+def coverage_exclude_EQ : Joined<["-"], "coverage-exclude=">,
+  Alias;
 def coverage_exit_block_before_body : Flag<["-"], 
"coverage-exit-block-before-body">,

vsk wrote:
> Have you checked whether gcc supports similar options? If so, it would be 
> great if we could match their name & behavior.
The only one I found -finstrument-functions-exclude-file-list 
(https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html).
But no regex and no way to include one file only.
I took the names from gcovr: 
https://manpages.debian.org/jessie/gcovr/gcovr.1.en.html


Repository:
  rC Clang

https://reviews.llvm.org/D52034



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49916: [CodeGen] Add to emitted DebugLoc information about coverage when it's required

2018-07-27 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added reviewers: marco-c, davidxl.
Herald added a subscriber: cfe-commits.

Some lines have a hit counter where they should not have one.
Cleanup stuff is located to the last line of the body which is most of the time 
a '}'.
And Exception stuff is added at the beginning of a function and at the end 
(represented by '{' and '}').
So in such cases, the DebugLoc used in GCOVProfiling.cpp must be marked as not 
covered.
This patch is a followup of https://reviews.llvm.org/D49915.


Repository:
  rC Clang

https://reviews.llvm.org/D49916

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h

Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -785,7 +785,7 @@
   // If we should perform a cleanup, force them now.  Note that
   // this ends the cleanup scope before rescoping any labels.
   if (PerformCleanup) {
-ApplyDebugLocation DL(CGF, Range.getEnd());
+ApplyDebugLocation DL(CGF, Range.getEnd(), false /* Covered */);
 ForceCleanup();
   }
 }
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1174,7 +1174,7 @@
   }
   // Emit a location at the end of the prologue.
   if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitLocation(Builder, StartLoc);
+DI->EmitLocation(Builder, StartLoc, false /* Covered */);
 
   // TODO: Do we need to handle this in two places like we do with
   // target-features/target-cpu?
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -361,7 +361,8 @@
   /// Emit metadata to indicate a change in line/column information in
   /// the source file. If the location is invalid, the previous
   /// location will be reused.
-  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
+  /// \param Covered   True if the Loc must have coverage information 
+  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc, bool Covered = true);
 
   /// Emit a call to llvm.dbg.function.start to indicate
   /// start of a new function.
@@ -641,16 +642,16 @@
 /// location or preferred location of the specified Expr.
 class ApplyDebugLocation {
 private:
-  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false);
+  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false, bool Covered = true);
   ApplyDebugLocation(CodeGenFunction &CGF, bool DefaultToEmpty,
  SourceLocation TemporaryLocation);
 
   llvm::DebugLoc OriginalLocation;
   CodeGenFunction *CGF;
 
 public:
   /// Set the location to the (valid) TemporaryLocation.
-  ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation);
+  ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation, bool Covered = true);
   ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E);
   ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc);
   ApplyDebugLocation(ApplyDebugLocation &&Other) : CGF(Other.CGF) {
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -76,9 +76,10 @@
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
-   SourceLocation TemporaryLocation)
+   SourceLocation TemporaryLocation,
+   bool Covered)
 : CGF(&CGF) {
-  init(TemporaryLocation);
+  init(TemporaryLocation, false /* DefaultToEmpty */, Covered);
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
@@ -89,7 +90,8 @@
 }
 
 void ApplyDebugLocation::init(SourceLocation TemporaryLocation,
-  bool DefaultToEmpty) {
+  bool DefaultToEmpty,
+  bool Covered) {
   auto *DI = CGF->getDebugInfo();
   if (!DI) {
 CGF = nullptr;
@@ -102,7 +104,7 @@
 return;
 
   if (TemporaryLocation.isValid()) {
-DI->EmitLocation(CGF->Builder, TemporaryLocation);
+DI->EmitLocation(CGF->Builder, TemporaryLocation, Covered);
 return;
   }
 
@@ -3444,16 +3446,16 @@
   setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
 }
 
-void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
+void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc, bool Covered) {
   // Update our current location
   setLocation(Loc);
 
   if (CurLoc.isInvalid() || CurLoc.isMacroID())
 return;
 
   llvm::MDNode *Scope = LexicalBlockStack.back();
   Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-  getLineNumber(CurLoc)

[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-10-18 Thread calixte via Phabricator via cfe-commits
calixte added a comment.

@vsk, gcc guys are ok for -fprofile-filter-files and  -fprofile-exclude-files, 
are you ok with that ?
Should these options prefixed by -Xclang or not ?


Repository:
  rC Clang

https://reviews.llvm.org/D52034



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53578: [CodeGen] Fix clang test for gcov profiling (follow-up of D51974)

2018-10-23 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: vsk.
Herald added a subscriber: cfe-commits.

After patch https://reviews.llvm.org/D51974 has landed, this one is required to 
fix a test.


Repository:
  rC Clang

https://reviews.llvm.org/D53578

Files:
  test/CodeGen/code-coverage.c


Index: test/CodeGen/code-coverage.c
===
--- test/CodeGen/code-coverage.c
+++ test/CodeGen/code-coverage.c
@@ -29,14 +29,10 @@
 
 // Inside function emission data structure, check that
 // -coverage-no-function-names-in-data uses null as the function name.
-// CHECK: @__llvm_internal_gcov_emit_function_args.0 = internal unnamed_addr 
constant
-// CHECK-SAME: { i32 {{[0-9]+}}, i8* getelementptr inbounds ({{[^,]*}}, 
{{[^,]*}}* @
-// CHECK-SAME: { i32 {{[0-9]+}}, i8* getelementptr inbounds ({{[^,]*}}, 
{{[^,]*}}* @
-// WITHOUTNAMES: @__llvm_internal_gcov_emit_function_args.0 = internal 
unnamed_addr constant
-// WITHOUTNAMES-NOT: getelementptr inbounds ({{.*}}@
-// WITHOUTNAMES-SAME: zeroinitializer,
-// WITHOUTNAMES-NOT: getelementptr inbounds ({{.*}}@
-// WITHOUTNAMES-SAME: { i32 {{[0-9]+}}, i8* null,
+// CHECK: {{.*}} private unnamed{{.*}}test1\00{{.*}}
+// CHECK: {{.*}} private unnamed{{.*}}test2\00{{.*}}
+// WITHOUTNAMES-NOT: {{.*}} private unnamed{{.*}}test1\00{{.*}}
+// WITHOUTNAMES-NOT: {{.*}} private unnamed{{.*}}test2\00{{.*}}
 
 // Check that the noredzone flag is set on the generated functions.
 


Index: test/CodeGen/code-coverage.c
===
--- test/CodeGen/code-coverage.c
+++ test/CodeGen/code-coverage.c
@@ -29,14 +29,10 @@
 
 // Inside function emission data structure, check that
 // -coverage-no-function-names-in-data uses null as the function name.
-// CHECK: @__llvm_internal_gcov_emit_function_args.0 = internal unnamed_addr constant
-// CHECK-SAME: { i32 {{[0-9]+}}, i8* getelementptr inbounds ({{[^,]*}}, {{[^,]*}}* @
-// CHECK-SAME: { i32 {{[0-9]+}}, i8* getelementptr inbounds ({{[^,]*}}, {{[^,]*}}* @
-// WITHOUTNAMES: @__llvm_internal_gcov_emit_function_args.0 = internal unnamed_addr constant
-// WITHOUTNAMES-NOT: getelementptr inbounds ({{.*}}@
-// WITHOUTNAMES-SAME: zeroinitializer,
-// WITHOUTNAMES-NOT: getelementptr inbounds ({{.*}}@
-// WITHOUTNAMES-SAME: { i32 {{[0-9]+}}, i8* null,
+// CHECK: {{.*}} private unnamed{{.*}}test1\00{{.*}}
+// CHECK: {{.*}} private unnamed{{.*}}test2\00{{.*}}
+// WITHOUTNAMES-NOT: {{.*}} private unnamed{{.*}}test1\00{{.*}}
+// WITHOUTNAMES-NOT: {{.*}} private unnamed{{.*}}test2\00{{.*}}
 
 // Check that the noredzone flag is set on the generated functions.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-11-06 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 172752.
calixte added a comment.

Change options names to -fprofile-exclude-files & -fprofile-filter-files and 
add some doc in UserManual.


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$:.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*2\.h$:.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,6 +811,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverag

[PATCH] D52034: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov

2018-11-06 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 172761.
calixte added a comment.

Fix plural form of regex and just use ';' as separator.


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,6 +811,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.ProfileFil

[PATCH] D52034: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov

2018-11-07 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 172905.
calixte added a comment.

Update doc.


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,6 +811,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.ProfileFilterFiles =
+Args.getLastArgValue(OPT

[PATCH] D52034: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov

2018-11-12 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 173622.
calixte added a comment.

Update ReleaseNotes


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/ReleaseNotes.rst
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,6 +811,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.ProfileFilterFiles =
+

[PATCH] D52034: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov

2018-11-12 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 173623.
calixte added a comment.

Forgot the ellipsis in the release notes.


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/ReleaseNotes.rst
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,6 +811,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.

[PATCH] D52034: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov

2018-11-12 Thread calixte via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC346642: [Clang] Add options -fprofile-filter-files and 
-fprofile-exclude-files to… (authored by calixte, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D52034?vs=173623&id=173627#toc

Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  docs/ReleaseNotes.rst
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: docs/UsersManual.rst
===
--- docs/UsersManual.rst
+++ docs/UsersManual.rst
@@ -1871,6 +1871,55 @@
   following the Itanium C++ ABI mangling scheme. This covers all C++ targets
   supported by Clang other than Windows.
 
+GCOV-based Profiling
+
+
+GCOV is a test coverage program, it helps to know how often a line of code
+is executed. When instrumenting the code with ``--coverage`` option, some
+counters are added for each edge linking basic blocks.
+
+At compile time, gcno files are generated containing information about
+blocks and edges between them. At runtime the counters are incremented and at
+exit the counters are dumped in gcda files.
+
+The tool ``llvm-cov gcov`` will parse gcno, gcda and source files to generate
+a report ``.c.gcov``.
+
+.. option:: -fprofile-filter-files=[regexes]
+
+  Define a list of regexes separated by a semi-colon.
+  If a file name matches any of the regexes then the file is instrumented.
+
+   .. code-block:: console
+
+ $ clang --coverage -fprofile-filter-files=".*\.c$" foo.c
+
+  For example, this will only instrument files finishing with ``.c``, skipping ``.h`` files.
+
+.. option:: -fprofile-exclude-files=[regexes]
+
+  Define a list of regexes separated by a semi-colon.
+  If a file name doesn't match all the regexes then the file is instrumented.
+
+  .. code-block:: console
+
+ $ clang --coverage -fprofile-exclude-files="^/usr/include/.*$" foo.c
+
+  For example, this will instrument all the files except the ones in ``/usr/include``.
+
+If both options are used then a file is instrumented if its name matches any
+of the regexes from ``-fprofile-filter-list`` and doesn't match all the regexes
+from ``-fprofile-exclude-list``.
+
+.. code-block:: console
+
+   $ clang --coverage -fprofile-exclude-files="^/usr/include/.*$" \
+   -fprofile-filter-files="^/usr/.*$"
+  
+In that case ``/usr/foo/oof.h`` is instrumented since it matches the filter regex and
+doesn't match the exclude regex, but ``/usr/include/foo.h`` doesn't since it matches
+the exclude regex.
+
 Controlling Debug Information
 -
 
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -64,6 +64,12 @@
 New Compiler Flags
 --
 
+- ``-fprofile-filter-files=[regexes]`` and ``-fprofile-exclude-files=[regexes]``.
+
+  Clang has now options to filter or exclude some files when
+  instrumenting for gcov-based profiling.
+  See the :doc:`UsersManual` for details.
+
 - ...
 
 Deprecated Compiler Flags
Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -768,6 +768,12 @@
 HelpText<"Disable using instrumentation data for profile-guided optimization">;
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
 Alias;
+def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">,
+Group, Flags<[CC1Option, CoreOption]>,
+HelpText<"Instrument only functions from files where names match any regex separated by a semi-colon">;
+def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">,
+Group, Flags<[CC1Option, CoreOption]>,
+HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">;
 
 def faddrsig : Flag<["-"], "faddrsig">, Group, Flags<[CoreOption, CC1Option]>,
   HelpText<"Emit an address-significance table">;
Index: include/clang/Frontend/CodeGenOptions.h
===
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -127,6 +127,12 @@
   /// The filename with path we use for coverage notes files.
   std::string CoverageNotesFile;
 
+  /// Regexes separated by a semi-colon to filter the files to instrument.
+  std::string ProfileFilterFiles;
+
+  /// Regexes separated by a semi-colon to filter the files to not instrument.
+  std::string ProfileExcludeFiles;
+
   /// The version string to put into coverage files.
   char CoverageVersion[4];
 

[PATCH] D54416: [GCOV] fix test after patch rL346642

2018-11-12 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: marco-c.
Herald added a subscriber: cfe-commits.

Test is failing under windows, so fix it


Repository:
  rC Clang

https://reviews.llvm.org/D54416

Files:
  test/CodeGen/code-coverage-filter.c


Index: test/CodeGen/code-coverage-filter.c
===
--- test/CodeGen/code-coverage-filter.c
+++ test/CodeGen/code-coverage-filter.c
@@ -23,62 +23,62 @@
   test2();
 }
 
-// ALL: define void @test1() #0 {{.*}}
+// ALL: void @test1() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test2() #0 {{.*}}
+// ALL: void @test2() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test() #0 {{.*}}
+// ALL: void @test() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
 
-// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER: void @test1() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER: void @test2() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: void @test() #0 {{.*}}
 // NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
 
-// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: void @test1() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2: void @test2() #0 {{.*}}
 // NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: void @test() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
 
-// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C: void @test1() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C: void @test2() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: void @test() #0 {{.*}}
 // JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
 
-// HEADER: define void @test1() #0 {{.*}}
+// HEADER: void @test1() #0 {{.*}}
 // HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
-// HEADER: define void @test2() #0 {{.*}}
+// HEADER: void @test2() #0 {{.*}}
 // HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
-// HEADER: define void @test() #0 {{.*}}
+// HEADER: void @test() #0 {{.*}}
 // HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
 
-// NONE: define void @test1() #0 {{.*}}
+// NONE: void @test1() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void
-// NONE: define void @test2() #0 {{.*}}
+// NONE: void @test2() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void
-// NONE: define void @test() #0 {{.*}}
+// NONE: void @test() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void


Index: test/CodeGen/code-coverage-filter.c
===
--- test/CodeGen/code-coverage-filter.c
+++ test/CodeGen/code-coverage-filter.c
@@ -23,62 +23,62 @@
   test2();
 }
 
-// ALL: define void @test1() #0 {{.*}}
+// ALL: void @test1() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test2() #0 {{.*}}
+// ALL: void @test2() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test() #0 {{.*}}
+// ALL: void @test() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
 
-// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER: void @test1() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER: void @test2() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: void @test() #0 {{.*}}
 // NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
 
-// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: void @test1() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2: void @test2() #0 {{.*}}
 // NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: void @test() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
 
-// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C: void @test1() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C: void @test2() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: void @test() #0 {{.*}}
 // JUST-C: {{.*}}__llvm

[PATCH] D54416: [GCOV] fix test after patch rL346642

2018-11-12 Thread calixte via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL346644: [GCOV] fix test after patch rL346642 (authored by 
calixte, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D54416

Files:
  cfe/trunk/test/CodeGen/code-coverage-filter.c


Index: cfe/trunk/test/CodeGen/code-coverage-filter.c
===
--- cfe/trunk/test/CodeGen/code-coverage-filter.c
+++ cfe/trunk/test/CodeGen/code-coverage-filter.c
@@ -23,62 +23,62 @@
   test2();
 }
 
-// ALL: define void @test1() #0 {{.*}}
+// ALL: void @test1() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test2() #0 {{.*}}
+// ALL: void @test2() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test() #0 {{.*}}
+// ALL: void @test() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
 
-// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER: void @test1() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER: void @test2() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: void @test() #0 {{.*}}
 // NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
 
-// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: void @test1() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2: void @test2() #0 {{.*}}
 // NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: void @test() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
 
-// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C: void @test1() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C: void @test2() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: void @test() #0 {{.*}}
 // JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
 
-// HEADER: define void @test1() #0 {{.*}}
+// HEADER: void @test1() #0 {{.*}}
 // HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
-// HEADER: define void @test2() #0 {{.*}}
+// HEADER: void @test2() #0 {{.*}}
 // HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
-// HEADER: define void @test() #0 {{.*}}
+// HEADER: void @test() #0 {{.*}}
 // HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // HEADER: ret void
 
-// NONE: define void @test1() #0 {{.*}}
+// NONE: void @test1() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void
-// NONE: define void @test2() #0 {{.*}}
+// NONE: void @test2() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void
-// NONE: define void @test() #0 {{.*}}
+// NONE: void @test() #0 {{.*}}
 // NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NONE: ret void


Index: cfe/trunk/test/CodeGen/code-coverage-filter.c
===
--- cfe/trunk/test/CodeGen/code-coverage-filter.c
+++ cfe/trunk/test/CodeGen/code-coverage-filter.c
@@ -23,62 +23,62 @@
   test2();
 }
 
-// ALL: define void @test1() #0 {{.*}}
+// ALL: void @test1() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test2() #0 {{.*}}
+// ALL: void @test2() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
-// ALL: define void @test() #0 {{.*}}
+// ALL: void @test() #0 {{.*}}
 // ALL: {{.*}}__llvm_gcov_ctr{{.*}}
 // ALL: ret void
 
-// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER: void @test1() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER: void @test2() #0 {{.*}}
 // NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
-// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: void @test() #0 {{.*}}
 // NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER: ret void
 
-// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: void @test1() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2: void @test2() #0 {{.*}}
 // NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
-// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: void @test() #0 {{.*}}
 // NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
 // NO-HEADER2: ret void
 
-// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C: void @test1() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
 // JUST-C: ret void
-// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C: void @test2() #0 {{.*}}
 // JUST-C-NOT: {{.*}}__llvm

[PATCH] D54600: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov (after revert https://reviews.llvm.org/rL346659)

2018-11-15 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: marco-c.
Herald added a subscriber: cfe-commits.

the previous patch (https://reviews.llvm.org/rC346642) has been reverted 
because of test failure under windows.
So this patch fix the test cfe/trunk/test/CodeGen/code-coverage-filter.c.


Repository:
  rC Clang

https://reviews.llvm.org/D54600

Files:
  docs/ReleaseNotes.rst
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang -S -emit-llvm --coverage %s -o %t
+// RUN: FileCheck -check-prefix=ALL < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER2 < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NONE < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -828,6 +828,10 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.ProfileFilterFiles =
+Args.getLastArgValue(OPT_fprofile_filter_files_EQ);
+Opts.ProfileExcludeFiles =
+Args.getLastArgValue(OPT_fprofile_exclude_files_EQ);
 Opts.CoverageExitBlockBeforeBody =
  

[PATCH] D54600: [Clang] Add options -fprofile-filter-files and -fprofile-exclude-files to filter the files to instrument with gcov (after revert https://reviews.llvm.org/rL346659)

2018-11-17 Thread calixte via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC347144: [Clang] Add options -fprofile-filter-files and 
-fprofile-exclude-files to… (authored by calixte, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D54600?vs=174281&id=174512#toc

Repository:
  rC Clang

https://reviews.llvm.org/D54600

Files:
  docs/ReleaseNotes.rst
  docs/UsersManual.rst
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: include/clang/Frontend/CodeGenOptions.h
===
--- include/clang/Frontend/CodeGenOptions.h
+++ include/clang/Frontend/CodeGenOptions.h
@@ -129,6 +129,12 @@
   /// The filename with path we use for coverage notes files.
   std::string CoverageNotesFile;
 
+  /// Regexes separated by a semi-colon to filter the files to instrument.
+  std::string ProfileFilterFiles;
+
+  /// Regexes separated by a semi-colon to filter the files to not instrument.
+  std::string ProfileExcludeFiles;
+
   /// The version string to put into coverage files.
   char CoverageVersion[4];
 
Index: include/clang/Driver/Options.td
===
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -768,6 +768,12 @@
 HelpText<"Disable using instrumentation data for profile-guided optimization">;
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
 Alias;
+def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">,
+Group, Flags<[CC1Option, CoreOption]>,
+HelpText<"Instrument only functions from files where names match any regex separated by a semi-colon">;
+def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">,
+Group, Flags<[CC1Option, CoreOption]>,
+HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">;
 
 def faddrsig : Flag<["-"], "faddrsig">, Group, Flags<[CoreOption, CC1Option]>,
   HelpText<"Emit an address-significance table">;
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- test/CodeGen/Inputs/code-coverage-filter2.h
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1 @@
+void test2() {}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- test/CodeGen/Inputs/code-coverage-filter1.h
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1 @@
+void test1() {}
Index: test/CodeGen/code-coverage-filter.c
===
--- test/CodeGen/code-coverage-filter.c
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang -S -emit-llvm --coverage %s -o %t
+// RUN: FileCheck -check-prefix=ALL < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=NO-HEADER2 < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*2\.h$;.*1\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-exclude-files=".*code\-coverage\-filter\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=HEADER < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.c$" %s -o %t
+// RUN: FileCheck -check-prefix=NONE < %t %s
+// RUN: %clang -S -emit-llvm --coverage -fprofile-filter-files=".*\.c$" -fprofile-exclude-files=".*\.h$" %s -o %t
+// RUN: FileCheck -check-prefix=JUST-C < %t %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+  test1();
+  test2();
+}
+
+// ALL: void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: void @test2() #0 {

[PATCH] D49916: [CodeGen] Add to emitted DebugLoc information about coverage when it's required

2018-09-21 Thread calixte via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC342717: [CodeGen] Add to emitted DebugLoc information about 
coverage when it's required (authored by calixte, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D49916?vs=164860&id=166416#toc

Repository:
  rC Clang

https://reviews.llvm.org/D49916

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/debug-info-scope-file.c
  test/CodeGenCXX/debug-info-inheriting-constructor.cpp
  test/CodeGenCXX/linetable-virtual-variadic.cpp
  test/CodeGenObjC/arc-linetable.m
  test/CodeGenObjC/debug-info-blocks.m

Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -76,20 +76,22 @@
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
-   SourceLocation TemporaryLocation)
+   SourceLocation TemporaryLocation,
+   bool ImplicitCode)
 : CGF(&CGF) {
-  init(TemporaryLocation);
+  init(TemporaryLocation, false /* DefaultToEmpty */, ImplicitCode);
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
bool DefaultToEmpty,
-   SourceLocation TemporaryLocation)
+   SourceLocation TemporaryLocation,
+   bool ImplicitCode)
 : CGF(&CGF) {
-  init(TemporaryLocation, DefaultToEmpty);
+  init(TemporaryLocation, DefaultToEmpty, ImplicitCode);
 }
 
 void ApplyDebugLocation::init(SourceLocation TemporaryLocation,
-  bool DefaultToEmpty) {
+  bool DefaultToEmpty, bool ImplicitCode) {
   auto *DI = CGF->getDebugInfo();
   if (!DI) {
 CGF = nullptr;
@@ -102,7 +104,7 @@
 return;
 
   if (TemporaryLocation.isValid()) {
-DI->EmitLocation(CGF->Builder, TemporaryLocation);
+DI->EmitLocation(CGF->Builder, TemporaryLocation, ImplicitCode);
 return;
   }
 
@@ -3484,16 +3486,18 @@
   setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
 }
 
-void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
+void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
+   bool ImplicitCode) {
   // Update our current location
   setLocation(Loc);
 
   if (CurLoc.isInvalid() || CurLoc.isMacroID())
 return;
 
   llvm::MDNode *Scope = LexicalBlockStack.back();
-  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-  getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
+  Builder.SetCurrentDebugLocation(
+  llvm::DebugLoc::get(getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope,
+  CurInlinedAt, ImplicitCode));
 }
 
 void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
@@ -3540,7 +3544,7 @@
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
 
   // Provide an entry in the line table for the end of the block.
-  EmitLocation(Builder, Loc);
+  EmitLocation(Builder, Loc, true /* ImplicitCode */);
 
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -3556,7 +3560,7 @@
   // Pop all regions for this function.
   while (LexicalBlockStack.size() != RCount) {
 // Provide an entry in the line table for the end of the block.
-EmitLocation(Builder, CurLoc);
+EmitLocation(Builder, CurLoc, true /* ImplicitCode */);
 LexicalBlockStack.pop_back();
   }
   FnBeginRegionCount.pop_back();
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -377,7 +377,9 @@
   /// Emit metadata to indicate a change in line/column information in
   /// the source file. If the location is invalid, the previous
   /// location will be reused.
-  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
+  /// \param ImplicitCode  True if the Loc must have coverage information
+  void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,
+bool ImplicitCode = false);
 
   /// Emit a call to llvm.dbg.function.start to indicate
   /// start of a new function.
@@ -664,16 +666,19 @@
 /// location or preferred location of the specified Expr.
 class ApplyDebugLocation {
 private:
-  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false);
+  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false,
+bool ImplicitCode = false);
   ApplyDebugLocation(CodeGenFunction &CGF, bool DefaultToEmpty,
- SourceLocation TemporaryLocation);
+ SourceLocation TemporaryLocation,
+ bool Implic

[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-09-26 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 167101.
calixte added a comment.

Fix tests


Repository:
  rC Clang

https://reviews.llvm.org/D52034

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/Inputs/code-coverage-filter1.h
  test/CodeGen/Inputs/code-coverage-filter2.h
  test/CodeGen/code-coverage-filter.c

Index: test/CodeGen/code-coverage-filter.c
===
--- /dev/null
+++ test/CodeGen/code-coverage-filter.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes %s -o - \
+// RUN:| FileCheck -check-prefix=ALL %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-exclude=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-filter=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-filter=".*\.c$:.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=NO-HEADER2 %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-exclude=".*2\.h$:.*1\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-exclude=".*code\-coverage\-filter\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=HEADER %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-filter=".*\.c$" -coverage-exclude=".*\.c$" %s -o - \
+// RUN:| FileCheck -check-prefix=NONE %s
+// RUN: %clang_cc1 -emit-llvm -femit-coverage-data -femit-coverage-notes -coverage-filter=".*\.c$" -coverage-exclude=".*\.h$" %s -o - \
+// RUN:| FileCheck -check-prefix=JUST-C %s
+
+#include "Inputs/code-coverage-filter1.h"
+#include "Inputs/code-coverage-filter2.h"
+
+void test() {
+test1();
+test2();
+}
+
+// ALL: define void @test1() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test2() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+// ALL: define void @test() #0 {{.*}}
+// ALL: {{.*}}__llvm_gcov_ctr{{.*}}
+// ALL: ret void
+
+// NO-HEADER: define void @test1() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test2() #0 {{.*}}
+// NO-HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+// NO-HEADER: define void @test() #0 {{.*}}
+// NO-HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER: ret void
+
+// NO-HEADER2: define void @test1() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test2() #0 {{.*}}
+// NO-HEADER2-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+// NO-HEADER2: define void @test() #0 {{.*}}
+// NO-HEADER2: {{.*}}__llvm_gcov_ctr{{.*}}
+// NO-HEADER2: ret void
+
+// JUST-C: define void @test1() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test2() #0 {{.*}}
+// JUST-C-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+// JUST-C: define void @test() #0 {{.*}}
+// JUST-C: {{.*}}__llvm_gcov_ctr{{.*}}
+// JUST-C: ret void
+
+// HEADER: define void @test1() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test2() #0 {{.*}}
+// HEADER: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+// HEADER: define void @test() #0 {{.*}}
+// HEADER-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// HEADER: ret void
+
+// NONE: define void @test1() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test2() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
+// NONE: define void @test() #0 {{.*}}
+// NONE-NOT: {{.*}}__llvm_gcov_ctr{{.*}}
+// NONE: ret void
Index: test/CodeGen/Inputs/code-coverage-filter2.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter2.h
@@ -0,0 +1,2 @@
+void test2() {
+}
Index: test/CodeGen/Inputs/code-coverage-filter1.h
===
--- /dev/null
+++ test/CodeGen/Inputs/code-coverage-filter1.h
@@ -0,0 +1,2 @@
+void test1() {
+}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -801,6 +801,8 @@
 Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
 Opts.CoverageNoFunctionNamesInData =
 Args.hasArg(OPT_coverage_no_function_names_in_data);
+Opts.CoverageFilter = Args.getLastArgValue(OPT_coverage_filter);
+Opts.CoverageExclude = Args.getLastArgValue(OPT_coverage_exclude);
 Opts.CoverageExi

[PATCH] D52034: [Clang] Add options -Xclang -coverage-filter and -Xclang -coverage-exclude to filter the files to instrument with gcov

2018-09-26 Thread calixte via Phabricator via cfe-commits
calixte added a comment.

I reported a bug for gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87442
@vsk I'd like to add documentation in Docs/UsersManual.rst, but I've no idea on 
what's a good place for this (I look for option 
-coverage-no-function-names-in-data, but I didn't get anything). So could you 
give a me a clue please ?


Repository:
  rC Clang

https://reviews.llvm.org/D52034



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83149: [gcov] Add __gcov_dump/__gcov_reset and delete __gcov_flush

2020-07-17 Thread calixte via Phabricator via cfe-commits
calixte accepted this revision.
calixte added a comment.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83149/new/

https://reviews.llvm.org/D83149



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78477: [profile] Don't crash when forking in several threads

2020-04-20 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 258686.
calixte added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Export symbol for Darwin target


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78477/new/

https://reviews.llvm.org/D78477

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  compiler-rt/test/profile/Inputs/instrprof-gcov-multithread_fork.cpp
  compiler-rt/test/profile/instrprof-gcov-multithread_fork.test
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,79 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector Forks;
+  SmallVector Execs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  Forks.push_back(CI);
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  Execs.push_back(CI);
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
+  for (auto F : Forks) {
+IRBuilder<> Builder(F);
+BasicBlock *Parent = F->getParent();
+auto NextInst = ++F->getIterator();
+
+// We've a fork so just reset the counters in the child process
+FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+F->setCalledFunction(GCOVFork);
+if (NextInst != Parent->end()) {
+  // We split just after the fork to have a counter for the lines after
+  // Anyway there's a bug:
+  // void foo() { fork(); }
+  // void bar() { foo(); blah(); }
+  // then "blah();" will be called 2 times but showed as 1
+  // because "blah()" belongs to the same block as "foo();"
+  Parent->splitBasicBlock(NextInst);
+
+  // back() is a br instruction with a debug location
+  // equals to the one from NextAfterFork
+  // So to avoid to have two debug locs on two blocks just change it
+  DebugLoc Loc = F->getDebugLoc();
+  Parent->back().setDebugLoc(Loc);
+}
+  }
+
+  for (auto E : Execs) {
+IRBuilder<> Builder(E);
+BasicBlock *Parent = E->getParent();
+auto NextInst = ++E->getIterator();
+
+// Since the process is replaced by a new one we need to write out gcdas
+// No need to reset the counters since they'll be lost after the exec**
 FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+FunctionCallee WriteoutF =
+M->getOrInsertFunction("llvm_writeout_files", FTy);
+Builder.CreateCall(WriteoutF);
+if (NextInst != Parent->end()) {
+  DebugLoc Loc = E->getDebugLoc();
+  Builder.SetInsertPoint(&*NextInst);
+  // If the exec** fails we must reset the counters since they've been
+  // dumped
+  FunctionCallee ResetF =
+  M->getOrInsertFunction("llvm_reset_counters", FTy);
+  Builder.CreateCall(ResetF)->setDebugLoc(Loc);
+  Parent->splitBasicBlock(NextInst);
+  Parent->back().setDebugLoc(Loc);
+}
   }
 }
 
@@ -851,7 +896,8 @@
 }
 
 Function *WriteoutF = insertCounterWriteout(CountersBySP);
-Function *FlushF = insertFlush(CountersBySP);
+Function *ResetF = insertReset(CountersBySP);
+Function *FlushF = insert

[PATCH] D78477: [profile] Don't crash when forking in several threads

2020-04-24 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 259854.
calixte added a comment.

Fix nits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78477/new/

https://reviews.llvm.org/D78477

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  compiler-rt/test/profile/Inputs/instrprof-gcov-multithread_fork.cpp
  compiler-rt/test/profile/instrprof-gcov-multithread_fork.test
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,76 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector Forks;
+  SmallVector Execs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  Forks.push_back(CI);
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  Execs.push_back(CI);
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
+  for (auto F : Forks) {
+IRBuilder<> Builder(F);
+BasicBlock *Parent = F->getParent();
+auto NextInst = ++F->getIterator();
+
+// We've a fork so just reset the counters in the child process
+FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+F->setCalledFunction(GCOVFork);
+
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }
+// void bar() { foo(); blah(); }
+// then "blah();" will be called 2 times but showed as 1
+// because "blah()" belongs to the same block as "foo();"
+Parent->splitBasicBlock(NextInst);
+
+// back() is a br instruction with a debug location
+// equals to the one from NextAfterFork
+// So to avoid to have two debug locs on two blocks just change it
+DebugLoc Loc = F->getDebugLoc();
+Parent->back().setDebugLoc(Loc);
+  }
+
+  for (auto E : Execs) {
+IRBuilder<> Builder(E);
+BasicBlock *Parent = E->getParent();
+auto NextInst = ++E->getIterator();
+
+// Since the process is replaced by a new one we need to write out gcdas
+// No need to reset the counters since they'll be lost after the exec**
 FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+FunctionCallee WriteoutF =
+M->getOrInsertFunction("llvm_writeout_files", FTy);
+Builder.CreateCall(WriteoutF);
+
+DebugLoc Loc = E->getDebugLoc();
+Builder.SetInsertPoint(&*NextInst);
+// If the exec** fails we must reset the counters since they've been
+// dumped
+FunctionCallee ResetF = M->getOrInsertFunction("llvm_reset_counters", FTy);
+Builder.CreateCall(ResetF)->setDebugLoc(Loc);
+Parent->splitBasicBlock(NextInst);
+Parent->back().setDebugLoc(Loc);
   }
 }
 
@@ -851,7 +893,8 @@
 }
 
 Function *WriteoutF = insertCounterWriteout(CountersBySP);
-Function *FlushF = insertFlush(CountersBySP);
+Function *ResetF = insertReset(CountersBySP);
+Function *FlushF = insertFlush(ResetF);
 
 // Create a small bit of code that registers the "__llvm_gcov_writeout" to
 // be executed at exit and the "__llvm_gcov_flush" function to be executed
@@ -869,16 +912,14 @@
 IRBuilder<> Builder(BB);
 

[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: marco-c.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, hiraditya.
Herald added projects: clang, Sanitizers, LLVM.

There is no need to write out gcdas when forking because we can just reset the 
counters in the parent process.
Let say a counter is N before the fork, then fork and this counter is set to 0 
in the child process.
In the parent process, the counter is incremented by P and in the child process 
it's incremented by C.
When dump is ran at exit, parent process will dump N+P for the given counter 
and the child process will dump 0+C, so when the gcdas are merged the resulting 
counter will be N+P+C.
About exec** functions, since the current process is replaced by an another one 
there is no need to reset the counters but just write out the gcdas since the 
counters are definitely lost.
To avoid to have lists in a bad state, we just lock them during the fork and 
the flush (if called explicitely) and lock them when an element is added.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74953

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,66 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  ForkAndExecs.push_back({true, CI});
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  ForkAndExecs.push_back({false, CI});
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
-FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+  for (auto F : ForkAndExecs) {
+IRBuilder<> Builder(F.second);
+BasicBlock *Parent = F.second->getParent();
+auto NextInst = ++F.second->getIterator();
+
+if (F.first) {
+  // We've a fork so just reset the counters in the child process
+  FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+  FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+  F.second->setCalledFunction(GCOVFork);
+  if (NextInst != Parent->end()) {
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }
+// void bar() { foo(); blah(); }
+// then "blah();" will be called 2 times but showed as 1
+// because "blah()" belongs to the same block as "foo();"
+Parent->splitBasicBlock(NextInst);
+
+// back() is a br instruction with a debug location
+// equals to the one from NextAfterFork
+// So to avoid to have two debug locs on two blocks just change it
+DebugLoc Loc = F.second->getDebugLoc();
+Parent->back().setDebugLoc(Loc);
+  }
+} else {
+  // Since the process is replaced by a new one we need to write out gcdas
+  // No need to reset the counters since there'll be lost after the exec**
+  FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+  FunctionCallee WriteoutF =
+  M->getOrInsertFunction("llvm_writeout_files

[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 245837.
calixte added a comment.

If exec** fails we need to reset the counters since they've have dumped just 
before to avoid to count them twice.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74953/new/

https://reviews.llvm.org/D74953

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,74 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  ForkAndExecs.push_back({true, CI});
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  ForkAndExecs.push_back({false, CI});
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
-FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+  for (auto F : ForkAndExecs) {
+IRBuilder<> Builder(F.second);
+BasicBlock *Parent = F.second->getParent();
+auto NextInst = ++F.second->getIterator();
+
+if (F.first) {
+  // We've a fork so just reset the counters in the child process
+  FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+  FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+  F.second->setCalledFunction(GCOVFork);
+  if (NextInst != Parent->end()) {
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }
+// void bar() { foo(); blah(); }
+// then "blah();" will be called 2 times but showed as 1
+// because "blah()" belongs to the same block as "foo();"
+Parent->splitBasicBlock(NextInst);
+
+// back() is a br instruction with a debug location
+// equals to the one from NextAfterFork
+// So to avoid to have two debug locs on two blocks just change it
+DebugLoc Loc = F.second->getDebugLoc();
+Parent->back().setDebugLoc(Loc);
+  }
+} else {
+  // Since the process is replaced by a new one we need to write out gcdas
+  // No need to reset the counters since there'll be lost after the exec**
+  FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+  FunctionCallee WriteoutF =
+  M->getOrInsertFunction("llvm_writeout_files", FTy);
+  Builder.CreateCall(WriteoutF);
+  if (NextInst != Parent->end()) {
+DebugLoc Loc = F.second->getDebugLoc();
+Builder.SetInsertPoint(&*NextInst);
+// If the exec** fails we must reset the counters since they've been
+// dumped
+FunctionCallee ResetF =
+M->getOrInsertFunction("llvm_reset_counters", FTy);
+Builder.CreateCall(ResetF)->setDebugLoc(Loc);
+Parent->splitBasicBlock(NextInst);
+Parent->back().setDebugLoc(Loc);
+  }
+}
   }
 }
 
@@ -851,7 +891,8 @@
 }
 
 Function *WriteoutF = insertCounterWriteout(CountersBySP);
-Function *FlushF = insertFlush(CountersBySP);
+Function *ResetF = insertReset(CountersBySP);
+Function *FlushF = insertFlush(ResetF

[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 245843.
calixte marked 4 inline comments as done.
calixte added a comment.

Add more comments to explain why we need to lock around the fork


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74953/new/

https://reviews.llvm.org/D74953

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,74 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  ForkAndExecs.push_back({true, CI});
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  ForkAndExecs.push_back({false, CI});
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
-FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+  for (auto F : ForkAndExecs) {
+IRBuilder<> Builder(F.second);
+BasicBlock *Parent = F.second->getParent();
+auto NextInst = ++F.second->getIterator();
+
+if (F.first) {
+  // We've a fork so just reset the counters in the child process
+  FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+  FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+  F.second->setCalledFunction(GCOVFork);
+  if (NextInst != Parent->end()) {
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }
+// void bar() { foo(); blah(); }
+// then "blah();" will be called 2 times but showed as 1
+// because "blah()" belongs to the same block as "foo();"
+Parent->splitBasicBlock(NextInst);
+
+// back() is a br instruction with a debug location
+// equals to the one from NextAfterFork
+// So to avoid to have two debug locs on two blocks just change it
+DebugLoc Loc = F.second->getDebugLoc();
+Parent->back().setDebugLoc(Loc);
+  }
+} else {
+  // Since the process is replaced by a new one we need to write out gcdas
+  // No need to reset the counters since there'll be lost after the exec**
+  FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+  FunctionCallee WriteoutF =
+  M->getOrInsertFunction("llvm_writeout_files", FTy);
+  Builder.CreateCall(WriteoutF);
+  if (NextInst != Parent->end()) {
+DebugLoc Loc = F.second->getDebugLoc();
+Builder.SetInsertPoint(&*NextInst);
+// If the exec** fails we must reset the counters since they've been
+// dumped
+FunctionCallee ResetF =
+M->getOrInsertFunction("llvm_reset_counters", FTy);
+Builder.CreateCall(ResetF)->setDebugLoc(Loc);
+Parent->splitBasicBlock(NextInst);
+Parent->back().setDebugLoc(Loc);
+  }
+}
   }
 }
 
@@ -851,7 +891,8 @@
 }
 
 Function *WriteoutF = insertCounterWriteout(CountersBySP);
-Function *FlushF = insertFlush(CountersBySP);
+Function *ResetF = insertReset(CountersBySP);
+Function *FlushF = insertFlush(ResetF);
 
   

[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte added inline comments.



Comment at: compiler-rt/lib/profile/GCDAProfiling.c:671
+pid_t child_pid = getpid();
+if (child_pid != parent_pid) {
+  // The pid changed so we've a fork

marco-c wrote:
> Nit: do we need this check or can we just use the earlier one on pid == 0?
I added this check to be sure we had a true fork in case of someone wrote its 
own fork function.



Comment at: compiler-rt/lib/profile/GCDAProfiling.c:675
+  // No need to lock here since we just forked and cannot have any other
+  // threads.
+  struct fn_node *curr = reset_fn_list.head;

marco-c wrote:
> What if we have a thread in another process making modifications to the list?
When forking, only the thread in the parent process is copied so in the child 
process we've only one thread.
When forking, the parent and the child process share the same memory until some 
change (Copy-on-Write), so even if in the parent process a list is changed then 
the memory will be copied before the change and then the child process will 
have an unchanged list. 



Comment at: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp:635
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {

marco-c wrote:
> Since we are now mostly doing different things on forks and execs, we could 
> remove this vector and just do the operations directly instead of adding to 
> the vec.
If we make the insertions of new code in the second for loop, we'll invalidate 
the iterator used in this loop. 



Comment at: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp:671
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }

marco-c wrote:
> Isn't this bug fixed by splitting the block?
With the example shew here, the split is in foo but not in bar, blah() should 
be in another block


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74953/new/

https://reviews.llvm.org/D74953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte marked an inline comment as done.
calixte added inline comments.



Comment at: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp:635
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {

marco-c wrote:
> calixte wrote:
> > marco-c wrote:
> > > Since we are now mostly doing different things on forks and execs, we 
> > > could remove this vector and just do the operations directly instead of 
> > > adding to the vec.
> > If we make the insertions of new code in the second for loop, we'll 
> > invalidate the iterator used in this loop. 
> M->getOrInsertFunction is what would invalidate the iterator?
> 
> You could clean things up a bit by having two vectors then, one for forks and 
> one for execs.
Builder.Create** will invalidate the iterator 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74953/new/

https://reviews.llvm.org/D74953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74953: [profile] Don't dump counters when forking and don't reset when calling exec** functions

2020-02-21 Thread calixte via Phabricator via cfe-commits
calixte updated this revision to Diff 245848.
calixte added a comment.

Fix a typo


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74953/new/

https://reviews.llvm.org/D74953

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -115,7 +115,8 @@
   // list.
   Function *
   insertCounterWriteout(ArrayRef>);
-  Function *insertFlush(ArrayRef>);
+  Function *insertReset(ArrayRef>);
+  Function *insertFlush(Function *ResetF);
 
   void AddFlushBeforeForkAndExec();
 
@@ -631,35 +632,74 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForkAndExecs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+#if !defined(_WIN32)
+  ForkAndExecs.push_back({true, CI});
+#endif
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  ForkAndExecs.push_back({false, CI});
+}
   }
 }
   }
 }
   }
 
-  // We need to split the block after the fork/exec call
-  // because else the counters for the lines after will be
-  // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
-FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
-FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
-Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+  for (auto F : ForkAndExecs) {
+IRBuilder<> Builder(F.second);
+BasicBlock *Parent = F.second->getParent();
+auto NextInst = ++F.second->getIterator();
+
+if (F.first) {
+  // We've a fork so just reset the counters in the child process
+  FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+  FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+  F.second->setCalledFunction(GCOVFork);
+  if (NextInst != Parent->end()) {
+// We split just after the fork to have a counter for the lines after
+// Anyway there's a bug:
+// void foo() { fork(); }
+// void bar() { foo(); blah(); }
+// then "blah();" will be called 2 times but showed as 1
+// because "blah()" belongs to the same block as "foo();"
+Parent->splitBasicBlock(NextInst);
+
+// back() is a br instruction with a debug location
+// equals to the one from NextAfterFork
+// So to avoid to have two debug locs on two blocks just change it
+DebugLoc Loc = F.second->getDebugLoc();
+Parent->back().setDebugLoc(Loc);
+  }
+} else {
+  // Since the process is replaced by a new one we need to write out gcdas
+  // No need to reset the counters since they'll be lost after the exec**
+  FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+  FunctionCallee WriteoutF =
+  M->getOrInsertFunction("llvm_writeout_files", FTy);
+  Builder.CreateCall(WriteoutF);
+  if (NextInst != Parent->end()) {
+DebugLoc Loc = F.second->getDebugLoc();
+Builder.SetInsertPoint(&*NextInst);
+// If the exec** fails we must reset the counters since they've been
+// dumped
+FunctionCallee ResetF =
+M->getOrInsertFunction("llvm_reset_counters", FTy);
+Builder.CreateCall(ResetF)->setDebugLoc(Loc);
+Parent->splitBasicBlock(NextInst);
+Parent->back().setDebugLoc(Loc);
+  }
+}
   }
 }
 
@@ -851,7 +891,8 @@
 }
 
 Function *WriteoutF = insertCounterWriteout(CountersBySP);
-Function *FlushF = insertFlush(CountersBySP);
+Function *ResetF = insertReset(CountersBySP);
+Function *FlushF = insertFlush(ResetF);
 
 // Create a small bit of code that registers the "__llvm_gcov_writeout" to
 // be executed 

[PATCH] D74071: [Profile] Avoid deadlock in multithreaded context when forking with coverage enabled

2020-02-05 Thread calixte via Phabricator via cfe-commits
calixte created this revision.
calixte added a reviewer: marco-c.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, jfb, hiraditya.
Herald added projects: clang, Sanitizers, LLVM.

When a program is forked with code coverage enabled, all the counters are 
flushed.
To avoid data race, a critical section has been added around `__gcov_flush` 
(https://reviews.llvm.org/D70910) but when forking the mutex is just duplicated 
and if it was in a locked state (in the parent process) then it's locked in the 
child process which leads to a deadlock when the child is trying to flush 
counters.
This patch aims to initialize the mutex in the child process when forking.
So a custom fork (`__gcov_fork`) is called from instrumented code and the mutex 
is then initialized in the child process.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74071

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/GCDAProfiling.c
  llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -631,20 +631,22 @@
 }
 
 void GCOVProfiler::AddFlushBeforeForkAndExec() {
-  SmallVector ForkAndExecs;
+  SmallVector, 2> ForksAndExecs;
   for (auto &F : M->functions()) {
 auto *TLI = &GetTLI(F);
 for (auto &I : instructions(F)) {
   if (CallInst *CI = dyn_cast(&I)) {
 if (Function *Callee = CI->getCalledFunction()) {
   LibFunc LF;
-  if (TLI->getLibFunc(*Callee, LF) &&
-  (LF == LibFunc_fork || LF == LibFunc_execl ||
-   LF == LibFunc_execle || LF == LibFunc_execlp ||
-   LF == LibFunc_execv || LF == LibFunc_execvp ||
-   LF == LibFunc_execve || LF == LibFunc_execvpe ||
-   LF == LibFunc_execvP)) {
-ForkAndExecs.push_back(&I);
+  if (TLI->getLibFunc(*Callee, LF)) {
+if (LF == LibFunc_fork) {
+  ForksAndExecs.push_back({true, CI});
+} else if (LF == LibFunc_execl || LF == LibFunc_execle ||
+   LF == LibFunc_execlp || LF == LibFunc_execv ||
+   LF == LibFunc_execvp || LF == LibFunc_execve ||
+   LF == LibFunc_execvpe || LF == LibFunc_execvP) {
+  ForksAndExecs.push_back({false, CI});
+}
   }
 }
   }
@@ -654,12 +656,21 @@
   // We need to split the block after the fork/exec call
   // because else the counters for the lines after will be
   // the same as before the call.
-  for (auto I : ForkAndExecs) {
-IRBuilder<> Builder(I);
+  for (auto F : ForksAndExecs) {
+IRBuilder<> Builder(F.second);
 FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
 FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
 Builder.CreateCall(GCOVFlush);
-I->getParent()->splitBasicBlock(I);
+
+if (F.first) {
+  // We've a fork, so we call a custom fork which will initialize the mutex
+  // used when flushing
+  FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
+  FunctionCallee GCOVFork = M->getOrInsertFunction("__gcov_fork", FTy);
+  F.second->setCalledFunction(GCOVFork);
+}
+
+F.second->getParent()->splitBasicBlock(F.second);
   }
 }
 
Index: compiler-rt/lib/profile/GCDAProfiling.c
===
--- compiler-rt/lib/profile/GCDAProfiling.c
+++ compiler-rt/lib/profile/GCDAProfiling.c
@@ -71,6 +71,9 @@
 static __inline void gcov_flush_unlock() {
   pthread_mutex_unlock(&gcov_flush_mutex);
 }
+static __inline void gcov_flush_init_mutex() {
+  pthread_mutex_init(&gcov_flush_mutex, NULL);
+}
 #else
 #include 
 static SRWLOCK gcov_flush_mutex = SRWLOCK_INIT;
@@ -80,6 +83,9 @@
 static __inline void gcov_flush_unlock() {
   ReleaseSRWLockExclusive(&gcov_flush_mutex);
 }
+static __inline void gcov_flush_init_mutex() {
+  InitializeSRWLock(&gcov_flush_mutex);
+}
 #endif
 
 /* #define DEBUG_GCDAPROFILING */
@@ -638,6 +644,16 @@
   fn_list_insert(&flush_fn_list, fn);
 }
 
+pid_t __gcov_fork() {
+  pid_t pid = fork();
+
+  if (pid == 0) {
+gcov_flush_init_mutex();
+  }
+
+  return pid;
+}
+
 void __gcov_flush() {
   gcov_flush_lock();
 
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1143,6 +1143,7 @@
   // runtime's functionality.
   if (hasExportSymbolDirective(Args)) {
 if (ForGCOV) {
+  addExportedSymbol(CmdArgs, "___gcov_fork");
   addExportedSymbol(CmdArgs, "___gcov_flush");
   addExportedSymbol(CmdArgs, "_flush_fn_list");
   addExportedSymbol(CmdArgs, "_writeout_fn_list");
___