Skip to content

[CMAKE][llvm-libraries] Add Precompiled Headers option to improve build times #91755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1423,3 +1423,6 @@ endif()
if (LLVM_INCLUDE_UTILS AND LLVM_INCLUDE_TOOLS)
add_subdirectory(utils/llvm-locstats)
endif()

include(LLVMPrecompiledHeaders)
llvm_lib_precompiled_headers()
11 changes: 10 additions & 1 deletion llvm/cmake/modules/HandleLLVMOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,11 @@ endif()

option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)

option(LLVM_ENABLE_LIB_PRECOMPILED_HEADERS "Enable precompiled headers for LLVM Lib projects to improve build times." OFF)

set(LLVM_LIB_DIRETORIES_FOR_PRECOMPILED_HEADERS ""
CACHE STRING "Semicolon-separated list of llvm/lib/ subdirectories to use precompiled headers")

if( MSVC )

# Add definitions that make MSVC much less annoying.
Expand Down Expand Up @@ -593,7 +598,11 @@ if( MSVC )
# PDBs without changing codegen.
option(LLVM_ENABLE_PDB OFF)
if (LLVM_ENABLE_PDB AND uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
append("/Zi" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
if (LLVM_ENABLE_LIB_PRECOMPILED_HEADERS)
append("/Z7" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
append("/Zi" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
# /DEBUG disables linker GC and ICF, but we want those in Release mode.
append("/DEBUG /OPT:REF /OPT:ICF"
CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS
Expand Down
88 changes: 88 additions & 0 deletions llvm/cmake/modules/LLVMPrecompiledHeaders.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
macro(get_all_targets_recursive targets dir)
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
foreach(subdir ${subdirectories})
get_all_targets_recursive(${targets} ${subdir})
endforeach()

get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
list(APPEND ${targets} ${current_targets})
endmacro()

function(get_all_targets dir outvar)
set(targets)
get_all_targets_recursive(targets ${dir})
set(${outvar} ${targets} PARENT_SCOPE)
endfunction()

function(add_llvm_lib_precompiled_headers target)
get_target_property(target_type ${target} TYPE)
if (target_type STREQUAL "STATIC_LIBRARY")
target_precompile_headers(${target} REUSE_FROM LLVMPchTarget)
endif()
endfunction()

function(add_llvm_subdir_pch subdir)
set(subdir_path "${LLVM_MAIN_SRC_DIR}/lib/${subdir}")
if (NOT EXISTS ${subdir_path})
message(WARNING "Directory does not exist. Skipping Precompiled Headers for ${subdir_path}")
return()
endif()

message(STATUS "Enabling Precompiled Headers for ${subdir_path}")
get_all_targets(${subdir_path} lib_targets)
foreach(target ${lib_targets})
add_llvm_lib_precompiled_headers(${target})
endforeach()
endfunction()

function(llvm_lib_precompiled_headers)
# target_precompile_headers was introduced in 3.16
if(${CMAKE_VERSION} VERSION_LESS "3.16")
message(STATUS "LLVM Lib Precompiled Headers requires CMake version 3.16")
set(LLVM_ENABLE_LIB_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
endif()

if (LLVM_ENABLE_LIB_PRECOMPILED_HEADERS)
message(STATUS "LLVM Lib Precompiled Headers are enabled")
# Create a dummy source file to compile the PCH target.
set(pch_dummy_cpp ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp)
if (NOT EXISTS ${pch_dummy_cpp})
FILE(TOUCH ${pch_dummy_cpp})
endif()

set(precompiled_header_path ${LLVM_MAIN_INCLUDE_DIR}/llvm/PrecompiledHeaders.h)

add_llvm_component_library(
LLVMPchTarget
${pch_dummy_cpp}
${precompiled_header_path}

# The PCH depends on Attributes.inc being generated
DEPENDS
intrinsics_gen
)
target_precompile_headers(LLVMPchTarget PUBLIC "$<$<COMPILE_LANGUAGE:CXX>:${LLVM_MAIN_INCLUDE_DIR}/llvm/PrecompiledHeaders.h>")

if (NOT LLVM_LIB_DIRETORIES_FOR_PRECOMPILED_HEADERS)
# LLVMSupport would be nice to have here, but causes a circular dependency with intrinsics_gen
set(default_lib_dirs_for_pch
"Analysis"
"CodeGen"
"DebugInfo"
"ExecutionEngine"
"IR"
"MC"
"MCA"
"ObjCopy"
"Object"
"Passes"
"Target"
"Transforms"
)
set(LLVM_LIB_DIRETORIES_FOR_PRECOMPILED_HEADERS ${default_lib_dirs_for_pch})
endif()
foreach(subdir ${LLVM_LIB_DIRETORIES_FOR_PRECOMPILED_HEADERS})
add_llvm_subdir_pch(${subdir})
endforeach()
endif()
endfunction()
1 change: 0 additions & 1 deletion llvm/include/llvm/ADT/ConcurrentHashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/xxhash.h"
#include <atomic>
#include <cstddef>
Expand Down
98 changes: 98 additions & 0 deletions llvm/include/llvm/PrecompiledHeaders.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//===-- llvm/PrecompiledHeaders.h - Precompiled Headers ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains common headers used within the LLVM library.
/// It is intended to be used as a precompiled header.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_PRECOMPILEDHEADERS_H
#define LLVM_PRECOMPILEDHEADERS_H

#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"

#include "llvm/ADT/ADL.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/EpochTracker.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringMapEntry.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/bit.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/ilist_node_base.h"
#include "llvm/ADT/ilist_node_options.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"

#include <algorithm>
#include <array>
#include <atomic>
#include <bitset>
#include <chrono>
#include <deque>
#include <functional>
#include <future>
#include <initializer_list>
#include <iomanip>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <new>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <cinttypes>
#include <climits>
#include <clocale>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>

#endif // LLVM_PRECOMPILEDHEADERS_H
2 changes: 1 addition & 1 deletion llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, uint64_t *OffsetPtr) {

// Read all of the abbreviation attributes and forms.
while (Data.isValidOffset(*OffsetPtr)) {
auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr, &Err));
auto A = static_cast<dwarf::Attribute>(Data.getULEB128(OffsetPtr, &Err));
if (Err)
return std::move(Err);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Object/Minidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Expected<ArrayRef<T>> MinidumpFile::getListStream(StreamType Type) const {

return getDataSliceAs<T>(*Stream, ListOffset, ListSize);
}
template Expected<ArrayRef<Module>>
template Expected<ArrayRef<minidump::Module>>
MinidumpFile::getListStream(StreamType) const;
template Expected<ArrayRef<Thread>>
MinidumpFile::getListStream(StreamType) const;
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,21 @@ add_llvm_component_library(LLVMSupport

set(llvm_system_libs ${system_libs})

if (LLVM_ENABLE_LIB_PRECOMPILED_HEADERS)
# CMake cannot use a C++ PCH in source targets that are non-C++
# Ideally this would be handled by LLVMPrecompiledHeaders.cmake
set(non_cpp_sources
regcomp.c
regerror.c
regexec.c
regfree.c
regstrlcpy.c
)
foreach(source ${non_cpp_sources})
set_source_files_properties(${source} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
endforeach()
endif()

# This block is only needed for llvm-config. When we deprecate llvm-config and
# move to using CMake export, this block can be removed.
if(LLVM_ENABLE_ZLIB)
Expand Down
Loading