MaskRay created this revision.
MaskRay added reviewers: calixte, marco-c, serge-sans-paille, vsk.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, hiraditya.
Herald added projects: clang, Sanitizers, LLVM.
GCC r187297 (2012-05) introduced __gcov_dump and __gcov_reset.
__gcov_flush = __gcov_dump + __gcov_reset
https://gcc.gnu.org/PR93623 (target GCC 11.0) removed the unuseful and
undocumented __gcov_flush.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D83149
Files:
clang/lib/Driver/ToolChains/Darwin.cpp
clang/test/Driver/darwin-ld.c
compiler-rt/lib/profile/GCDAProfiling.c
compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
compiler-rt/test/profile/Posix/gcov-shared-flush.c
compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
compiler-rt/test/profile/gcov-dump-and-remove.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
@@ -130,7 +130,6 @@
Function *
insertCounterWriteout(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
Function *insertReset(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
- Function *insertFlush(Function *ResetF);
bool AddFlushBeforeForkAndExec();
@@ -909,7 +908,6 @@
Function *WriteoutF = insertCounterWriteout(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
@@ -927,14 +925,13 @@
IRBuilder<> Builder(BB);
FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
- Type *Params[] = {PointerType::get(FTy, 0), PointerType::get(FTy, 0),
- PointerType::get(FTy, 0)};
- FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
+ auto *PFTy = PointerType::get(FTy, 0);
+ FTy = FunctionType::get(Builder.getVoidTy(), {PFTy, PFTy}, false);
// Initialize the environment and register the local writeout, flush and
// reset functions.
FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
- Builder.CreateCall(GCOVInit, {WriteoutF, FlushF, ResetF});
+ Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
Builder.CreateRetVoid();
appendToGlobalCtors(*M, F, 0);
@@ -1266,36 +1263,3 @@
return ResetF;
}
-
-Function *GCOVProfiler::insertFlush(Function *ResetF) {
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
- Function *FlushF = M->getFunction("__llvm_gcov_flush");
- if (!FlushF)
- FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
- "__llvm_gcov_flush", M);
- FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
- FlushF->addFnAttr(Attribute::NoInline);
- if (Options.NoRedZone)
- FlushF->addFnAttr(Attribute::NoRedZone);
-
- BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
-
- // Write out the current counters.
- Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
- assert(WriteoutF && "Need to create the writeout function first!");
-
- IRBuilder<> Builder(Entry);
- Builder.CreateCall(WriteoutF, {});
- Builder.CreateCall(ResetF, {});
-
- Type *RetTy = FlushF->getReturnType();
- if (RetTy->isVoidTy())
- Builder.CreateRetVoid();
- else if (RetTy->isIntegerTy())
- // Used if __llvm_gcov_flush was implicitly declared.
- Builder.CreateRet(ConstantInt::get(RetTy, 0));
- else
- report_fatal_error("invalid return type for __llvm_gcov_flush");
-
- return FlushF;
-}
Index: compiler-rt/test/profile/gcov-dump-and-remove.c
===================================================================
--- compiler-rt/test/profile/gcov-dump-and-remove.c
+++ compiler-rt/test/profile/gcov-dump-and-remove.c
@@ -8,16 +8,19 @@
// RUN: rm -f gcov-dump-and-remove.gcda && %run %t
// RUN: llvm-cov gcov -t gcov-dump-and-remove.gcda | FileCheck %s
-extern void __gcov_flush(void);
+extern void __gcov_dump(void);
+extern void __gcov_reset(void);
extern int remove(const char *); // CHECK: -: [[#@LINE]]:extern int remove
int main(void) { // CHECK-NEXT: #####: [[#@LINE]]:
- __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]:
+ __gcov_dump(); // CHECK-NEXT: #####: [[#@LINE]]:
+ __gcov_reset(); // CHECK-NEXT: #####: [[#@LINE]]:
if (remove("gcov-dump-and-remove.gcda") != 0) // CHECK-NEXT: #####: [[#@LINE]]:
return 1; // CHECK-NEXT: #####: [[#@LINE]]: return 1;
// CHECK-NEXT: -: [[#@LINE]]:
- __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]:
- __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]:
- if (remove("gcov-dump-and-remove.gcda") != 0) // CHECK-NEXT: #####: [[#@LINE]]:
+ __gcov_dump(); // CHECK-NEXT: 1: [[#@LINE]]:
+ __gcov_reset(); // CHECK-NEXT: 1: [[#@LINE]]:
+ __gcov_dump(); // CHECK-NEXT: 1: [[#@LINE]]:
+ if (remove("gcov-dump-and-remove.gcda") != 0) // CHECK-NEXT: 1: [[#@LINE]]:
return 1; // CHECK-NEXT: #####: [[#@LINE]]: return 1;
return 0;
Index: compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
===================================================================
--- compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -10,11 +10,13 @@
// CHECK: -: 0:Runs:1
// CHECK-NEXT: -: 0:Programs:1
-void __gcov_flush(void);
+void __gcov_dump(void);
+void __gcov_reset(void);
int main(void) { // CHECK: 1: [[#@LINE]]:int main(void)
int i = 22; // CHECK-NEXT: 1: [[#@LINE]]:
- __gcov_flush(); // CHECK-NEXT: 1: [[#@LINE]]:
+ __gcov_dump(); // CHECK-NEXT: 1: [[#@LINE]]:
+ __gcov_reset(); // CHECK-NEXT: 1: [[#@LINE]]:
i = 42; // CHECK-NEXT: 1: [[#@LINE]]:
__builtin_trap(); // CHECK-NEXT: 1: [[#@LINE]]:
i = 84; // CHECK-NEXT: 1: [[#@LINE]]:
Index: compiler-rt/test/profile/Posix/gcov-shared-flush.c
===================================================================
--- compiler-rt/test/profile/Posix/gcov-shared-flush.c
+++ compiler-rt/test/profile/Posix/gcov-shared-flush.c
@@ -7,7 +7,7 @@
// RUN: %clang --coverage -fPIC -shared shared.c -o libfunc.so
// RUN: test -f shared.gcno
-/// Test the case where we exit abruptly after calling __gcov_flush, which means we don't write out the counters at exit.
+/// Test the case where we exit abruptly after calling __gcov_dump, which means we don't write out the counters at exit.
// RUN: %clang -DEXIT_ABRUPTLY -DSHARED_CALL_BEFORE_FLUSH -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t
// RUN: test -f gcov-shared-flush.gcno
@@ -21,7 +21,7 @@
// SHARED: 1: {{[[0-9]+}}:void foo(int n)
-/// Test the case where we exit normally and we have a call to the shared library function before __gcov_flush.
+/// Test the case where we exit normally and we have a call to the shared library function before __gcov_dump.
// RUN: %clang -DSHARED_CALL_BEFORE_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t
// RUN: test -f gcov-shared-flush.gcno
@@ -32,14 +32,15 @@
// BEFORE: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH
// BEFORE-NEXT: 1: {{[0-9]+}}: foo(1);
-// BEFORE: 1: {{[0-9]+}}: __gcov_flush();
+// BEFORE: 1: {{[0-9]+}}: __gcov_dump();
+// BEFORE-NEXT: 1: {{[0-9]+}}: __gcov_reset();
// BEFORE: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH
// BEFORE-NEXT: -: {{[0-9]+}}: foo(1);
// BEFORE: 1: {{[0-9]+}}: bar(5);
// SHARED_ONCE: 1: {{[0-9]+}}:void foo(int n)
-// # Test the case where we exit normally and we have a call to the shared library function after __gcov_flush.
+// # Test the case where we exit normally and we have a call to the shared library function after __gcov_dump.
// RUN: %clang -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t
// RUN: test -f gcov-shared-flush.gcno
@@ -50,12 +51,13 @@
// AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH
// AFTER-NEXT: -: {{[0-9]+}}: foo(1);
-// AFTER: 1: {{[0-9]+}}: __gcov_flush();
+// AFTER: 1: {{[0-9]+}}: __gcov_dump();
+// AFTER-NEXT: 1: {{[0-9]+}}: __gcov_reset();
// AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH
// AFTER-NEXT: 1: {{[0-9]+}}: foo(1);
// AFTER: 1: {{[0-9]+}}: bar(5);
-// # Test the case where we exit normally and we have calls to the shared library function before and after __gcov_flush.
+// # Test the case where we exit normally and we have calls to the shared library function before and after __gcov_dump.
// RUN: %clang -DSHARED_CALL_BEFORE_FLUSH -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t
// RUN: test -f gcov-shared-flush.gcno
@@ -66,7 +68,8 @@
// BEFORE_AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH
// BEFORE_AFTER-NEXT: 1: {{[0-9]+}}: foo(1);
-// BEFORE_AFTER: 1: {{[0-9]+}}: __gcov_flush();
+// BEFORE_AFTER: 1: {{[0-9]+}}: __gcov_dump();
+// BEFORE_AFTER-NEXT: 1: {{[0-9]+}}: __gcov_reset();
// BEFORE_AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH
// BEFORE_AFTER-NEXT: 1: {{[0-9]+}}: foo(1);
// BEFORE_AFTER: 1: {{[0-9]+}}: bar(5);
@@ -78,7 +81,8 @@
}
#else
extern void foo(int n);
-extern void __gcov_flush(void);
+extern void __gcov_dump(void);
+extern void __gcov_reset(void);
int bar1 = 0;
int bar2 = 1;
@@ -96,7 +100,8 @@
#endif
bar(5);
- __gcov_flush();
+ __gcov_dump();
+ __gcov_reset();
bar(5);
#ifdef SHARED_CALL_AFTER_FLUSH
Index: compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
===================================================================
--- compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
+++ compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main_three-libs.c.gcov
@@ -51,21 +51,21 @@
// CHECK-NEXT: -: 46:#endif
// CHECK-NEXT: -: 47:
// CHECK-NEXT: 1: 48: dlerror();
-// CHECK-NEXT: 1: 49: void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
-// CHECK-NEXT: 1: 50: if (gcov_flush1 == NULL) {
-// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+// CHECK-NEXT: 1: 49: void (*gcov_reset1)() = (void (*)())dlsym(f1_handle, "__gcov_reset");
+// CHECK-NEXT: 1: 50: if (gcov_reset1 == NULL) {
+// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_reset in func.shared': %s\n", dlerror());
// CHECK-NEXT: #####: 52: return EXIT_FAILURE;
// CHECK-NEXT: -: 53: }
// CHECK-NEXT: -: 54:
// CHECK-NEXT: 1: 55: dlerror();
-// CHECK-NEXT: 1: 56: void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
-// CHECK-NEXT: 1: 57: if (gcov_flush2 == NULL) {
-// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+// CHECK-NEXT: 1: 56: void (*gcov_reset2)() = (void (*)())dlsym(f2_handle, "__gcov_reset");
+// CHECK-NEXT: 1: 57: if (gcov_reset2 == NULL) {
+// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_reset in func2.shared': %s\n", dlerror());
// CHECK-NEXT: #####: 59: return EXIT_FAILURE;
// CHECK-NEXT: -: 60: }
// CHECK-NEXT: -: 61:
-// CHECK-NEXT: 1: 62: if (gcov_flush1 == gcov_flush2) {
-// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+// CHECK-NEXT: 1: 62: if (gcov_reset1 == gcov_reset2) {
+// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_reset found in func.shared and func2.shared\n");
// CHECK-NEXT: #####: 64: return EXIT_FAILURE;
// CHECK-NEXT: -: 65: }
// CHECK-NEXT: -: 66:
Index: compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
===================================================================
--- compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
+++ compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c.gcov
@@ -51,21 +51,21 @@
// CHECK-NEXT: -: 46:#endif
// CHECK-NEXT: -: 47:
// CHECK-NEXT: 1: 48: dlerror();
-// CHECK-NEXT: 1: 49: void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
-// CHECK-NEXT: 1: 50: if (gcov_flush1 == NULL) {
-// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+// CHECK-NEXT: 1: 49: void (*gcov_reset1)() = (void (*)())dlsym(f1_handle, "__gcov_reset");
+// CHECK-NEXT: 1: 50: if (gcov_reset1 == NULL) {
+// CHECK-NEXT: #####: 51: fprintf(stderr, "unable to find __gcov_reset in func.shared': %s\n", dlerror());
// CHECK-NEXT: #####: 52: return EXIT_FAILURE;
// CHECK-NEXT: -: 53: }
// CHECK-NEXT: -: 54:
// CHECK-NEXT: 1: 55: dlerror();
-// CHECK-NEXT: 1: 56: void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
-// CHECK-NEXT: 1: 57: if (gcov_flush2 == NULL) {
-// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+// CHECK-NEXT: 1: 56: void (*gcov_reset2)() = (void (*)())dlsym(f2_handle, "__gcov_reset");
+// CHECK-NEXT: 1: 57: if (gcov_reset2 == NULL) {
+// CHECK-NEXT: #####: 58: fprintf(stderr, "unable to find __gcov_reset in func2.shared': %s\n", dlerror());
// CHECK-NEXT: #####: 59: return EXIT_FAILURE;
// CHECK-NEXT: -: 60: }
// CHECK-NEXT: -: 61:
-// CHECK-NEXT: 1: 62: if (gcov_flush1 == gcov_flush2) {
-// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+// CHECK-NEXT: 1: 62: if (gcov_reset1 == gcov_reset2) {
+// CHECK-NEXT: #####: 63: fprintf(stderr, "Same __gcov_reset found in func.shared and func2.shared\n");
// CHECK-NEXT: #####: 64: return EXIT_FAILURE;
// CHECK-NEXT: -: 65: }
// CHECK-NEXT: -: 66:
Index: compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
===================================================================
--- compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
+++ compiler-rt/test/profile/Inputs/instrprof-dlopen-dlclose-main.c
@@ -46,21 +46,21 @@
#endif
dlerror();
- void (*gcov_flush1)() = (void (*)())dlsym(f1_handle, "__gcov_flush");
- if (gcov_flush1 == NULL) {
- fprintf(stderr, "unable to find __gcov_flush in func.shared': %s\n", dlerror());
+ void (*gcov_reset1)() = (void (*)())dlsym(f1_handle, "__gcov_reset");
+ if (gcov_reset1 == NULL) {
+ fprintf(stderr, "unable to find __gcov_reset in func.shared': %s\n", dlerror());
return EXIT_FAILURE;
}
dlerror();
- void (*gcov_flush2)() = (void (*)())dlsym(f2_handle, "__gcov_flush");
- if (gcov_flush2 == NULL) {
- fprintf(stderr, "unable to find __gcov_flush in func2.shared': %s\n", dlerror());
+ void (*gcov_reset2)() = (void (*)())dlsym(f2_handle, "__gcov_reset");
+ if (gcov_reset2 == NULL) {
+ fprintf(stderr, "unable to find __gcov_reset in func2.shared': %s\n", dlerror());
return EXIT_FAILURE;
}
- if (gcov_flush1 == gcov_flush2) {
- fprintf(stderr, "Same __gcov_flush found in func.shared and func2.shared\n");
+ if (gcov_reset1 == gcov_reset2) {
+ fprintf(stderr, "Same __gcov_reset found in func.shared and func2.shared\n");
return EXIT_FAILURE;
}
Index: compiler-rt/lib/profile/GCDAProfiling.c
===================================================================
--- compiler-rt/lib/profile/GCDAProfiling.c
+++ compiler-rt/lib/profile/GCDAProfiling.c
@@ -639,25 +639,6 @@
fn_list_remove(&writeout_fn_list);
}
-COMPILER_RT_VISIBILITY
-void llvm_register_flush_function(fn_ptr fn) {
- fn_list_insert(&flush_fn_list, fn);
-}
-
-void __gcov_flush() {
- struct fn_node* curr = flush_fn_list.head;
-
- while (curr) {
- curr->fn();
- curr = curr->next;
- }
-}
-
-COMPILER_RT_VISIBILITY
-void llvm_delete_flush_function_list(void) {
- fn_list_remove(&flush_fn_list);
-}
-
COMPILER_RT_VISIBILITY
void llvm_register_reset_function(fn_ptr fn) {
fn_list_insert(&reset_fn_list, fn);
@@ -698,15 +679,12 @@
#endif
COMPILER_RT_VISIBILITY
-void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn, fn_ptr rfn) {
+void llvm_gcov_init(fn_ptr wfn, fn_ptr rfn) {
static int atexit_ran = 0;
if (wfn)
llvm_register_writeout_function(wfn);
- if (ffn)
- llvm_register_flush_function(ffn);
-
if (rfn)
llvm_register_reset_function(rfn);
@@ -715,11 +693,20 @@
/* Make sure we write out the data and delete the data structures. */
atexit(llvm_delete_reset_function_list);
- atexit(llvm_delete_flush_function_list);
#ifdef _WIN32
atexit(llvm_writeout_and_clear);
#endif
}
}
+void __gcov_dump(void) {
+ for (struct fn_node *f = writeout_fn_list.head; f; f = f->next)
+ f->fn();
+}
+
+void __gcov_reset(void) {
+ for (struct fn_node *f = reset_fn_list.head; f; f = f->next)
+ f->fn();
+}
+
#endif
Index: clang/test/Driver/darwin-ld.c
===================================================================
--- clang/test/Driver/darwin-ld.c
+++ clang/test/Driver/darwin-ld.c
@@ -351,7 +351,8 @@
// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
// RUN: %clang -target x86_64-apple-darwin12 -fprofile-arcs -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=GCOV_EXPORT %s < %t.log
-// GCOV_EXPORT: "-exported_symbol" "___gcov_flush"
+// GCOV_EXPORT: "-exported_symbol" "___gcov_dump"
+// GCOV_EXPORT: "-exported_symbol" "___gcov_reset"
//
// Check that we can pass the outliner down to the linker.
// RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1187,7 +1187,8 @@
// runtime's functionality.
if (hasExportSymbolDirective(Args)) {
if (ForGCOV) {
- addExportedSymbol(CmdArgs, "___gcov_flush");
+ addExportedSymbol(CmdArgs, "___gcov_dump");
+ addExportedSymbol(CmdArgs, "___gcov_reset");
addExportedSymbol(CmdArgs, "_flush_fn_list");
addExportedSymbol(CmdArgs, "_writeout_fn_list");
addExportedSymbol(CmdArgs, "_reset_fn_list");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits