[llvm-branch-commits] [llvm] [mlir] [mlir] Reuse the MLIRIR PCH through dependencies (NFC) (PR #222581)

Mehdi Amini via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Sep 10 03:06:35 PDT 2026


https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/222581

Track whether an MLIR library's link closure reaches MLIRIR and reuse the MLIRIR PCH for those libraries. Preserve higher-priority local PCHs and add an explicit opt-out for targets whose sources are incompatible with reuse.

Relative to the core and LLVM dialect PCH parent, clean Release builds of LLVM and MLIR with `ninja -j16` improved as follows:

```
  wall:   398.79s -> 386.47s (-3.09%)
  user:  5789.14s -> 5624.02s (-2.85%)
  system: 455.05s -> 438.45s (-3.65%)
```

Assisted-by: Codex

>From a53bc4fa61c0ee92f4fd378f7ec9295e05f9ee85 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Wed, 9 Sep 2026 04:47:28 -0700
Subject: [PATCH] [mlir] Reuse the MLIRIR PCH through dependencies (NFC)

Track whether an MLIR library's link closure reaches MLIRIR and reuse the
MLIRIR PCH for those libraries. Preserve higher-priority local PCHs and add an
explicit opt-out for targets whose sources are incompatible with reuse.

Relative to the core and LLVM dialect PCH parent, clean Release builds of LLVM
and MLIR with Ninja -j16 pinned to CPUs 16-31 improved as follows:

  wall:   398.79s -> 386.47s (-3.09%)
  user:  5789.14s -> 5624.02s (-2.85%)
  system: 455.05s -> 438.45s (-3.65%)

Assisted-by: Codex
---
 llvm/cmake/modules/AddLLVM.cmake         |  9 +++-
 mlir/cmake/modules/AddMLIR.cmake         | 61 +++++++++++++++++++++++-
 mlir/test/lib/CMake/CMakeLists.txt       | 38 +++++++++++++++
 mlir/test/lib/CMake/Inputs/PCHOptOut.c   |  1 +
 mlir/test/lib/CMake/Inputs/PCHOptOut.cpp |  1 +
 mlir/test/lib/CMakeLists.txt             |  1 +
 6 files changed, 109 insertions(+), 2 deletions(-)
 create mode 100644 mlir/test/lib/CMake/CMakeLists.txt
 create mode 100644 mlir/test/lib/CMake/Inputs/PCHOptOut.c
 create mode 100644 mlir/test/lib/CMake/Inputs/PCHOptOut.cpp

diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index 3169756c0f28a..e4a93ef976165 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -106,6 +106,9 @@ function(llvm_update_pch name)
     # Disable for Objective-C as well to avoid errors due to mixed languages.
     set(ARG_DISABLE_PCH_REUSE ON)
   endif()
+  if(ARG_DISABLE_PCH_REUSE)
+    set_target_properties(${name} PROPERTIES LLVM_DISABLE_PCH_REUSE TRUE)
+  endif()
 
   # Find PCH with highest priority from dependencies. We reuse the first PCH
   # with the highest priority. If the target has its own set of PCH, we give it
@@ -117,6 +120,7 @@ function(llvm_update_pch name)
     ${LLVM_LINK_COMPONENTS}
   )
   list(APPEND libs ${ARG_LINK_LIBS})
+  list(APPEND libs ${ARG_PCH_REUSE_FROM})
   foreach(lib ${libs})
     if(TARGET ${lib})
       get_target_property(lib_pch_priority ${lib} LLVM_PCH_PRIORITY)
@@ -573,6 +577,9 @@ endfunction(set_windows_version_resource_properties)
 #   PRECOMPILE_HEADERS include_directives...
 #     Pre-compiled C++ headers to use. PCH can be reused by dependants. If
 #     specified, no PCHs from dependencies will be reused.
+#   PCH_REUSE_FROM targets...
+#     Additional targets whose PCH may be reused without adding a link
+#     dependency.
 #   DISABLE_PCH_REUSE
 #     Disable reuse of pre-compiled headers in both directions: the library will
 #     not reuse the PCH of a dependency and a defined PCH will not be offered
