aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt
diff options
context:
space:
mode:
authorQiongsi Wu <274595+qiongsiwu@users.noreply.github.com>2024-01-22 14:54:58 -0500
committerGitHub <noreply@github.com>2024-01-22 14:54:58 -0500
commit4f21fb84479286ddc781d73f8df152f81a8264e7 (patch)
tree672a0355a3338e21036c52f3a4828682f494d3f4 /compiler-rt
parent02aa6956b5b6c92f3d4aea0aa466ed0d33343335 (diff)
downloadllvm-4f21fb84479286ddc781d73f8df152f81a8264e7.zip
llvm-4f21fb84479286ddc781d73f8df152f81a8264e7.tar.gz
llvm-4f21fb84479286ddc781d73f8df152f81a8264e7.tar.bz2
[PGO] Reland PGO's Counter Reset and File Dumping APIs #76471 (#78285)
https://github.com/llvm/llvm-project/pull/76471 caused buildbot failures on Windows. For more details, see https://github.com/llvm/llvm-project/issues/77546. This PR revises the test and relands https://github.com/llvm/llvm-project/pull/76471.
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/include/CMakeLists.txt1
-rw-r--r--compiler-rt/include/profile/instr_prof_interface.h92
-rw-r--r--compiler-rt/lib/profile/InstrProfiling.h61
-rw-r--r--compiler-rt/test/profile/Linux/instrprof-weak-symbol.c16
-rw-r--r--compiler-rt/test/profile/instrprof-api.c49
5 files changed, 169 insertions, 50 deletions
diff --git a/compiler-rt/include/CMakeLists.txt b/compiler-rt/include/CMakeLists.txt
index 78427be..7a100c6 100644
--- a/compiler-rt/include/CMakeLists.txt
+++ b/compiler-rt/include/CMakeLists.txt
@@ -44,6 +44,7 @@ endif(COMPILER_RT_BUILD_ORC)
if (COMPILER_RT_BUILD_PROFILE)
set(PROFILE_HEADERS
profile/InstrProfData.inc
+ profile/instr_prof_interface.h
)
endif(COMPILER_RT_BUILD_PROFILE)
diff --git a/compiler-rt/include/profile/instr_prof_interface.h b/compiler-rt/include/profile/instr_prof_interface.h
new file mode 100644
index 0000000..be40f26
--- /dev/null
+++ b/compiler-rt/include/profile/instr_prof_interface.h
@@ -0,0 +1,92 @@
+/*===---- instr_prof_interface.h - Instrumentation PGO User Program API ----===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ *
+ * This header provides a public interface for fine-grained control of counter
+ * reset and profile dumping. These interface functions can be directly called
+ * in user programs.
+ *
+\*===---------------------------------------------------------------------===*/
+
+#ifndef COMPILER_RT_INSTR_PROFILING
+#define COMPILER_RT_INSTR_PROFILING
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __LLVM_INSTR_PROFILE_GENERATE
+// Profile file reset and dump interfaces.
+// When `-fprofile[-instr]-generate`/`-fcs-profile-generate` is in effect,
+// clang defines __LLVM_INSTR_PROFILE_GENERATE to pick up the API calls.
+
+/*!
+ * \brief Set the filename for writing instrumentation data.
+ *
+ * Sets the filename to be used for subsequent calls to
+ * \a __llvm_profile_write_file().
+ *
+ * \c Name is not copied, so it must remain valid. Passing NULL resets the
+ * filename logic to the default behaviour.
+ *
+ * Note: There may be multiple copies of the profile runtime (one for each
+ * instrumented image/DSO). This API only modifies the filename within the
+ * copy of the runtime available to the calling image.
+ *
+ * Warning: This is a no-op if continuous mode (\ref
+ * __llvm_profile_is_continuous_mode_enabled) is on. The reason for this is
+ * that in continuous mode, profile counters are mmap()'d to the profile at
+ * program initialization time. Support for transferring the mmap'd profile
+ * counts to a new file has not been implemented.
+ */
+void __llvm_profile_set_filename(const char *Name);
+
+/*!
+ * \brief Interface to set all PGO counters to zero for the current process.
+ *
+ */
+void __llvm_profile_reset_counters(void);
+
+/*!
+ * \brief this is a wrapper interface to \c __llvm_profile_write_file.
+ * After this interface is invoked, an already dumped flag will be set
+ * so that profile won't be dumped again during program exit.
+ * Invocation of interface __llvm_profile_reset_counters will clear
+ * the flag. This interface is designed to be used to collect profile
+ * data from user selected hot regions. The use model is
+ * __llvm_profile_reset_counters();
+ * ... hot region 1
+ * __llvm_profile_dump();
+ * .. some other code
+ * __llvm_profile_reset_counters();
+ * ... hot region 2
+ * __llvm_profile_dump();
+ *
+ * It is expected that on-line profile merging is on with \c %m specifier
+ * used in profile filename . If merging is not turned on, user is expected
+ * to invoke __llvm_profile_set_filename to specify different profile names
+ * for different regions before dumping to avoid profile write clobbering.
+ */
+int __llvm_profile_dump(void);
+
+// Interface to dump the current process' order file to disk.
+int __llvm_orderfile_dump(void);
+
+#else
+
+#define __llvm_profile_set_filename(Name)
+#define __llvm_profile_reset_counters()
+#define __llvm_profile_dump() (0)
+#define __llvm_orderfile_dump() (0)
+
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h
index 1371159..0123908 100644
--- a/compiler-rt/lib/profile/InstrProfiling.h
+++ b/compiler-rt/lib/profile/InstrProfiling.h
@@ -12,6 +12,17 @@
#include "InstrProfilingPort.h"
#include <stdio.h>
+// Make sure __LLVM_INSTR_PROFILE_GENERATE is always defined before
+// including instr_prof_interface.h so the interface functions are
+// declared correctly for the runtime.
+// __LLVM_INSTR_PROFILE_GENERATE is always `#undef`ed after the header,
+// because compiler-rt does not support profiling the profiling runtime itself.
+#ifndef __LLVM_INSTR_PROFILE_GENERATE
+#define __LLVM_INSTR_PROFILE_GENERATE
+#endif
+#include "profile/instr_prof_interface.h"
+#undef __LLVM_INSTR_PROFILE_GENERATE
+
#define INSTR_PROF_VISIBILITY COMPILER_RT_VISIBILITY
#include "profile/InstrProfData.inc"
@@ -101,12 +112,6 @@ ValueProfNode *__llvm_profile_end_vnodes();
uint32_t *__llvm_profile_begin_orderfile();
/*!
- * \brief Clear profile counters to zero.
- *
- */
-void __llvm_profile_reset_counters(void);
-
-/*!
* \brief Merge profile data from buffer.
*
* Read profile data from buffer \p Profile and merge with in-process profile
@@ -156,50 +161,6 @@ void __llvm_profile_instrument_target_value(uint64_t TargetValue, void *Data,
int __llvm_profile_write_file(void);
int __llvm_orderfile_write_file(void);
-/*!
- * \brief this is a wrapper interface to \c __llvm_profile_write_file.
- * After this interface is invoked, an already dumped flag will be set
- * so that profile won't be dumped again during program exit.
- * Invocation of interface __llvm_profile_reset_counters will clear
- * the flag. This interface is designed to be used to collect profile
- * data from user selected hot regions. The use model is
- * __llvm_profile_reset_counters();
- * ... hot region 1
- * __llvm_profile_dump();
- * .. some other code
- * __llvm_profile_reset_counters();
- * ... hot region 2
- * __llvm_profile_dump();
- *
- * It is expected that on-line profile merging is on with \c %m specifier
- * used in profile filename . If merging is not turned on, user is expected
- * to invoke __llvm_profile_set_filename to specify different profile names
- * for different regions before dumping to avoid profile write clobbering.
- */
-int __llvm_profile_dump(void);
-
-int __llvm_orderfile_dump(void);
-
-/*!
- * \brief Set the filename for writing instrumentation data.
- *
- * Sets the filename to be used for subsequent calls to
- * \a __llvm_profile_write_file().
- *
- * \c Name is not copied, so it must remain valid. Passing NULL resets the
- * filename logic to the default behaviour.
- *
- * Note: There may be multiple copies of the profile runtime (one for each
- * instrumented image/DSO). This API only modifies the filename within the
- * copy of the runtime available to the calling image.
- *
- * Warning: This is a no-op if continuous mode (\ref
- * __llvm_profile_is_continuous_mode_enabled) is on. The reason for this is
- * that in continuous mode, profile counters are mmap()'d to the profile at
- * program initialization time. Support for transferring the mmap'd profile
- * counts to a new file has not been implemented.
- */
-void __llvm_profile_set_filename(const char *Name);
/*!
* \brief Set the FILE object for writing instrumentation data. Return 0 if set
diff --git a/compiler-rt/test/profile/Linux/instrprof-weak-symbol.c b/compiler-rt/test/profile/Linux/instrprof-weak-symbol.c
new file mode 100644
index 0000000..eda299c
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/instrprof-weak-symbol.c
@@ -0,0 +1,16 @@
+// Test the linker feature that treats undefined weak symbols as null values.
+
+// RUN: %clang_pgogen -o %t %s
+// RUN: not %t
+// RUN: %clang -o %t %s
+// RUN: %t
+
+__attribute__((weak)) void __llvm_profile_reset_counters(void);
+
+int main() {
+ if (__llvm_profile_reset_counters) {
+ __llvm_profile_reset_counters();
+ return 1;
+ }
+ return 0;
+}
diff --git a/compiler-rt/test/profile/instrprof-api.c b/compiler-rt/test/profile/instrprof-api.c
new file mode 100644
index 0000000..fedec2d
--- /dev/null
+++ b/compiler-rt/test/profile/instrprof-api.c
@@ -0,0 +1,49 @@
+// UNSUPPORTED: target={{.*windows.*}}
+// __llvm_orderfile_dump() is not supported on Windows.
+
+// Testing profile generate.
+// RUN: %clang_profgen %s -S -emit-llvm -o - | FileCheck %s --check-prefix=PROFGEN
+// RUN: %clang_pgogen %s -S -emit-llvm -o - | FileCheck %s --check-prefix=PROFGEN
+
+// Testing profile use. Generate some profile file first.
+// RUN: rm -rf rawprof.profraw
+// RUN: %clang_profgen -o %t1 %s
+// RUN: %run %t1
+// RUN: llvm-profdata merge -o %t1.profdata rawprof.profraw
+// RUN: %clang_profuse=%t1.profdata %s -S -emit-llvm -o - | FileCheck %s --check-prefix=PROFUSE
+// RUN: rm -rf rawprof.profraw
+// RUN: %clang_pgogen -o %t2 %s
+// RUN: %run %t2
+// RUN: llvm-profdata merge -o %t2.profdata rawprof.profraw
+// RUN: %clang_pgouse=%t2.profdata %s -S -emit-llvm -o - | FileCheck %s --check-prefix=PROFUSE
+#include "profile/instr_prof_interface.h"
+
+__attribute__((noinline)) int bar() { return 4; }
+
+int foo() {
+ __llvm_profile_reset_counters();
+ // PROFGEN: call void @__llvm_profile_reset_counters()
+ // PROFUSE-NOT: call void @__llvm_profile_reset_counters()
+ return bar();
+}
+
+// PROFUSE-NOT: declare void @__llvm_profile_reset_counters()
+
+int main() {
+ int z = foo() + 3;
+ __llvm_profile_set_filename("rawprof.profraw");
+ // PROFGEN: call void @__llvm_profile_set_filename(ptr noundef @{{.*}})
+ // PROFUSE-NOT: call void @__llvm_profile_set_filename(ptr noundef @{{.*}})
+ if (__llvm_profile_dump())
+ return 2;
+ // PROFGEN: %{{.*}} = call {{(signext )*}}i32 @__llvm_profile_dump()
+ // PROFUSE-NOT: %{{.*}} = call {{(signext )*}}i32 @__llvm_profile_dump()
+ __llvm_orderfile_dump();
+ // PROFGEN: %{{.*}} = call {{(signext )*}}i32 @__llvm_orderfile_dump()
+ // PROFUSE-NOT: %{{.*}} = call {{(signext )*}}i32 @__llvm_orderfile_dump()
+ return z + bar() - 11;
+}
+
+// PROFUSE-NOT: declare void @__llvm_profile_set_filename(ptr noundef)
+// PROFUSE-NOT: declare signext i32 @__llvm_profile_dump()
+// PROFUSE-NOT: declare signext i32 @__llvm_orderfile_dump()