llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Alexis Engelke (aengelke)

<details>
<summary>Changes</summary>

This patch implements PCH support.

* Libraries can defined precompiled headers using a newly added 
PRECOMPILE_HEADERS keyword. If specified, the listed headers will be compiled 
into a pre-compiled header using standard CMake mechanisms.

* Libraries that don't define their own PRECOMPILE_HEADERS but directly depend 
on a library or component that defines its own PCH will reuse that PCH. This 
reuse is not transitive to prevent excessive use of unrelated headers. If 
multiple dependencies provide a reusable PCH, the first one with the longest 
dependency chain (stored in the CMake target property LLVM_PCH_PRIORITY) is 
used. However, due to CMake limitations, only PCH from targets that are already 
defined can be reused; therefore libraries that should reuse a PCH must be 
defined later in the CMake file (=&gt; add_subdirectory order matters).

* Libraries and executables can prevent PCH reuse with the keyword 
DISABLE_PCH_REUSE. This both prevents reuse from dependencies and reuse by 
other dependants. This is useful when, e.g., internal headers are used in the 
PCH or the used headers are unlikely to provide benefits for dependants.

* Precompiled headers are only used for C++ targets. Due to CMake-weirdness, 
C-only targets must explicitly disable PCH reuse, otherwise configuration fails.

* With GCC, PCH provide very little benefits (tested with GCC 14 and 15) due to 
increased template instatiation costs, but substantially increase max-rss and 
build directory size. Therefore, disable PCH with GCC by default; this can be 
explicitly overridden on the command line with 
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF.

* With ccache and non-Clang compilers, changes in macro definitions are not 
always accurately forwarded with ccache's preprocessed mode. To be on the safe 
side, when ccache is enabled, disable PCH with all non-Clang compilers; this 
can be explicitly overridden.

* Add a base PCH to LLVMSupport, which includes widely used standard library 
and Support+ADT headers. The pch.h is placed in include so that later PCH 
headers can extend that list of headers.

* Flang PCH use is ported to the general mechanism.

Addition of PCH headers for other components (e.g., IR, CodeGen) will be posted 
as separate PRs.

RFC: 
https://discourse.llvm.org/t/rfc-use-pre-compiled-headers-to-speed-up-llvm-build-by-1-5-2x/89345

---

Patch is 25.98 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/176420.diff


25 Files Affected:

- (modified) clang/tools/c-index-test/CMakeLists.txt (+2) 
- (modified) clang/tools/clang-fuzzer/dictionary/CMakeLists.txt (+2) 
- (modified) flang/CMakeLists.txt (-10) 
- (modified) flang/lib/Evaluate/CMakeLists.txt (+9-9) 
- (modified) flang/lib/Frontend/CMakeLists.txt (+8-8) 
- (modified) flang/lib/Lower/CMakeLists.txt (+11-11) 
- (modified) flang/lib/Parser/CMakeLists.txt (+8-8) 
- (modified) flang/lib/Semantics/CMakeLists.txt (+9-9) 
- (modified) llvm/CMakeLists.txt (+16) 
- (modified) llvm/cmake/modules/AddLLVM.cmake (+69-8) 
- (modified) llvm/cmake/modules/HandleLLVMOptions.cmake (+21) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt (+2) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt (+2) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt (+2) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt (+2) 
- (modified) llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt (+2) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt 
(+2) 
- (modified) 
llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt (+2) 
- (modified) llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt 
(+2) 
- (added) llvm/include/llvm/Support/pch.h (+75) 
- (modified) llvm/lib/CMakeLists.txt (+1-1) 
- (modified) llvm/lib/Support/CMakeLists.txt (+6-1) 
- (modified) llvm/tools/llvm-c-test/CMakeLists.txt (+2) 
- (modified) llvm/utils/count/CMakeLists.txt (+2) 
- (modified) mlir/test/CAPI/CMakeLists.txt (+1) 


