Merge branch 'feat/llvm-opt-integration' into 'master'

feat(compiler): add ESP-IDF LLVM optimization enablement framework

See merge request espressif/esp-idf!51154
This commit is contained in:
Marius Vikhammer
2026-09-07 10:11:37 +08:00
24 changed files with 742 additions and 2 deletions
+72
View File
@@ -471,6 +471,74 @@ This can be useful if there is upstream code that emits warnings.
When using these commands, place them after the call to ``idf_component_register`` in the component CMakeLists file.
.. only:: esp32p4
.. _cmake-llvm-optimizations:
LLVM Optimizations
^^^^^^^^^^^^^^^^^^
ESP-IDF can apply extra LLVM/Clang optimizations to selected sources. Enable the options in menuconfig. Mark a component or a file list in CMake. ESP-IDF sets the corresponding compiler flags, so projects do not write those flags by hand.
In :ref:`project-configuration-menu`, enable :menuitem:`CONFIG_COMPILER_LLVM_MEMCPY_OPTIMIZATION` under Compiler options > LLVM optimizations. Flags apply only to components or source files you select in CMake.
Apply to the whole component:
.. code-block:: cmake
idf_component_register(SRCS "foo.c" "bar.c"
INCLUDE_DIRS "."
ENABLE_LLVM_OPT)
Apply to one or more source files (call after ``idf_component_register``):
.. code-block:: cmake
idf_component_enable_llvm_opt(SRCS "foo.c" "bar.c")
Source paths must match the paths passed to ``idf_component_register``. As with ``set_source_files_properties``, source-level selection is not supported with sources discovered through ``SRC_DIRS``.
Third-party components such as LVGL do not call these helpers. After ``idf_component_register``, get the dependency's library target and apply the exported flags with standard CMake. ``IDF_LLVM_OPT_ALL`` holds the flags for every LLVM optimization enabled in menuconfig; ``IDF_LLVM_OPT_MEMCPY`` holds only the flags for :menuitem:`CONFIG_COMPILER_LLVM_MEMCPY_OPTIMIZATION`. Both are empty when those options are off or the compiler is not Clang:
Library target of the managed ``lvgl`` component (registry name :code:`lvgl__lvgl`), not its source list:
.. code-block:: cmake
idf_component_get_property(lvgl_lib "lvgl__lvgl" COMPONENT_LIB)
if(IDF_LLVM_OPT_ALL)
target_compile_options(${lvgl_lib} PRIVATE ${IDF_LLVM_OPT_ALL})
endif()
To apply only the memcpy optimization:
.. code-block:: cmake
idf_component_get_property(lvgl_lib "lvgl__lvgl" COMPONENT_LIB)
if(IDF_LLVM_OPT_MEMCPY)
target_compile_options(${lvgl_lib} PRIVATE ${IDF_LLVM_OPT_MEMCPY})
endif()
This does not patch the third-party CMakeLists. Do not apply it to every source in a large component; see the limitations below.
Advanced users can append extra Clang or LLVM flags. These are applied together with any LLVM optimizations enabled in menuconfig. Omit ``SRCS`` to apply them to the whole component:
.. code-block:: cmake
idf_component_enable_llvm_opt(
SRCS "foo.c"
OPTIONS "-mllvm=-my-custom-llvm-option")
The current menuconfig option speeds up ``memcpy`` using the RISC-V PIE extension. Install and select the Espressif Clang toolchain with ``IDF_TOOLCHAIN=clang``; IDF does not substitute flags when the active compiler is GCC. Further menuconfig options can be added later without changing the CMake enable API. See :example:`system/llvm_opt` and :example:`system/llvm_memcpy_opt`.
Limitations:
- Requires the Espressif Clang toolchain. ``ENABLE_LLVM_OPT``, ``idf_component_enable_llvm_opt``, ``IDF_LLVM_OPT_ALL``, and ``IDF_LLVM_OPT_MEMCPY`` have no effect when the selected compiler is not Clang.
- Currently validated on ESP32-P4 only.
- Apply only to hot paths. Prefer a measured file list. Results depend on alignment, size, chip revision, and flash/cache layout.
- Do **not** enable this for the whole project or for every source in a large component. The generated code uses the PIE coprocessor. The first PIE instruction in a task that does not currently own PIE traps into the kernel, which lazy-saves the previous owner's registers and restores this task's; that switch repeats for every such task and can make the application slower overall. Extra code size (I-cache) can also hurt, but is secondary. See :doc:`../api-reference/system/freertos_idf`.
- Do not use this memcpy option from an ISR: PIE coprocessor use in interrupt context is not allowed and aborts.
- Do not treat the CMake markers as a global ``-O`` replacement.
.. _component-configuration:
@@ -1565,6 +1633,10 @@ The arguments for ``idf_component_register`` include:
- KCONFIG_PROJBUILD - override the default Kconfig.projbuild file
- WHOLE_ARCHIVE - if specified, the component library is surrounded by ``-Wl,--whole-archive``, ``-Wl,--no-whole-archive`` when linked. This has the same effect as setting ``WHOLE_ARCHIVE`` component property.
.. only:: esp32p4
On ESP32-P4, ``idf_component_register`` also accepts ``ENABLE_LLVM_OPT`` to apply LLVM optimizations enabled in menuconfig to all source files in the component. Ignored when the selected compiler is not Clang. See :ref:`cmake-llvm-optimizations`.
The following are used for :ref:`embedding data into the component <cmake_embed_data>`, and is considered as source files when determining if a component is config-only. This means that even if the component does not specify source files, a static library is still created internally for the component if it specifies either:
- EMBED_FILES - binary files to be embedded in the component