diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 1ed4e66d5622f..66fe9c6563230 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -309,6 +309,8 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF) +option(COMPILER_RT_PROFILE_BAREMETAL "Build minimal baremetal profile library" OFF) + include(config-ix) #================================ diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt index a6402f80b890a..7795e7399f493 100644 --- a/compiler-rt/lib/profile/CMakeLists.txt +++ b/compiler-rt/lib/profile/CMakeLists.txt @@ -60,12 +60,9 @@ int main() { add_compiler_rt_component(profile) set(PROFILE_SOURCES - GCDAProfiling.c InstrProfiling.c InstrProfilingInternal.c - InstrProfilingValue.c InstrProfilingBuffer.c - InstrProfilingFile.c InstrProfilingMerge.c InstrProfilingMergeFile.c InstrProfilingNameVar.c @@ -77,10 +74,25 @@ set(PROFILE_SOURCES InstrProfilingPlatformLinux.c InstrProfilingPlatformOther.c InstrProfilingPlatformWindows.c - InstrProfilingRuntime.cpp - InstrProfilingUtil.c ) +if (NOT COMPILER_RT_PROFILE_BAREMETAL) + # For baremetal, exclude the following: + # - Anything that contains filesystem operations (InstrProfilingFile.c, + # InstrProfilingUtils.c) + # - Initialization, because it isn't necesary without the filesystem bits + # on ELF targets (InstrProfilingRuntime.cpp). + # - Value profiling, because it requires malloc (InstrProfilingValue.c). + # This could be optional if someone needs it. + # - GCDA profiling, which is unrelated (GCDAProfiling.c) + list(APPEND PROFILE_SOURCES GCDAProfiling.c + InstrProfilingFile.c + InstrProfilingRuntime.cpp + InstrProfilingUtil.c + InstrProfilingValue.c + ) +endif() + set(PROFILE_HEADERS InstrProfiling.h InstrProfilingInternal.h @@ -135,6 +147,12 @@ if(COMPILER_RT_TARGET_HAS_UNAME) -DCOMPILER_RT_HAS_UNAME=1) endif() +if(COMPILER_RT_PROFILE_BAREMETAL) + set(EXTRA_FLAGS + ${EXTRA_FLAGS} + -DCOMPILER_RT_PROFILE_BAREMETAL=1) +endif() + if(MSVC) # profile historically has only been supported with the static runtime # on windows diff --git a/compiler-rt/lib/profile/InstrProfiling.c b/compiler-rt/lib/profile/InstrProfiling.c index da04d8ebdec95..d59ec78ad3296 100644 --- a/compiler-rt/lib/profile/InstrProfiling.c +++ b/compiler-rt/lib/profile/InstrProfiling.c @@ -10,8 +10,6 @@ // with freestanding compilation. See `darwin_add_builtin_libraries`. #include -#include -#include #include #include "InstrProfiling.h" diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h index 8791d5aa5dd70..187ef55ef3784 100644 --- a/compiler-rt/lib/profile/InstrProfiling.h +++ b/compiler-rt/lib/profile/InstrProfiling.h @@ -10,7 +10,10 @@ #define PROFILE_INSTRPROFILING_H_ #include "InstrProfilingPort.h" +#include +#ifndef COMPILER_RT_PROFILE_BAREMETAL #include +#endif // Make sure __LLVM_INSTR_PROFILE_GENERATE is always defined before // including instr_prof_interface.h so the interface functions are @@ -200,7 +203,9 @@ int __llvm_profile_write_file(void); * copying the old profile file to new profile file and this function is usually * used when the proess doesn't have permission to open file. */ +#ifndef COMPILER_RT_PROFILE_BAREMETAL int __llvm_profile_set_file_object(FILE *File, int EnableMerge); +#endif /*! \brief Register to write instrumentation data to file at exit. */ int __llvm_profile_register_write_file_atexit(void); diff --git a/compiler-rt/lib/profile/InstrProfilingMerge.c b/compiler-rt/lib/profile/InstrProfilingMerge.c index 92721c4fd55ea..9b84b512ad9c7 100644 --- a/compiler-rt/lib/profile/InstrProfilingMerge.c +++ b/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -11,7 +11,6 @@ #include "InstrProfiling.h" #include "InstrProfilingInternal.h" -#include "InstrProfilingUtil.h" #define INSTR_PROF_VALUE_PROF_DATA #include "profile/InstrProfData.inc" @@ -131,9 +130,11 @@ COMPILER_RT_VISIBILITY int __llvm_profile_merge_from_buffer(const char *ProfileData, uint64_t ProfileSize) { if (__llvm_profile_get_version() & VARIANT_MASK_TEMPORAL_PROF) { +#ifndef COMPILER_RT_PROFILE_BAREMETAL PROF_ERR("%s\n", "Temporal profiles do not support profile merging at runtime. " "Instead, merge raw profiles using the llvm-profdata tool."); +#endif return 1; } diff --git a/compiler-rt/lib/profile/InstrProfilingMergeFile.c b/compiler-rt/lib/profile/InstrProfilingMergeFile.c index 8923ba21cc580..d8fe1f6677950 100644 --- a/compiler-rt/lib/profile/InstrProfilingMergeFile.c +++ b/compiler-rt/lib/profile/InstrProfilingMergeFile.c @@ -13,7 +13,6 @@ #include "InstrProfiling.h" #include "InstrProfilingInternal.h" -#include "InstrProfilingUtil.h" #define INSTR_PROF_VALUE_PROF_DATA #include "profile/InstrProfData.inc" diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index 558b7fc8cad62..acdb222004fd4 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -6,16 +6,33 @@ |* \*===----------------------------------------------------------------------===*/ +// This file defines profile data symbols for ELF, wasm, XCOFF. It assumes +// __start_ and __stop_ symbols for profile data point at the beginning and +// end of the sections in question. (This is technically a linker feature, +// not a file format feature, but linkers for these targets support it.) +// +// MachO (MacOS/iOS) and PE-COFF (Windows) have a similar support, but the +// identifiers are different, so the support is in separate files. +// +// Support for targets which don't have linker support is in +// InstrProfilingPlatformOther.c. +// +// This file also contains code to extract ELF build IDs from the ELF file, +// to identify the build which generated the file. + #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \ - defined(_AIX) || defined(__wasm__) || defined(__HAIKU__) + defined(_AIX) || defined(__wasm__) || defined(__HAIKU__) || \ + defined(COMPILER_RT_PROFILE_BAREMETAL) -#if !defined(_AIX) && !defined(__wasm__) +#if !defined(_AIX) && !defined(__wasm__) && \ + !defined(COMPILER_RT_PROFILE_BAREMETAL) +// Includes for non-baremetal ELF targets, used to output build IDs. #include #include -#endif #include #include +#endif #include "InstrProfiling.h" #include "InstrProfilingInternal.h" diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c index 19414ab78b3be..f5d1c74f10115 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c @@ -6,10 +6,18 @@ |* \*===----------------------------------------------------------------------===*/ +// This file defines a fallback implementation to compute the locations of +// profile data sections, for targets that don't have linker support. No +// commonly used targets use this codepath. +// +// This implementation expects the compiler instrumentation pass to define a +// constructor in each file which calls into this file. + #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \ !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \ !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && \ - !defined(__wasm__) && !defined(__HAIKU__) + !defined(__wasm__) && !defined(__HAIKU__) && \ + !defined(COMPILER_RT_PROFILE_BAREMETAL) #include #include diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h index 66d697885eaee..151ed94007413 100644 --- a/compiler-rt/lib/profile/InstrProfilingPort.h +++ b/compiler-rt/lib/profile/InstrProfilingPort.h @@ -117,7 +117,9 @@ static inline size_t getpagesize(void) { return S.dwPageSize; } #else /* defined(_WIN32) */ +#ifndef COMPILER_RT_PROFILE_BAREMETAL #include +#endif #endif /* defined(_WIN32) */ #define PROF_ERR(Format, ...) \ @@ -137,16 +139,6 @@ static inline size_t getpagesize(void) { #define O_BINARY 0 #endif -#if defined(__FreeBSD__) - -#include -#include - -#else /* defined(__FreeBSD__) */ - -#include #include -#endif /* defined(__FreeBSD__) && defined(__i386__) */ - #endif /* PROFILE_INSTRPROFILING_PORT_H_ */