``````````diff
diff --git a/clang/tools/c-index-test/CMakeLists.txt 
b/clang/tools/c-index-test/CMakeLists.txt
index 41e80e66ffa7a..2bbd387d6e812 100644
--- a/clang/tools/c-index-test/CMakeLists.txt
+++ b/clang/tools/c-index-test/CMakeLists.txt
@@ -5,6 +5,8 @@ set(LLVM_LINK_COMPONENTS
 add_clang_executable(c-index-test
   c-index-test.c
   core_main.cpp
+
+  DISABLE_PCH_REUSE # Prevent CMake error with C source files.
   )
 
 if(NOT MSVC)
diff --git a/clang/tools/clang-fuzzer/dictionary/CMakeLists.txt 
b/clang/tools/clang-fuzzer/dictionary/CMakeLists.txt
index 6b72b98f5e1c4..a7f18965b4e29 100644
--- a/clang/tools/clang-fuzzer/dictionary/CMakeLists.txt
+++ b/clang/tools/clang-fuzzer/dictionary/CMakeLists.txt
@@ -1,5 +1,7 @@
 set(CMAKE_CXX_FLAGS ${CXX_FLAGS_NOFUZZ})
 add_clang_executable(clang-fuzzer-dictionary
   dictionary.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
 
diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
index c01eb56d5e496..e21304d2e4da7 100644
--- a/flang/CMakeLists.txt
+++ b/flang/CMakeLists.txt
@@ -441,11 +441,6 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
   if (BUILD_SHARED_LIBS AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} 
-fno-semantic-interposition")
   endif()
-
-  # GCC requires this flag in order for precompiled headers to work with ccache
-  if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT 
CMAKE_DISABLE_PRECOMPILE_HEADERS)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpch-preprocess")
-  endif()
 endif()
 
 # Clang on Darwin enables non-POSIX extensions by default, which allows the
@@ -456,11 +451,6 @@ if (APPLE)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_POSIX_C_SOURCE=200809")
 endif()
 
-# Clang requires this flag in order for precompiled headers to work with ccache
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT 
CMAKE_DISABLE_PRECOMPILE_HEADERS)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -fno-pch-timestamp")
-endif()
-
 list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS)
 
 # Determine HOST_LINK_VERSION on Darwin.
