mirror of
https://github.com/intel/llvm.git
synced 2026-01-12 10:17:28 +08:00
[compiler-rt] Add baremetal version of profile library. (#167998)
Adds a flag COMPILER_RT_PROFILE_BAREMETAL, which disables the parts of the profile runtime which require a filesystem or malloc. This minimal library only requires string.h from the C library. This is useful for profiling or code coverage of baremetal images, which don't have filesystem APIs, and might not have malloc configured (or have limited heap space). Expected usage: - Add code to your project to call `__llvm_profile_get_size_for_buffer()` and `__llvm_profile_write_buffer()` to write the profile data to a buffer in memory, and then copy that data off the device using target-specific tools. - If you're using a linker script, set up your linker script to map the profiling and coverage input sections to corresponding output sections with the same name, and mark them KEEP. `__llvm_covfun` and `__llvm_covmap` are non-allocatable, `__llvm_prf_names` is read-only allocatable, and `__llvm_prf_cnts` and `__llvm_prf_data` are read-write allocatable. - The resulting data is in same format as the non-baremetal profiles. There's some room for improvement here in the future for doing profiling and code coverage for baremetal. If we revised the profiling format, and introduced some additional host tooling, we could move some of the metadata into non-allocated sections, and construct the profraw file on the host. But this patch is sufficient for some use-cases.
This commit is contained in:
@@ -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)
|
||||
|
||||
#================================
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
// with freestanding compilation. See `darwin_add_builtin_libraries`.
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
#define PROFILE_INSTRPROFILING_H_
|
||||
|
||||
#include "InstrProfilingPort.h"
|
||||
#include <stddef.h>
|
||||
#ifndef COMPILER_RT_PROFILE_BAREMETAL
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
#include "InstrProfilingInternal.h"
|
||||
#include "InstrProfilingUtil.h"
|
||||
|
||||
#define INSTR_PROF_VALUE_PROF_DATA
|
||||
#include "profile/InstrProfData.inc"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
#include "InstrProfilingInternal.h"
|
||||
#include "InstrProfilingUtil.h"
|
||||
|
||||
#define INSTR_PROF_VALUE_PROF_DATA
|
||||
#include "profile/InstrProfData.inc"
|
||||
|
||||
@@ -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 <elf.h>
|
||||
#include <link.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
#include "InstrProfilingInternal.h"
|
||||
|
||||
@@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -117,9 +117,17 @@ static inline size_t getpagesize(void) {
|
||||
return S.dwPageSize;
|
||||
}
|
||||
#else /* defined(_WIN32) */
|
||||
#ifndef COMPILER_RT_PROFILE_BAREMETAL
|
||||
#include <unistd.h>
|
||||
#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 <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#else /* defined(__FreeBSD__) */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#endif /* defined(__FreeBSD__) && defined(__i386__) */
|
||||
|
||||
#endif /* PROFILE_INSTRPROFILING_PORT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user