diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 58ea75c42d14..a92258ae1244 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -312,6 +312,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/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 084a7060e8d1..1f82ff3cf753 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -842,7 +842,7 @@ else() endif() if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI|Haiku") + (OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI|Haiku" OR COMPILER_RT_PROFILE_BAREMETAL)) set(COMPILER_RT_HAS_PROFILE TRUE) else() set(COMPILER_RT_HAS_PROFILE FALSE) diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt index a6402f80b890..7c8473cc5f20 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,26 @@ 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 +148,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 da04d8ebdec9..d59ec78ad329 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 8791d5aa5dd7..187ef55ef378 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 92721c4fd55e..681abda0188a 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" diff --git a/compiler-rt/lib/profile/InstrProfilingMergeFile.c b/compiler-rt/lib/profile/InstrProfilingMergeFile.c index 8923ba21cc58..d8fe1f667795 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 558b7fc8cad6..acdb222004fd 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 19414ab78b3b..f5d1c74f1011 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 66d697885eae..0149c7aacb2d 100644 --- a/compiler-rt/lib/profile/InstrProfilingPort.h +++ b/compiler-rt/lib/profile/InstrProfilingPort.h @@ -117,9 +117,17 @@ static inline size_t getpagesize(void) { return S.dwPageSize; } #else /* defined(_WIN32) */ +#ifndef COMPILER_RT_PROFILE_BAREMETAL #include +#endif #endif /* defined(_WIN32) */ +#ifdef COMPILER_RT_PROFILE_BAREMETAL +// Baremetal doesn't support logging +#define PROF_ERR(Format, ...) +#define PROF_WARN(Format, ...) +#define PROF_NOTE(Format, ...) +#else #define PROF_ERR(Format, ...) \ fprintf(stderr, "LLVM Profile Error: " Format, __VA_ARGS__); @@ -128,6 +136,7 @@ static inline size_t getpagesize(void) { #define PROF_NOTE(Format, ...) \ fprintf(stderr, "LLVM Profile Note: " Format, __VA_ARGS__); +#endif /* COMPILER_RT_PROFILE_BAREMETAL */ #ifndef MAP_FILE #define MAP_FILE 0 @@ -137,16 +146,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_ */