diff --git a/flang/lib/Evaluate/CMakeLists.txt 
b/flang/lib/Evaluate/CMakeLists.txt
index 24a1c9004bc3b..472ecb6d8d079 100644
--- a/flang/lib/Evaluate/CMakeLists.txt
+++ b/flang/lib/Evaluate/CMakeLists.txt
@@ -66,15 +66,8 @@ add_flang_library(FortranEvaluate
   ${LIBPGMATH}
   ${QUADMATHLIB}
 
-  LINK_COMPONENTS
-  Support
-
-  DEPENDS
-  acc_gen
-  omp_gen
-)
-
-target_precompile_headers(FortranEvaluate PRIVATE
+  DISABLE_PCH_REUSE
+  PRECOMPILE_HEADERS
   [["flang/Evaluate/common.h"]]
   [["flang/Evaluate/call.h"]]
   [["flang/Evaluate/traverse.h"]]
@@ -86,4 +79,11 @@ target_precompile_headers(FortranEvaluate PRIVATE
   [["flang/Evaluate/integer.h"]]
   [["flang/Evaluate/expression.h"]]
   [["flang/Evaluate/tools.h"]]
+
+  LINK_COMPONENTS
+  Support
+
+  DEPENDS
+  acc_gen
+  omp_gen
 )
diff --git a/flang/lib/Frontend/CMakeLists.txt 
b/flang/lib/Frontend/CMakeLists.txt
index 4ebe497e65676..bd67ec444f358 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -13,6 +13,14 @@ add_flang_library(flangFrontend
   TextDiagnosticBuffer.cpp
   TextDiagnostic.cpp
 
+  DISABLE_PCH_REUSE
+  PRECOMPILE_HEADERS
+  [["flang/Parser/parsing.h"]]
+  [["flang/Parser/parse-tree.h"]]
+  [["flang/Parser/dump-parse-tree.h"]]
+  [["flang/Lower/PFTBuilder.h"]]
+  [["flang/Lower/Bridge.h"]]
+
   DEPENDS
   CUFDialect
   FIRDialect
@@ -78,11 +86,3 @@ add_flang_library(flangFrontend
   clangBasic
   clangOptions
 )
-
-target_precompile_headers(flangFrontend PRIVATE
-  [["flang/Parser/parsing.h"]]
-  [["flang/Parser/parse-tree.h"]]
-  [["flang/Parser/dump-parse-tree.h"]]
-  [["flang/Lower/PFTBuilder.h"]]
-  [["flang/Lower/Bridge.h"]]
-)
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index 230a56ab66ec5..f5424c78b9a98 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -38,6 +38,17 @@ add_flang_library(FortranLower
   Support/Utils.cpp
   SymbolMap.cpp
   VectorSubscripts.cpp
+
+  DISABLE_PCH_REUSE
+  PRECOMPILE_HEADERS
+  [["flang/Lower/ConvertExpr.h"]]
+  [["flang/Lower/SymbolMap.h"]]
+  [["flang/Lower/AbstractConverter.h"]]
+  [["flang/Lower/IterationSpace.h"]]
+  [["flang/Lower/CallInterface.h"]]
+  [["flang/Lower/BoxAnalyzer.h"]]
+  [["flang/Lower/PFTBuilder.h"]]
+  [["flang/Lower/DirectivesCommon.h"]]
   
   DEPENDS
   CUFAttrs
@@ -79,14 +90,3 @@ add_flang_library(FortranLower
   MLIRLLVMDialect
   MLIRSCFToControlFlow
 )
-
-target_precompile_headers(FortranLower PRIVATE
-  [["flang/Lower/ConvertExpr.h"]]
-  [["flang/Lower/SymbolMap.h"]]
-  [["flang/Lower/AbstractConverter.h"]]
-  [["flang/Lower/IterationSpace.h"]]
-  [["flang/Lower/CallInterface.h"]]
-  [["flang/Lower/BoxAnalyzer.h"]]
-  [["flang/Lower/PFTBuilder.h"]]
-  [["flang/Lower/DirectivesCommon.h"]]
-)
diff --git a/flang/lib/Parser/CMakeLists.txt b/flang/lib/Parser/CMakeLists.txt
index 20c6c2a7c8f80..e0479b0da3eb8 100644
--- a/flang/lib/Parser/CMakeLists.txt
+++ b/flang/lib/Parser/CMakeLists.txt
@@ -25,6 +25,14 @@ add_flang_library(FortranParser
   unparse.cpp
   user-state.cpp
 
+  DISABLE_PCH_REUSE
+  PRECOMPILE_HEADERS
+  [["flang/Parser/parsing.h"]]
+  [["flang/Parser/parse-tree.h"]]
+  [["flang/Parser/provenance.h"]]
+  [["flang/Parser/message.h"]]
+  [["flang/Parser/parse-tree-visitor.h"]]
+
   LINK_LIBS
   FortranSupport
 
@@ -37,11 +45,3 @@ add_flang_library(FortranParser
   omp_gen
   acc_gen
 )
-
-target_precompile_headers(FortranParser PRIVATE
-  [["flang/Parser/parsing.h"]]
-  [["flang/Parser/parse-tree.h"]]
-  [["flang/Parser/provenance.h"]]
-  [["flang/Parser/message.h"]]
-  [["flang/Parser/parse-tree-visitor.h"]]
-)
diff --git a/flang/lib/Semantics/CMakeLists.txt 
b/flang/lib/Semantics/CMakeLists.txt
index 109bc2dbb8569..44e6dfb4dd09f 100644
--- a/flang/lib/Semantics/CMakeLists.txt
+++ b/flang/lib/Semantics/CMakeLists.txt
@@ -53,6 +53,15 @@ add_flang_library(FortranSemantics
   type.cpp
   unparse-with-symbols.cpp
 
+  DISABLE_PCH_REUSE
+  PRECOMPILE_HEADERS
+  [["flang/Semantics/semantics.h"]]
+  [["flang/Semantics/type.h"]]
+  [["flang/Semantics/openmp-modifiers.h"]]
+  [["flang/Semantics/expression.h"]]
+  [["flang/Semantics/tools.h"]]
+  [["flang/Semantics/symbol.h"]]
+
   DEPENDS
   acc_gen
   omp_gen
@@ -68,12 +77,3 @@ add_flang_library(FortranSemantics
   FrontendOpenACC
   TargetParser
 )
-
-target_precompile_headers(FortranSemantics PRIVATE
-  [["flang/Semantics/semantics.h"]]
-  [["flang/Semantics/type.h"]]
-  [["flang/Semantics/openmp-modifiers.h"]]
-  [["flang/Semantics/expression.h"]]
-  [["flang/Semantics/tools.h"]]
-  [["flang/Semantics/symbol.h"]]
-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 9954053591d30..a539a2182efa5 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -313,6 +313,22 @@ if(LLVM_CCACHE_BUILD)
         set(CCACHE_PROGRAM "CCACHE_DIR=${LLVM_CCACHE_DIR} ${CCACHE_PROGRAM}")
       endif()
       set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})
+
+      if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+        # ccache with PCH can lead to false-positives when only a macro
+        # definition changes with non-Clang compilers, because macro 
definitions
+        # are not compared in preprocessed mode.
+        # See: https://github.com/ccache/ccache/issues/1668
+        if(NOT DEFINED CMAKE_DISABLE_PRECOMPILE_HEADERS)
+          message(NOTICE "Using ccache with precompiled headers with non-Clang 
"
+            "compilers is not supported. CMAKE_DISABLE_PRECOMPILE_HEADERS will 
be set to ON. "
+            "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override this.")
+          set(CMAKE_DISABLE_PRECOMPILE_HEADERS "ON")
+        elseif(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
+          message(WARNING "Using ccache with precompiled headers with 
non-Clang "
+            "compilers is not supported.")
+        endif()
+      endif()
     else()
       # Until a way to reliably configure ccache on Windows is found,
       # disable precompiled headers for Windows + ccache builds
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index d938214f9d0df..c9ed03d98cc9c 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -79,6 +79,48 @@ function(llvm_update_compile_flags name)
   target_compile_definitions(${name} PRIVATE ${LLVM_COMPILE_DEFINITIONS})
 endfunction()
 
+function(llvm_update_pch name)
+  if(LLVM_REQUIRES_RTTI OR LLVM_REQUIRES_EH)
+    # Non-default RTTI/EH results in incompatible flags, precluding PCH reuse.
+    set(ARG_DISABLE_PCH_REUSE ON)
+  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
+  # a higher priority so that dependents will prefer the new PCH. We don't do
+  # transitive PCH reuse, because this causes too many unrelated naming
+  # collisions (e.g., in A -> B -> C{pch}, only B would reuse the PCH of C).
+  set(pch_priority 0)
+  llvm_map_components_to_libnames(libs
+    ${LLVM_LINK_COMPONENTS}
+  )
+  list(APPEND libs ${ARG_LINK_LIBS})
+  foreach(lib ${libs})
+    if(TARGET ${lib})
+      get_target_property(lib_pch_priority ${lib} LLVM_PCH_PRIORITY)
+      if(${lib_pch_priority} GREATER ${pch_priority})
+        set(pch_priority ${lib_pch_priority})
+        set(pch_reuse ${lib})
+      endif()
+    endif()
+  endforeach()
+
+  if(ARG_PRECOMPILE_HEADERS)
+    message(DEBUG "Adding PCH ${ARG_PRECOMPILE_HEADERS} for ${name} (prio 
${pch_priority})")
+    target_precompile_headers(${name} PRIVATE 
$<$<COMPILE_LANGUAGE:CXX>:${ARG_PRECOMPILE_HEADERS}>)
+    if(NOT ARG_DISABLE_PCH_REUSE)
+      # Set priority so that dependants can reuse the PCH.
+      math(EXPR pch_priority "${pch_priority} + 1")
+      set_target_properties(${name} PROPERTIES LLVM_PCH_PRIORITY 
${pch_priority})
+    endif()
+  elseif(pch_reuse AND NOT ARG_DISABLE_PCH_REUSE)
+    message(DEBUG "Using PCH ${pch_reuse} for ${name} (prio ${pch_priority})")
+    target_precompile_headers(${name} REUSE_FROM ${pch_reuse})
+  else()
+    message(DEBUG "Using NO PCH for ${name}")
+  endif()
+endfunction()
+
 function(add_llvm_symbol_exports target_name export_file)
   if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
     set(native_export_file "${target_name}.exports")
@@ -485,6 +527,13 @@ endfunction(set_windows_version_resource_properties)
 #     Corresponds to OUTPUT_NAME in target properties.
 #   DEPENDS targets...
 #     Same semantics as add_dependencies().
+#   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.
+#   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
+#     for reuse by dependants.
 #   LINK_COMPONENTS components...
 #     Same as the variable LLVM_LINK_COMPONENTS.
 #   LINK_LIBS lib_targets...
@@ -504,11 +553,12 @@ endfunction(set_windows_version_resource_properties)
 #   )
 function(llvm_add_library name)
   cmake_parse_arguments(ARG
-    
"MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
+    
"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;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
+    
"ADDITIONAL_HEADERS;PRECOMPILE_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
     ${ARGN})
   list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
+  list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
   if(ARG_ADDITIONAL_HEADERS)
     # Pass through ADDITIONAL_HEADERS.
     set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS})
@@ -550,6 +600,7 @@ function(llvm_add_library name)
       ${ALL_FILES}
       )
     llvm_update_compile_flags(${obj_name})
+    llvm_update_pch(${obj_name})
     if(CMAKE_GENERATOR STREQUAL "Xcode")
       set(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/Dummy.c)
       file(WRITE ${DUMMY_FILE} "// This file intentionally empty\n")
@@ -604,7 +655,7 @@ function(llvm_add_library name)
       ${output_name}
       OBJLIBS ${ALL_FILES} # objlib
       LINK_LIBS ${ARG_LINK_LIBS}
-      LINK_COMPONENTS ${ARG_LINK_COMPONENTS}
+      LINK_COMPONENTS ${LLVM_LINK_COMPONENTS}
       )
     set_target_properties(${name_static} PROPERTIES FOLDER 
"${subproject_title}/Libraries")
 
@@ -676,6 +727,11 @@ function(llvm_add_library name)
   # $<TARGET_OBJECTS> doesn't require compile flags.
   if(NOT obj_name)
     llvm_update_compile_flags(${name})
+    llvm_update_pch(${name})
+  else()
+    target_precompile_headers(${name} REUSE_FROM ${obj_name})
+    get_target_property(pch_priority ${obj_name} LLVM_PCH_PRIORITY)
+    set_target_properties(${name} PROPERTIES LLVM_PCH_PRIORITY ${pch_priority})
   endif()
   add_link_opts( ${name} )
   if(ARG_OUTPUT_NAME)
@@ -758,8 +814,7 @@ function(llvm_add_library name)
         target_compile_definitions(${name} PRIVATE LLVM_BUILD_STATIC)
       endif()
       llvm_map_components_to_libnames(llvm_libs
-       ${ARG_LINK_COMPONENTS}
-       ${LLVM_LINK_COMPONENTS}
+        ${LLVM_LINK_COMPONENTS}
        )
     endif()
   else()
@@ -770,7 +825,7 @@ function(llvm_add_library name)
     # It would be nice to verify that we have the dependencies for this library
     # name, but using get_property(... SET) doesn't suffice to determine if a
     # property has been set to an empty value.
-    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS 
${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})
+    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS 
${LLVM_LINK_COMPONENTS})
 
     # This property is an internal property only used to make sure the
     # link step applied in LLVMBuildResolveComponentsLink uses the same
