Index: compiler-rt/lib/profile/InstrProfiling.h =================================================================== --- compiler-rt/lib/profile/InstrProfiling.h +++ compiler-rt/lib/profile/InstrProfiling.h @@ -218,6 +218,9 @@ /*! \brief Initialize file handling. */ void __llvm_profile_initialize_file(void); +/*! \brief Initialize the profile runtime. */ +void __llvm_profile_initialize(void); + /*! * \brief Return path prefix (excluding the base filename) of the profile data. * This is useful for users using \c -fprofile-generate=./path_prefix who do Index: compiler-rt/lib/profile/InstrProfilingFile.c =================================================================== --- compiler-rt/lib/profile/InstrProfilingFile.c +++ compiler-rt/lib/profile/InstrProfilingFile.c @@ -35,6 +35,9 @@ #include "InstrProfilingPort.h" #include "InstrProfilingUtil.h" +/* When counters are being relocated at runtime, this parameter is set to 1. */ +COMPILER_RT_VISIBILITY int RuntimeCounterRelocation = 0; + /* From where is profile name specified. * The order the enumerators define their * precedence. Re-order them may lead to @@ -951,10 +954,10 @@ return FilenameBuf; } -/* This method is invoked by the runtime initialization hook - * InstrProfilingRuntime.o if it is linked in. Both user specified +/* This API initializes the file handling, both user specified * profile path via -fprofile-instr-generate= and LLVM_PROFILE_FILE - * environment variable can override this default value. */ + * environment variable can override this default value. + */ COMPILER_RT_VISIBILITY void __llvm_profile_initialize_file(void) { const char *EnvFilenamePat; @@ -982,6 +985,15 @@ parseAndSetFilename(SelectedPat, PNS, 0); } +/* This method is invoked by the runtime initialization hook + * InstrProfilingRuntime.o if it is linked in. + */ +void __llvm_profile_initialize(void) { + __llvm_profile_initialize_file(); + if (!__llvm_profile_is_continuous_mode_enabled()) + __llvm_profile_register_write_file_atexit(); +} + /* This API is directly called by the user application code. It has the * highest precedence compared with LLVM_PROFILE_FILE environment variable * and command line option -fprofile-instr-generate=. Index: compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c =================================================================== --- compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c +++ compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c @@ -34,7 +34,10 @@ #include "InstrProfilingInternal.h" #include "InstrProfilingUtil.h" -/* VMO that contains the coverage data shared across all modules. */ +/* When counters are being relocated at runtime, this parameter is set to 1. */ +COMPILER_RT_VISIBILITY int RuntimeCounterRelocation = 1; + +/* VMO that contains the profile data for this module. */ static zx_handle_t __llvm_profile_vmo; /* Current offset within the VMO where data should be written next. */ static uint64_t __llvm_profile_offset; @@ -92,43 +95,21 @@ This->WriterCtx = NULL; } -static int dump(void) { - if (lprofProfileDumped()) { - lprofWrite("LLVM Profile: data not published: already written.\n"); - return 0; - } - - /* Check if there is llvm/runtime version mismatch. */ - if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) { - lprofWrite("LLVM Profile: runtime and instrumentation version mismatch: " - "expected %d, but got %d\n", - INSTR_PROF_RAW_VERSION, - (int)GET_VERSION(__llvm_profile_get_version())); - return -1; - } - - /* Write the profile data into the mapped region. */ - ProfDataWriter VMOWriter; - initVMOWriter(&VMOWriter); - if (lprofWriteData(&VMOWriter, lprofGetVPDataReader(), 0) != 0) - return -1; - - return 0; -} - +/* This method is invoked by the runtime initialization hook + * InstrProfilingRuntime.o if it is linked in. + */ COMPILER_RT_VISIBILITY -int __llvm_profile_dump(void) { - int rc = dump(); - lprofSetProfileDumped(); - return rc; -} - -static void dumpWithoutReturn(void) { dump(); } +void __llvm_profile_initialize(void) { + if (__llvm_profile_counter_bias == -1) { + lprofWrite("LLVM Profile: counter relocation at runtime is required\n"); + return; + } -static void createVMO(void) { /* Don't create VMO if it has been alread created. */ - if (__llvm_profile_vmo != ZX_HANDLE_INVALID) + if (__llvm_profile_vmo != ZX_HANDLE_INVALID) { + lprofWrite("LLVM Profile: VMO has already been created\n"); return; + } const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); @@ -211,23 +192,4 @@ (uintptr_t)__llvm_profile_begin_counters() + CountersOffset; } -/* This method is invoked by the runtime initialization hook - * InstrProfilingRuntime.o if it is linked in. - */ -COMPILER_RT_VISIBILITY -void __llvm_profile_initialize_file(void) { createVMO(); } - -COMPILER_RT_VISIBILITY -int __llvm_profile_register_write_file_atexit(void) { - static bool HasBeenRegistered = false; - - if (HasBeenRegistered) - return 0; - - lprofSetupValueProfiler(); - - HasBeenRegistered = true; - return atexit(dumpWithoutReturn); -} - #endif Index: compiler-rt/lib/profile/InstrProfilingRuntime.cpp =================================================================== --- compiler-rt/lib/profile/InstrProfilingRuntime.cpp +++ compiler-rt/lib/profile/InstrProfilingRuntime.cpp @@ -19,9 +19,7 @@ class RegisterRuntime { public: RegisterRuntime() { - __llvm_profile_initialize_file(); - if (!__llvm_profile_is_continuous_mode_enabled()) - __llvm_profile_register_write_file_atexit(); + __llvm_profile_initialize(); } };