@@ -598,7 +605,7 @@ function(llvm_add_library name)
   cmake_parse_arguments(ARG
     "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB;DISABLE_PCH_REUSE"
     "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
-    "ADDITIONAL_HEADERS;PRECOMPILE_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
+    "ADDITIONAL_HEADERS;PRECOMPILE_HEADERS;PCH_REUSE_FROM;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
     ${ARGN})
   list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
   list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake
index d3f534a02f9de..cffdd00c16169 100644
--- a/mlir/cmake/modules/AddMLIR.cmake
+++ b/mlir/cmake/modules/AddMLIR.cmake
@@ -305,6 +305,22 @@ function(add_mlir_example_library name)
   endif()
 endfunction()
 
+function(_mlir_link_libraries_reach_mlirir out_var)
+  set(reaches_mlirir OFF)
+  foreach(lib ${ARGN})
+    if(lib STREQUAL MLIRIR)
+      set(reaches_mlirir ON)
+    elseif(TARGET ${lib})
+      get_target_property(lib_reaches_mlirir
+        ${lib} MLIR_MLIRIR_LINK_CLOSURE)
+      if(lib_reaches_mlirir)
+        set(reaches_mlirir ON)
+      endif()
+    endif()
+  endforeach()
+  set(${out_var} ${reaches_mlirir} PARENT_SCOPE)
+endfunction()
+
 # Declare an mlir library which can be compiled in libMLIR.so
 # In addition to everything that llvm_add_library accepts, this
 # also has the following option:
@@ -387,9 +403,22 @@ function(add_mlir_library name)
   _check_llvm_components_usage(${name} ${ARG_LINK_LIBS})
 
   list(APPEND ARG_DEPENDS mlir-generic-headers)
-  llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS})
+  _mlir_link_libraries_reach_mlirir(MLIRIR_LINK_CLOSURE ${ARG_LINK_LIBS})
+  set(PCH_REUSE_ARGS)
+  if(TARGET MLIRIR AND MLIRIR_LINK_CLOSURE AND NOT ARG_STANDALONE)
+    set(PCH_REUSE_ARGS PCH_REUSE_FROM MLIRIR)
+  endif()
+  llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs}
+    ${PCH_REUSE_ARGS}
+    DEPENDS ${ARG_DEPENDS}
+    LINK_COMPONENTS ${ARG_LINK_COMPONENTS}
+    LINK_LIBS ${ARG_LINK_LIBS})
 
   if(TARGET ${name})
+    if(name STREQUAL MLIRIR OR MLIRIR_LINK_CLOSURE)
+      set_target_properties(${name} PROPERTIES
+        MLIR_MLIRIR_LINK_CLOSURE TRUE)
+    endif()
     target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS})
     if(ARG_INSTALL_WITH_TOOLCHAIN)
       set_target_properties(${name} PROPERTIES MLIR_INSTALL_WITH_TOOLCHAIN TRUE)
@@ -746,8 +775,38 @@ endfunction(mlir_check_all_link_libraries)
 # part of the dylib (like test libraries), target_link_libraries() should be
 # used.
 function(mlir_target_link_libraries target type)
+  set(pch_compile_target ${target})
   if (TARGET obj.${target})
     target_link_libraries(obj.${target} ${type} ${ARGN})
+    set(pch_compile_target obj.${target})
+  endif()
+
+  _mlir_link_libraries_reach_mlirir(mlirir_link_closure ${ARGN})
+
+  if(TARGET MLIRIR AND mlirir_link_closure)
+    get_target_property(current_disable_all_pch ${pch_compile_target}
+      DISABLE_PRECOMPILE_HEADERS)
+    get_target_property(current_disable_pch_reuse ${pch_compile_target}
+      LLVM_DISABLE_PCH_REUSE)
+    get_target_property(current_pch_headers ${pch_compile_target}
+      PRECOMPILE_HEADERS)
+    get_target_property(current_pch_reuse ${pch_compile_target}
+      PRECOMPILE_HEADERS_REUSE_FROM)
+    set(current_pch_priority 0)
+    if(TARGET ${current_pch_reuse})
+      get_target_property(current_pch_priority ${current_pch_reuse}
+        LLVM_PCH_PRIORITY)
+    endif()
+    get_target_property(mlirir_pch_priority MLIRIR LLVM_PCH_PRIORITY)
+    if(NOT current_disable_all_pch AND NOT current_disable_pch_reuse AND
+        NOT current_pch_headers AND
+        mlirir_pch_priority GREATER current_pch_priority)
+      set_target_properties(${pch_compile_target} PROPERTIES
+        PRECOMPILE_HEADERS_REUSE_FROM MLIRIR)
+      add_dependencies(${pch_compile_target} MLIRIR)
+    endif()
+    set_target_properties(${target} PROPERTIES
+      MLIR_MLIRIR_LINK_CLOSURE TRUE)
   endif()
 
   if (MLIR_LINK_MLIR_DYLIB)
