Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,14 @@ option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatom

option(COMPILER_RT_PROFILE_BAREMETAL "Build minimal baremetal profile library" OFF)

# Opt-in clang_rt.profile_rocm (built /MD on Windows, depends on the sanitizer
# interception library). Off by default on all platforms so default builds are
# unaffected.
option(COMPILER_RT_BUILD_PROFILE_ROCM
"Build the host-side ROCm/HIP device profile collection runtime (clang_rt.profile_rocm)"
OFF)
mark_as_advanced(COMPILER_RT_BUILD_PROFILE_ROCM)

include(config-ix)

#================================
Expand Down
59 changes: 59 additions & 0 deletions compiler-rt/lib/profile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,62 @@ else()
LINK_LIBS ${PROFILE_LINK_LIBS}
PARENT_TARGET profile)
endif()

# clang_rt.profile_rocm: opt-in, self-contained host-side profile runtime for
# HIP/ROCm device PGO. It is a superset of clang_rt.profile (all base sources
# plus InstrProfilingPlatformROCm.cpp and its interceptor dependency), built
# entirely /MD on Windows so a single CRT model holds within the archive and
# clang_rt.profile is left untouched (/MT, no ROCm). The driver links it ahead
# of clang_rt.profile, which then stays inert.
if(COMPILER_RT_BUILD_PROFILE_ROCM AND NOT COMPILER_RT_PROFILE_BAREMETAL
AND COMPILER_RT_HAS_INTERCEPTION
AND TARGET RTInterception.${COMPILER_RT_DEFAULT_TARGET_ARCH}
AND TARGET RTSanitizerCommon.${COMPILER_RT_DEFAULT_TARGET_ARCH}
AND TARGET RTSanitizerCommonLibc.${COMPILER_RT_DEFAULT_TARGET_ARCH})

set(PROFILE_ROCM_SOURCES ${PROFILE_SOURCES} InstrProfilingPlatformROCm.cpp)

# Enables the device-collection call in InstrProfilingFile.c.
set(PROFILE_ROCM_FLAGS ${EXTRA_FLAGS} -DCOMPILER_RT_BUILD_PROFILE_ROCM=1)

# The archive is linked from C, so the C++ ROCm source must not emit an
# exception personality (__gxx_personality_v0).
append_list_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions
PROFILE_ROCM_FLAGS)

# The interceptor path needs sanitizer_common symbols; merge the same object
# libs as clang_rt.cfi so the archive stays self-contained.
set(PROFILE_ROCM_OBJECT_LIBS
RTInterception
RTSanitizerCommon
RTSanitizerCommonLibc)

if(MSVC)
# These merged object libs are built /MD; match it so the archive is
# CRT-consistent. clang_rt.profile stays /MT.
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
endif()

if(APPLE)
add_compiler_rt_runtime(clang_rt.profile_rocm
STATIC
OS ${PROFILE_SUPPORTED_OS}
ARCHS ${PROFILE_SUPPORTED_ARCH}
OBJECT_LIBS ${PROFILE_ROCM_OBJECT_LIBS}
CFLAGS ${PROFILE_ROCM_FLAGS}
SOURCES ${PROFILE_ROCM_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
LINK_LIBS ${PROFILE_LINK_LIBS}
PARENT_TARGET profile)
else()
add_compiler_rt_runtime(clang_rt.profile_rocm
STATIC
ARCHS ${PROFILE_SUPPORTED_ARCH}
OBJECT_LIBS ${PROFILE_ROCM_OBJECT_LIBS}
CFLAGS ${PROFILE_ROCM_FLAGS}
SOURCES ${PROFILE_ROCM_SOURCES}
ADDITIONAL_HEADERS ${PROFILE_HEADERS}
LINK_LIBS ${PROFILE_LINK_LIBS}
PARENT_TARGET profile)
endif()
endif()
30 changes: 30 additions & 0 deletions compiler-rt/lib/profile/InstrProfilingFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@
#include "InstrProfilingPort.h"
#include "InstrProfilingUtil.h"

/* Weak so non-HIP programs do not force InstrProfilingPlatformROCm.o (and its
* transitive sanitizer_common / interception dependencies) into the host link
* out of libclang_rt.profile.a. HIP programs emit strong references to other
* ROCm-runtime symbols (e.g. __llvm_profile_offload_register_shadow_variable)
* that pull in the strong definition.
* No COMPILER_RT_VISIBILITY: a hidden weak-undefined symbol is non-preemptible
* and the address test at the call site would fold to true.
* Windows: __declspec(selectany) is data-only, and the ROCm interceptor path
* is not used there, so keep the original strong extern. */
#if COMPILER_RT_BUILD_PROFILE_ROCM
#if defined(_WIN32)
extern int __llvm_profile_hip_collect_device_data(void);
#else
__attribute__((weak)) int __llvm_profile_hip_collect_device_data(void);
#endif
#endif

/* From where is profile name specified.
* The order the enumerators define their
* precedence. Re-order them may lead to
Expand Down Expand Up @@ -1198,6 +1215,19 @@ int __llvm_profile_write_file(void) {
if (rc)
PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));

/* On non-Windows the declaration is weak: only invoked when
* InstrProfilingPlatformROCm.o is in the link, which happens when the program
* references other ROCm-runtime symbols (HIP-with-PGO). Warning on failure is
* handled inside the callee. */
#if COMPILER_RT_BUILD_PROFILE_ROCM
#if defined(_WIN32)
(void)__llvm_profile_hip_collect_device_data();
#else
if (&__llvm_profile_hip_collect_device_data)
(void)__llvm_profile_hip_collect_device_data();
#endif
#endif

// Restore SIGKILL.
if (PDeathSig == 1)
lprofRestoreSigKill();
Expand Down
Loading