@@ -993,6 +1048,7 @@ macro(generate_llvm_objects name)
       ${ALL_FILES}
       )
     llvm_update_compile_flags(${obj_name})
+    llvm_update_pch(${obj_name})
     set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>")
     if(ARG_DEPENDS)
       add_dependencies(${obj_name} ${ARG_DEPENDS})
@@ -1032,7 +1088,7 @@ endmacro()
 
 macro(add_llvm_executable name)
   cmake_parse_arguments(ARG
-    
"DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;EXPORT_SYMBOLS"
+    
"DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;EXPORT_SYMBOLS;DISABLE_PCH_REUSE"
     "ENTITLEMENTS;BUNDLE_PATH"
     ""
     ${ARGN})
@@ -1073,6 +1129,11 @@ macro(add_llvm_executable name)
   # $<TARGET_OBJECTS> doesn't require compile flags.
   if(NOT LLVM_ENABLE_OBJLIB)
     llvm_update_compile_flags(${name})
+    llvm_update_pch(${name})
+  else()
+    target_precompile_headers(${name} REUSE_FROM ${obj_name})
+    get_target_property(pch_priority ${obj_name} LLVM_PCH_PRIORITY)
+    set_target_properties(${name} PROPERTIES LLVM_PCH_PRIORITY ${pch_priority})
   endif()
 
   if (ARG_SUPPORT_PLUGINS AND NOT "${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
@@ -1780,7 +1841,7 @@ function(add_unittest test_suite test_name)
   endif()
 
   list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream
-  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO 
NO_INSTALL_RPATH ${ARGN})
+  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO 
NO_INSTALL_RPATH DISABLE_PCH_REUSE ${ARGN})
   get_subproject_title(subproject_title)
   set_target_properties(${test_name} PROPERTIES FOLDER 
"${subproject_title}/Tests/Unit")
 
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake 
b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 311123084bf58..2e90c0ad0ad76 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -1304,6 +1304,27 @@ if (LLVM_BUILD_INSTRUMENTED AND 
LLVM_BUILD_INSTRUMENTED_COVERAGE)
   message(FATAL_ERROR "LLVM_BUILD_INSTRUMENTED and 
LLVM_BUILD_INSTRUMENTED_COVERAGE cannot both be specified")
 endif()
 
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT DEFINED 
CMAKE_DISABLE_PRECOMPILE_HEADERS)
+  # Pre-compiled headers with GCC (tested versions 14+15) provide very little
+  # compile-time improvements, but substantially increase the build dir size.
+  # Therefore, disable PCH with GCC by default.
+  message(NOTICE "Precompiled headers are disabled by default with GCC. "
+    "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+  set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+endif()
+if(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
+  message(STATUS "Precompiled headers enabled.")
+  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    # Clang requires this flag in order for precompiled headers to work with 
ccache
+    append("-Xclang -fno-pch-timestamp" CMAKE_CXX_FLAGS)
+  elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+    # GCC requires this flag in order for precompiled headers to work with 
ccache
+    append("-fpch-preprocess" CMAKE_CXX_FLAGS)
+  endif()
+else()
+  message(STATUS "Precompiled headers disabled.")
+endif()
+
 set(LLVM_THINLTO_CACHE_PATH "${PROJECT_BINARY_DIR}/lto.cache" CACHE STRING 
"Set ThinLTO cache path. This can be used when building LLVM from several 
different directiories.")
 
 if(LLVM_ENABLE_LTO AND WIN32 AND NOT LINKER_IS_LLD_LINK AND NOT MINGW)
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
index cc50112f326ea..9a82cc0ed0916 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsAddObjectFile
   OrcV2CBindingsAddObjectFile.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
index 0f18d6c24912f..1a738f60d15e1 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsBasicUsage
   OrcV2CBindingsBasicUsage.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
index 8e2c97d782062..c7f748a12bf35 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsDumpObjects
   OrcV2CBindingsDumpObjects.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
index af1b43e43e111..b152faf1e3527 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
@@ -13,4 +13,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsIRTransforms
   OrcV2CBindingsIRTransforms.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
index 52eb2d496fc23..c46700d9b2576 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsLazy
   OrcV2CBindingsLazy.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
index 4cdc2b114e9a5..d4a06104120c8 100644
--- 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
+++ 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_exampl...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/176420
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to