diff --git a/mlir/test/lib/CMake/CMakeLists.txt b/mlir/test/lib/CMake/CMakeLists.txt
new file mode 100644
index 0000000000000..8332bd6693231
--- /dev/null
+++ b/mlir/test/lib/CMake/CMakeLists.txt
@@ -0,0 +1,38 @@
+function(_mlir_assert_no_pch_reuse target)
+  get_target_property(pch_reuse ${target} PRECOMPILE_HEADERS_REUSE_FROM)
+  if(pch_reuse)
+    message(FATAL_ERROR
+      "${target} unexpectedly reuses the PCH from ${pch_reuse}")
+  endif()
+endfunction()
+
+# Verify that a dependency added after target creation cannot override an
+# explicit PCH-reuse opt-out.
+add_mlir_library(MLIRTestPCHExplicitOptOut
+  Inputs/PCHOptOut.cpp
+
+  PARTIAL_SOURCES_INTENDED
+  EXCLUDE_FROM_LIBMLIR
+  DISABLE_INSTALL
+  DISABLE_PCH_REUSE
+  )
+set_target_properties(MLIRTestPCHExplicitOptOut PROPERTIES
+  EXCLUDE_FROM_ALL TRUE)
+mlir_target_link_libraries(MLIRTestPCHExplicitOptOut PRIVATE MLIRIR)
+_mlir_assert_no_pch_reuse(MLIRTestPCHExplicitOptOut)
+
+# Mixed C and C++ targets cannot reuse a C++ PCH. Exercise the object-library
+# path because the delayed-link helper applies PCH properties to that target.
+add_mlir_library(MLIRTestPCHMixedLanguageOptOut
+  Inputs/PCHOptOut.c
+  Inputs/PCHOptOut.cpp
+
+  PARTIAL_SOURCES_INTENDED
+  OBJECT
+  EXCLUDE_FROM_LIBMLIR
+  DISABLE_INSTALL
+  )
+set_target_properties(MLIRTestPCHMixedLanguageOptOut PROPERTIES
+  EXCLUDE_FROM_ALL TRUE)
+mlir_target_link_libraries(MLIRTestPCHMixedLanguageOptOut PRIVATE MLIRIR)
+_mlir_assert_no_pch_reuse(obj.MLIRTestPCHMixedLanguageOptOut)
diff --git a/mlir/test/lib/CMake/Inputs/PCHOptOut.c b/mlir/test/lib/CMake/Inputs/PCHOptOut.c
new file mode 100644
index 0000000000000..f262bf36acc91
--- /dev/null
+++ b/mlir/test/lib/CMake/Inputs/PCHOptOut.c
@@ -0,0 +1 @@
+void mlirTestPCHOptOutC(void) {}
diff --git a/mlir/test/lib/CMake/Inputs/PCHOptOut.cpp b/mlir/test/lib/CMake/Inputs/PCHOptOut.cpp
new file mode 100644
index 0000000000000..9ef3c48f131cc
--- /dev/null
+++ b/mlir/test/lib/CMake/Inputs/PCHOptOut.cpp
@@ -0,0 +1 @@
+void mlirTestPCHOptOutCxx() {}
diff --git a/mlir/test/lib/CMakeLists.txt b/mlir/test/lib/CMakeLists.txt
index 88e55e77a3fb9..6c03b79c5beb0 100644
--- a/mlir/test/lib/CMakeLists.txt
+++ b/mlir/test/lib/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(Analysis)
+add_subdirectory(CMake)
 add_subdirectory(Conversion)
 add_subdirectory(Dialect)
 add_subdirectory(Interfaces)



More information about the llvm-branch-commits mailing list