[clang] [flang] [lld] [llvm] [mlir] [RFC] Use pre-compiled headers to speed up LLVM build (~1.5-2x) (PR #173868)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 8 12:02:02 PST 2026
https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/173868
>From 684214fc7faf2af988577533563bf4370730ce71 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Tue, 30 Dec 2025 10:15:51 +0000
Subject: [PATCH 01/12] [LLD][MachO] Avoid ambiguity between lld::Reloc and
llvm::Reloc
---
lld/MachO/EhFrame.cpp | 15 +++++------
lld/MachO/ICF.cpp | 18 ++++++-------
lld/MachO/InputSection.cpp | 15 +++++------
lld/MachO/ObjC.cpp | 46 +++++++++++++++++----------------
lld/MachO/Relocations.cpp | 1 -
lld/MachO/UnwindInfoSection.cpp | 19 +++++++-------
6 files changed, 56 insertions(+), 58 deletions(-)
diff --git a/lld/MachO/EhFrame.cpp b/lld/MachO/EhFrame.cpp
index 2446b49b5098a..e6b473475c1fe 100644
--- a/lld/MachO/EhFrame.cpp
+++ b/lld/MachO/EhFrame.cpp
@@ -13,7 +13,6 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Endian.h"
-using namespace llvm;
using namespace lld;
using namespace lld::macho;
using namespace llvm::support::endian;
@@ -24,7 +23,7 @@ uint64_t EhReader::readLength(size_t *off) const {
failOn(errOff, "CIE/FDE too small");
uint64_t len = read32le(data.data() + *off);
*off += 4;
- if (len == dwarf::DW_LENGTH_DWARF64) {
+ if (len == llvm::dwarf::DW_LENGTH_DWARF64) {
// FIXME: test this DWARF64 code path
if (*off + 8 > data.size())
failOn(errOff, "CIE/FDE too small");
@@ -39,7 +38,7 @@ uint64_t EhReader::readLength(size_t *off) const {
void EhReader::skipValidLength(size_t *off) const {
uint32_t len = read32le(data.data() + *off);
*off += 4;
- if (len == dwarf::DW_LENGTH_DWARF64)
+ if (len == llvm::dwarf::DW_LENGTH_DWARF64)
*off += 8;
}
@@ -106,10 +105,10 @@ void EhReader::failOn(size_t errOff, const Twine &msg) const {
* `(a + offset) - b` if Invert == true
*/
template <bool Invert = false>
-static void createSubtraction(PointerUnion<Symbol *, InputSection *> a,
- PointerUnion<Symbol *, InputSection *> b,
+static void createSubtraction(llvm::PointerUnion<Symbol *, InputSection *> a,
+ llvm::PointerUnion<Symbol *, InputSection *> b,
uint64_t off, uint8_t length,
- SmallVectorImpl<Reloc> *newRelocs) {
+ llvm::SmallVectorImpl<Reloc> *newRelocs) {
auto subtrahend = a;
auto minuend = b;
if (Invert)
@@ -124,13 +123,13 @@ static void createSubtraction(PointerUnion<Symbol *, InputSection *> a,
}
void EhRelocator::makePcRel(uint64_t off,
- PointerUnion<Symbol *, InputSection *> target,
+ llvm::PointerUnion<Symbol *, InputSection *> target,
uint8_t length) {
createSubtraction(isec->symbols[0], target, off, length, &newRelocs);
}
void EhRelocator::makeNegativePcRel(
- uint64_t off, PointerUnion<Symbol *, InputSection *> target,
+ uint64_t off, llvm::PointerUnion<Symbol *, InputSection *> target,
uint8_t length) {
createSubtraction</*Invert=*/true>(isec, target, off, length, &newRelocs);
}
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index e0fc89782a419..aae5dfa1b03a4 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -20,7 +20,6 @@
#include <atomic>
-using namespace llvm;
using namespace lld;
using namespace lld::macho;
@@ -374,10 +373,10 @@ void ICF::forEachClass(llvm::function_ref<void(size_t, size_t)> func) {
size_t boundaries[shards + 1];
boundaries[0] = 0;
boundaries[shards] = icfInputs.size();
- parallelFor(1, shards, [&](size_t i) {
+ llvm::parallelFor(1, shards, [&](size_t i) {
boundaries[i] = findBoundary((i - 1) * step, icfInputs.size());
});
- parallelFor(1, shards + 1, [&](size_t i) {
+ llvm::parallelFor(1, shards + 1, [&](size_t i) {
if (boundaries[i - 1] < boundaries[i]) {
forEachClassRange(boundaries[i - 1], boundaries[i], func);
}
@@ -388,7 +387,7 @@ void ICF::forEachClass(llvm::function_ref<void(size_t, size_t)> func) {
void ICF::run() {
// Into each origin-section hash, combine all reloc referent section hashes.
for (icfPass = 0; icfPass < 2; ++icfPass) {
- parallelForEach(icfInputs, [&](ConcatInputSection *isec) {
+ llvm::parallelForEach(icfInputs, [&](ConcatInputSection *isec) {
uint32_t hash = isec->icfEqClass[icfPass % 2];
for (const Reloc &r : isec->relocs) {
if (auto *sym = r.referent.dyn_cast<Symbol *>()) {
@@ -507,7 +506,7 @@ void macho::markSymAsAddrSig(Symbol *s) {
}
void macho::markAddrSigSymbols() {
- TimeTraceScope timeScope("Mark addrsig symbols");
+ llvm::TimeTraceScope timeScope("Mark addrsig symbols");
for (InputFile *file : inputFiles) {
ObjFile *obj = dyn_cast<ObjFile>(file);
if (!obj)
@@ -550,7 +549,7 @@ Defined *macho::getBodyForThunkFoldedSym(Defined *foldedSym) {
return cast<Defined>(targetSym);
}
void macho::foldIdenticalSections(bool onlyCfStrings) {
- TimeTraceScope timeScope("Fold Identical Code Sections");
+ llvm::TimeTraceScope timeScope("Fold Identical Code Sections");
// The ICF equivalence-class segregation algorithm relies on pre-computed
// hashes of InputSection::data for the ConcatOutputSection::inputs and all
// sections referenced by their relocs. We could recursively traverse the
@@ -575,8 +574,9 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
isSelRefsSection(isec);
// NOTE: __objc_selrefs is typically marked as no_dead_strip by MC, but we
// can still fold it.
- bool hasFoldableFlags = (isSelRefsSection(isec) ||
- sectionType(isec->getFlags()) == MachO::S_REGULAR);
+ bool hasFoldableFlags =
+ (isSelRefsSection(isec) ||
+ sectionType(isec->getFlags()) == llvm::MachO::S_REGULAR);
bool isCodeSec = isCodeSection(isec);
@@ -620,7 +620,7 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
isec->icfEqClass[0] = ++icfUniqueID;
}
}
- parallelForEach(foldable, [](ConcatInputSection *isec) {
+ llvm::parallelForEach(foldable, [](ConcatInputSection *isec) {
assert(isec->icfEqClass[0] == 0); // don't overwrite a unique ID!
// Turn-on the top bit to guarantee that valid hashes have no collisions
// with the small-integer unique IDs for ICF-ineligible sections
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index 2b2d28ef63e2d..81ec37ace93d2 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -21,7 +21,6 @@
#include "lld/Common/Memory.h"
#include "llvm/Support/xxhash.h"
-using namespace llvm;
using namespace llvm::MachO;
using namespace llvm::support;
using namespace lld;
@@ -146,7 +145,7 @@ std::string InputSection::getSourceLocation(uint64_t off) const {
}
auto createMsg = [&](StringRef path, unsigned line) {
- std::string filename = sys::path::filename(path).str();
+ std::string filename = llvm::sys::path::filename(path).str();
std::string lineStr = (":" + Twine(line)).str();
if (filename == path)
return filename + lineStr;
@@ -154,8 +153,8 @@ std::string InputSection::getSourceLocation(uint64_t off) const {
};
// First, look up a function for a given offset.
- if (std::optional<DILineInfo> li = dwarf->getDILineInfo(
- section.addr + off, object::SectionedAddress::UndefSection))
+ if (std::optional<llvm::DILineInfo> li = dwarf->getDILineInfo(
+ section.addr + off, llvm::object::SectionedAddress::UndefSection))
return createMsg(li->FileName, li->Line);
// If it failed, look up again as a variable.
@@ -302,8 +301,8 @@ StringPiece &CStringInputSection::getStringPiece(uint64_t off) {
if (off >= data.size())
fatal(toString(this) + ": offset is outside the section");
- auto it =
- partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; });
+ auto it = llvm::partition_point(
+ pieces, [=](StringPiece p) { return p.inSecOff <= off; });
return it[-1];
}
@@ -315,8 +314,8 @@ size_t CStringInputSection::getStringPieceIndex(uint64_t off) const {
if (off >= data.size())
fatal(toString(this) + ": offset is outside the section");
- auto it =
- partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; });
+ auto it = llvm::partition_point(
+ pieces, [=](StringPiece p) { return p.inSecOff <= off; });
return std::distance(pieces.begin(), it) - 1;
}
diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index ab7f73c3a1df6..3ac27279905a7 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -17,10 +17,10 @@
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Support/TimeProfiler.h"
-using namespace llvm;
using namespace llvm::MachO;
using namespace lld;
using namespace lld::macho;
@@ -38,10 +38,11 @@ template <class LP> static bool objectHasObjCSection(MemoryBufferRef mb) {
auto sectionHeaders = ArrayRef<SectionHeader>{
reinterpret_cast<const SectionHeader *>(c + 1), c->nsects};
for (const SectionHeader &secHead : sectionHeaders) {
- StringRef sectname(secHead.sectname,
- strnlen(secHead.sectname, sizeof(secHead.sectname)));
- StringRef segname(secHead.segname,
- strnlen(secHead.segname, sizeof(secHead.segname)));
+ llvm::StringRef sectname(
+ secHead.sectname,
+ strnlen(secHead.sectname, sizeof(secHead.sectname)));
+ llvm::StringRef segname(
+ secHead.segname, strnlen(secHead.segname, sizeof(secHead.segname)));
if ((segname == segment_names::data &&
sectname == section_names::objcCatList) ||
(segname == segment_names::text &&
@@ -62,9 +63,9 @@ static bool objectHasObjCSection(MemoryBufferRef mb) {
bool macho::hasObjCSection(MemoryBufferRef mb) {
switch (identify_magic(mb.getBuffer())) {
- case file_magic::macho_object:
+ case llvm::file_magic::macho_object:
return objectHasObjCSection(mb);
- case file_magic::bitcode:
+ case llvm::file_magic::bitcode:
return check(isBitcodeContainingObjCCategory(mb));
default:
return false;
@@ -153,8 +154,8 @@ enum MethodKind {
};
struct ObjcClass {
- DenseMap<CachedHashStringRef, MethodContainer> instanceMethods;
- DenseMap<CachedHashStringRef, MethodContainer> classMethods;
+ llvm::DenseMap<llvm::CachedHashStringRef, MethodContainer> instanceMethods;
+ llvm::DenseMap<llvm::CachedHashStringRef, MethodContainer> classMethods;
};
} // namespace
@@ -177,7 +178,7 @@ class ObjcCategoryChecker {
ListHeaderLayout listHeaderLayout;
MethodLayout methodLayout;
- DenseMap<const Symbol *, ObjcClass> classMap;
+ llvm::DenseMap<const Symbol *, ObjcClass> classMap;
};
ObjcCategoryChecker::ObjcCategoryChecker()
@@ -196,7 +197,7 @@ void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec,
methodLayout.nameOffset)
continue;
- CachedHashStringRef methodName(r.getReferentString());
+ llvm::CachedHashStringRef methodName(r.getReferentString());
// +load methods are special: all implementations are called by the runtime
// even if they are part of the same class. Thus there is no need to check
// for duplicates.
@@ -311,7 +312,7 @@ void ObjcCategoryChecker::parseClass(const Defined *classSym) {
}
void objc::checkCategories() {
- TimeTraceScope timeScope("ObjcCategoryChecker");
+ llvm::TimeTraceScope timeScope("ObjcCategoryChecker");
ObjcCategoryChecker checker;
for (const InputSection *isec : inputSections) {
@@ -420,7 +421,7 @@ class ObjcCategoryMerger {
static void doCleanup();
private:
- DenseSet<const Symbol *> collectNlCategories();
+ llvm::DenseSet<const Symbol *> collectNlCategories();
void collectAndValidateCategoriesData();
bool
mergeCategoriesIntoSingleCategory(std::vector<InfoInputCategory> &categories);
@@ -429,7 +430,7 @@ class ObjcCategoryMerger {
void eraseMergedCategories();
void generateCatListForNonErasedCategories(
- MapVector<ConcatInputSection *, std::set<uint64_t>>
+ llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
catListToErasedOffsets);
void collectSectionWriteInfoFromIsec(const InputSection *isec,
InfoWriteSection &catWriteInfo);
@@ -494,14 +495,14 @@ class ObjcCategoryMerger {
InfoCategoryWriter infoCategoryWriter;
std::vector<ConcatInputSection *> &allInputSections;
// Map of base class Symbol to list of InfoInputCategory's for it
- MapVector<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
+ llvm::MapVector<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
// Normally, the binary data comes from the input files, but since we're
// generating binary data ourselves, we use the below array to store it in.
// Need this to be 'static' so the data survives past the ObjcCategoryMerger
// object, as the data will be read by the Writer when the final binary is
// generated.
- static SmallVector<std::unique_ptr<SmallVector<uint8_t>>>
+ static llvm::SmallVector<std::unique_ptr<llvm::SmallVector<uint8_t>>>
generatedSectionData;
};
@@ -542,7 +543,7 @@ ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
if (!reloc)
return nullptr;
- Symbol *sym = dyn_cast_if_present<Symbol *>(reloc->referent);
+ Symbol *sym = llvm::dyn_cast_if_present<Symbol *>(reloc->referent);
if (reloc->addend && sym) {
assert(isa<Defined>(sym) && "Expected defined for non-zero addend");
@@ -1149,8 +1150,8 @@ void ObjcCategoryMerger::createSymbolReference(Defined *refFrom,
// Get the list of categories in the '__objc_nlcatlist' section. We can't
// optimize these as they have a '+load' method that has to be called at
// runtime.
-DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() {
- DenseSet<const Symbol *> nlCategories;
+llvm::DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() {
+ llvm::DenseSet<const Symbol *> nlCategories;
for (InputSection *sec : allInputSections) {
if (sec->getName() != section_names::objcNonLazyCatList)
@@ -1219,7 +1220,7 @@ void ObjcCategoryMerger::collectAndValidateCategoriesData() {
// (not erased). For these not erased categories, we generate new __objc_catlist
// entries since the parent __objc_catlist entry will be erased
void ObjcCategoryMerger::generateCatListForNonErasedCategories(
- const MapVector<ConcatInputSection *, std::set<uint64_t>>
+ const llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
catListToErasedOffsets) {
// Go through all offsets of all __objc_catlist's that we process and if there
@@ -1284,7 +1285,8 @@ void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) {
// them.
void ObjcCategoryMerger::eraseMergedCategories() {
// Map of InputSection to a set of offsets of the categories that were merged
- MapVector<ConcatInputSection *, std::set<uint64_t>> catListToErasedOffsets;
+ llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
+ catListToErasedOffsets;
for (auto &mapEntry : categoryMap) {
for (InfoInputCategory &catInfo : mapEntry.second) {
@@ -1374,7 +1376,7 @@ SmallVector<uint8_t> &ObjcCategoryMerger::newSectionData(uint32_t size) {
} // namespace
void objc::mergeCategories() {
- TimeTraceScope timeScope("ObjcCategoryMerger");
+ llvm::TimeTraceScope timeScope("ObjcCategoryMerger");
ObjcCategoryMerger merger(inputSections);
merger.doMerge();
diff --git a/lld/MachO/Relocations.cpp b/lld/MachO/Relocations.cpp
index 78cc13388d6eb..f9b18305b5654 100644
--- a/lld/MachO/Relocations.cpp
+++ b/lld/MachO/Relocations.cpp
@@ -14,7 +14,6 @@
#include "lld/Common/ErrorHandler.h"
-using namespace llvm;
using namespace lld;
using namespace lld::macho;
diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index bf01b12d11dfd..0d6a829cf21dc 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -27,7 +27,6 @@
#include <numeric>
-using namespace llvm;
using namespace llvm::MachO;
using namespace llvm::support::endian;
using namespace lld;
@@ -118,7 +117,7 @@ struct CompactUnwindEntry {
InputSection *lsda;
};
-using EncodingMap = DenseMap<compact_unwind_encoding_t, size_t>;
+using EncodingMap = llvm::DenseMap<compact_unwind_encoding_t, size_t>;
struct SecondLevelPage {
uint32_t kind;
@@ -146,7 +145,7 @@ class UnwindInfoSectionImpl final : public UnwindInfoSection {
Symbol *canonicalizePersonality(Symbol *);
uint64_t unwindInfoSize = 0;
- SmallVector<decltype(symbols)::value_type, 0> symbolsVec;
+ llvm::SmallVector<decltype(symbols)::value_type, 0> symbolsVec;
CompactUnwindLayout cuLayout;
std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings;
EncodingMap commonEncodingIndexes;
@@ -154,12 +153,13 @@ class UnwindInfoSectionImpl final : public UnwindInfoSection {
// in symbolsVec.
std::vector<CompactUnwindEntry> cuEntries;
std::vector<Symbol *> personalities;
- SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>, Symbol *>
+ llvm::SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>,
+ Symbol *>
personalityTable;
// Indices into cuEntries for CUEs with a non-null LSDA.
std::vector<size_t> entriesWithLsda;
// Map of cuEntries index to an index within the LSDA array.
- DenseMap<size_t, uint32_t> lsdaIndex;
+ llvm::DenseMap<size_t, uint32_t> lsdaIndex;
std::vector<SecondLevelPage> secondLevelPages;
uint64_t level2PagesOffset = 0;
// The highest-address function plus its size. The unwinder needs this to
@@ -346,7 +346,7 @@ Symbol *UnwindInfoSectionImpl::canonicalizePersonality(Symbol *personality) {
// is no source address to make a relative location meaningful.
void UnwindInfoSectionImpl::relocateCompactUnwind(
std::vector<CompactUnwindEntry> &cuEntries) {
- parallelFor(0, symbolsVec.size(), [&](size_t i) {
+ llvm::parallelFor(0, symbolsVec.size(), [&](size_t i) {
CompactUnwindEntry &cu = cuEntries[i];
const Defined *d = symbolsVec[i].second;
cu.functionAddress = d->getVA();
@@ -383,9 +383,8 @@ void UnwindInfoSectionImpl::relocateCompactUnwind(
auto buf =
reinterpret_cast<const uint8_t *>(d->unwindEntry()->data.data()) -
target->wordSize;
- cu.functionLength =
- support::endian::read32le(buf + cuLayout.functionLengthOffset);
- cu.encoding = support::endian::read32le(buf + cuLayout.encodingOffset);
+ cu.functionLength = read32le(buf + cuLayout.functionLengthOffset);
+ cu.encoding = read32le(buf + cuLayout.encodingOffset);
for (const Reloc &r : d->unwindEntry()->relocs) {
if (r.offset == cuLayout.personalityOffset)
cu.personality = cast<Symbol *>(r.referent);
@@ -402,7 +401,7 @@ void UnwindInfoSectionImpl::encodePersonalities() {
if (cu.personality == nullptr)
continue;
// Linear search is fast enough for a small array.
- auto it = find(personalities, cu.personality);
+ auto it = llvm::find(personalities, cu.personality);
uint32_t personalityIndex; // 1-based index
if (it != personalities.end()) {
personalityIndex = std::distance(personalities.begin(), it) + 1;
>From 0132e36f56c9e3076b623d5bd8095c36581b53e1 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Tue, 30 Dec 2025 12:07:07 +0000
Subject: [PATCH 02/12] [MLIR][NFC] Fix ambiguity between const char* and Twine
---
mlir/lib/Support/TypeID.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Support/TypeID.cpp b/mlir/lib/Support/TypeID.cpp
index 304253cc6daa7..3526a0d49cc79 100644
--- a/mlir/lib/Support/TypeID.cpp
+++ b/mlir/lib/Support/TypeID.cpp
@@ -49,7 +49,7 @@ struct ImplicitTypeIDRegistry {
"`MLIR_DEFINE_EXPLICIT_TYPE_ID` or "
"`MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID`.\n";
}
- llvm::report_fatal_error(errorStr);
+ llvm::report_fatal_error(llvm::StringRef(errorStr));
}
#endif
>From 2fbd73f57cd15ce0d2d9f108414db862de979466 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 12:57:26 +0000
Subject: [PATCH 03/12] [CMake][LLVM] Add PCH infrastructure and LLVMSupport
PCH
---
clang/tools/c-index-test/CMakeLists.txt | 2 +
.../clang-fuzzer/dictionary/CMakeLists.txt | 2 +
flang/CMakeLists.txt | 10 --
flang/lib/Evaluate/CMakeLists.txt | 18 +--
flang/lib/Frontend/CMakeLists.txt | 16 +--
flang/lib/Lower/CMakeLists.txt | 22 +--
flang/lib/Parser/CMakeLists.txt | 16 +--
flang/lib/Semantics/CMakeLists.txt | 18 +--
llvm/cmake/modules/AddLLVM.cmake | 86 ++++++++++--
llvm/cmake/modules/HandleLLVMOptions.cmake | 10 ++
.../CMakeLists.txt | 2 +
.../OrcV2CBindingsBasicUsage/CMakeLists.txt | 2 +
.../OrcV2CBindingsDumpObjects/CMakeLists.txt | 2 +
.../OrcV2CBindingsIRTransforms/CMakeLists.txt | 2 +
.../OrcV2CBindingsLazy/CMakeLists.txt | 2 +
.../CMakeLists.txt | 2 +
.../CMakeLists.txt | 2 +
.../OrcV2CBindingsVeryLazy/CMakeLists.txt | 2 +
llvm/include/llvm/Support/pch.h | 130 ++++++++++++++++++
llvm/lib/CMakeLists.txt | 2 +-
llvm/lib/Support/CMakeLists.txt | 7 +-
llvm/tools/llvm-c-test/CMakeLists.txt | 2 +
llvm/utils/count/CMakeLists.txt | 2 +
mlir/test/CAPI/CMakeLists.txt | 1 +
24 files changed, 295 insertions(+), 65 deletions(-)
create mode 100644 llvm/include/llvm/Support/pch.h
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/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index d6acb4f984be9..71aeb8246669d 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -64,6 +64,57 @@ 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.
+ return()
+ 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)
+ #message(STATUS "PCH INFO: ${name} ${lib} ${lib_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(STATUS "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)
+ # This loop is purely for debugging to see what the actually used PCH is.
+ while(FALSE)
+ get_target_property(pch_reuse_parent ${pch_reuse} PRECOMPILE_HEADERS_REUSE_FROM)
+ if(${pch_reuse_parent} STREQUAL "pch_reuse_parent-NOTFOUND")
+ break()
+ endif()
+ set(pch_reuse ${pch_reuse_parent})
+ endwhile()
+ message(STATUS "Using PCH ${pch_reuse} for ${name} (prio ${pch_priority})")
+ target_precompile_headers(${name} REUSE_FROM ${pch_reuse})
+ else()
+ message(STATUS "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")
@@ -470,6 +521,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...
@@ -489,11 +547,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})
@@ -535,6 +594,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")
@@ -589,7 +649,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")
@@ -661,6 +721,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)
@@ -743,8 +808,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()
@@ -755,7 +819,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
@@ -978,6 +1042,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})
@@ -1017,7 +1082,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})
@@ -1058,6 +1123,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")
@@ -1765,7 +1835,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 397aa0a6e0766..2e84fbe2b310f 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -1313,6 +1313,16 @@ 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(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
+ 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()
+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_example(OrcV2CBindingsMCJITLikeMemoryManager
OrcV2CBindingsMCJITLikeMemoryManager.c
+
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
)
diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt b/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
index 5b737557bb1ef..441814054d9d1 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_example(OrcV2CBindingsRemovableCode
OrcV2CBindingsRemovableCode.c
+
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
)
diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt b/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
index 0bc9610b1ad7e..6ec22f63875b9 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_example(OrcV2CBindingsVeryLazy
OrcV2CBindingsVeryLazy.c
+
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
)
diff --git a/llvm/include/llvm/Support/pch.h b/llvm/include/llvm/Support/pch.h
new file mode 100644
index 0000000000000..b1ff8698827ff
--- /dev/null
+++ b/llvm/include/llvm/Support/pch.h
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMSupport.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ADL.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <any>
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <charconv>
+#include <chrono>
+#include <cinttypes>
+#include <climits>
+#include <cmath>
+#include <complex.h>
+#include <complex>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <ctype.h>
+#include <cuchar>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <errno.h>
+#include <exception>
+#include <execution>
+#include <fenv.h>
+#include <filesystem>
+#include <float.h>
+#include <forward_list>
+#include <fstream>
+#include <functional>
+#include <initializer_list>
+#include <iostream>
+#include <istream>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <memory_resource>
+#include <mutex>
+#include <new>
+#include <numeric>
+#include <optional>
+#include <ostream>
+#include <queue>
+#include <random>
+#include <ratio>
+#include <regex>
+#include <scoped_allocator>
+#include <set>
+#include <shared_mutex>
+#include <sstream>
+#include <stack>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdexcept>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <streambuf>
+#include <string.h>
+#include <string>
+#include <string_view>
+#include <system_error>
+#include <tgmath.h>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#include <typeindex>
+#include <typeinfo>
+#include <uchar.h>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <variant>
+#include <vector>
+#include <wchar.h>
+#include <wctype.h>
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index 9af1854852436..f0faaff307997 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -3,8 +3,8 @@ include(LLVM-Build)
# `Demangle', `Support' and `TableGen' libraries are added on the top-level
# CMakeLists.txt
-add_subdirectory(ABI)
add_subdirectory(IR)
+add_subdirectory(ABI)
add_subdirectory(FuzzMutate)
add_subdirectory(FileCheck)
add_subdirectory(InterfaceStub)
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 099b0e55579be..b4e39fced3853 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -135,7 +135,6 @@ if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
endif()
add_subdirectory(BLAKE3)
-add_subdirectory(LSP)
add_llvm_component_library(LLVMSupport
ABIBreak.cpp
@@ -322,6 +321,9 @@ add_llvm_component_library(LLVMSupport
${LLVM_MAIN_INCLUDE_DIR}/llvm/Support
${Backtrace_INCLUDE_DIRS}
+ PRECOMPILE_HEADERS
+ [["llvm/Support/pch.h"]]
+
LINK_LIBS
${system_libs} ${imported_libs} ${delayload_flags}
@@ -396,3 +398,6 @@ target_include_directories(LLVMSupport
PRIVATE
${LLVM_THIRD_PARTY_DIR}/siphash/include
)
+
+# SupportLSP depends on Support and therefore must be included afterwards.
+add_subdirectory(LSP)
diff --git a/llvm/tools/llvm-c-test/CMakeLists.txt b/llvm/tools/llvm-c-test/CMakeLists.txt
index 939164e636216..8dd42b48e39a2 100644
--- a/llvm/tools/llvm-c-test/CMakeLists.txt
+++ b/llvm/tools/llvm-c-test/CMakeLists.txt
@@ -53,6 +53,8 @@ add_llvm_tool(llvm-c-test
metadata.c
object.c
targets.c
+
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
)
if(USE_LLVM_DYLIB)
diff --git a/llvm/utils/count/CMakeLists.txt b/llvm/utils/count/CMakeLists.txt
index cfd1f4a85d8a1..4f53b72bf8203 100644
--- a/llvm/utils/count/CMakeLists.txt
+++ b/llvm/utils/count/CMakeLists.txt
@@ -4,4 +4,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_utility(count
count.c
+
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
)
diff --git a/mlir/test/CAPI/CMakeLists.txt b/mlir/test/CAPI/CMakeLists.txt
index d45142510a496..3b4ee07b2283e 100644
--- a/mlir/test/CAPI/CMakeLists.txt
+++ b/mlir/test/CAPI/CMakeLists.txt
@@ -8,6 +8,7 @@ function(_add_capi_test_executable name)
)
add_llvm_executable(${name}
PARTIAL_SOURCES_INTENDED
+ DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
${ARG_UNPARSED_ARGUMENTS})
set_target_properties(${name} PROPERTIES FOLDER "MLIR/Tests")
set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL ON)
>From 1b605e083e1fb2d12a7e63e4bce8c05665f89c39 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 13:08:45 +0000
Subject: [PATCH 04/12] [CMake][IR] Add PCH
---
llvm/include/llvm/IR/pch.h | 31 +++++++++++++++++++++++++++++++
llvm/lib/IR/CMakeLists.txt | 3 +++
2 files changed, 34 insertions(+)
create mode 100644 llvm/include/llvm/IR/pch.h
diff --git a/llvm/include/llvm/IR/pch.h b/llvm/include/llvm/IR/pch.h
new file mode 100644
index 0000000000000..b2fa937076d77
--- /dev/null
+++ b/llvm/include/llvm/IR/pch.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMCore.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/pch.h"
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 31821a2d6b208..08bac979d4c90 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -83,6 +83,9 @@ add_llvm_component_library(LLVMCore
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
+ PRECOMPILE_HEADERS
+ [["llvm/IR/pch.h"]]
+
LINK_LIBS
${LLVM_PTHREAD_LIB}
>From 3d3e54e7a7968d9d3617760a42d29318d0c89afa Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 13:09:09 +0000
Subject: [PATCH 05/12] [CMake][CodeGen] Add PCH
---
llvm/include/llvm/CodeGen/pch.h | 25 +++++++++++++++++++++++++
llvm/lib/CodeGen/CMakeLists.txt | 3 +++
2 files changed, 28 insertions(+)
create mode 100644 llvm/include/llvm/CodeGen/pch.h
diff --git a/llvm/include/llvm/CodeGen/pch.h b/llvm/include/llvm/CodeGen/pch.h
new file mode 100644
index 0000000000000..36eb560b3c003
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/pch.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMCodeGen.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/IR/pch.h"
+#include "llvm/Support/pch.h"
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index f26b2cb6fddf5..21845da1da54b 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -267,6 +267,9 @@ add_llvm_component_library(LLVMCodeGen
${LLVM_MAIN_INCLUDE_DIR}/llvm/CodeGen
${LLVM_MAIN_INCLUDE_DIR}/llvm/CodeGen/PBQP
+ PRECOMPILE_HEADERS
+ [["llvm/CodeGen/pch.h"]]
+
LINK_LIBS ${LLVM_PTHREAD_LIB} ${MLLinkDeps}
DEPENDS
>From 06d5189659d5e09b5007dd98fb70e7154355c9d3 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 13:09:27 +0000
Subject: [PATCH 06/12] [CMake][AST] Add PCH
---
clang/include/clang/AST/pch.h | 32 +++++++++++++++++++++++++++
clang/lib/AST/CMakeLists.txt | 3 +++
clang/lib/Frontend/TextDiagnostic.cpp | 4 ++--
3 files changed, 37 insertions(+), 2 deletions(-)
create mode 100644 clang/include/clang/AST/pch.h
diff --git a/clang/include/clang/AST/pch.h b/clang/include/clang/AST/pch.h
new file mode 100644
index 0000000000000..b048f866bc555
--- /dev/null
+++ b/clang/include/clang/AST/pch.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for clangAST.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/GlobalDecl.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "llvm/Support/pch.h"
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index f9a5f4f0e7ecd..0e0a0c94d2ac5 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -136,6 +136,9 @@ add_clang_library(clangAST
VTableBuilder.cpp
VTTBuilder.cpp
+ PRECOMPILE_HEADERS
+ [["clang/AST/pch.h"]]
+
LINK_LIBS
clangBasic
clangLex
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index 3f30709b0447e..196ab715206ff 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -37,7 +37,7 @@ static constexpr raw_ostream::Colors SavedColor = raw_ostream::SAVEDCOLOR;
// is already taken for 'note'. Green is already used to underline
// source ranges. White and black are bad because of the usual
// terminal backgrounds. Which leaves us only with TWO options.
-static constexpr raw_ostream::Colors CommentColor = raw_ostream::YELLOW;
+static constexpr raw_ostream::Colors TCommentColor = raw_ostream::YELLOW;
static constexpr raw_ostream::Colors LiteralColor = raw_ostream::GREEN;
static constexpr raw_ostream::Colors KeywordColor = raw_ostream::BLUE;
@@ -1269,7 +1269,7 @@ highlightLines(StringRef FileData, unsigned StartLineNumber,
Vec.emplace_back(Start, Start + Length, LiteralColor);
} else {
assert(T.is(tok::comment));
- Vec.emplace_back(Start, Start + Length, CommentColor);
+ Vec.emplace_back(Start, Start + Length, TCommentColor);
}
};
>From 330e472e63981a2906a80f8a2cf832f8333493d3 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Tue, 30 Dec 2025 11:10:43 +0000
Subject: [PATCH 07/12] pch for unittests
---
clang/unittests/Basic/CharInfoTest.cpp | 1 -
.../Interpreter/ExceptionTests/CMakeLists.txt | 2 +-
llvm/cmake/modules/AddLLVM.cmake | 12 ++++++++++--
llvm/unittests/Support/raw_sha1_ostream_test.cpp | 15 +--------------
third-party/unittest/CMakeLists.txt | 7 ++++++-
5 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/clang/unittests/Basic/CharInfoTest.cpp b/clang/unittests/Basic/CharInfoTest.cpp
index 491c9afceb6f8..09b827be35397 100644
--- a/clang/unittests/Basic/CharInfoTest.cpp
+++ b/clang/unittests/Basic/CharInfoTest.cpp
@@ -9,7 +9,6 @@
#include "clang/Basic/CharInfo.h"
#include "gtest/gtest.h"
-using namespace llvm;
using namespace clang;
// Check that the CharInfo table has been constructed reasonably.
diff --git a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
index dfd94d8e6442c..5ea752b77f6f9 100644
--- a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
+++ b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
@@ -1,7 +1,7 @@
# The interpreter can throw an exception from user input. The test binary needs
# to be compiled with exception support to catch the thrown exception.
set(LLVM_REQUIRES_EH ON)
-set(LLVM_REQUIRES_RTTI ON)
+set(LLVM_REQUIRES_RTTI OFF)
add_distinct_clang_unittest(ClangReplInterpreterExceptionTests
InterpreterExceptionTest.cpp
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index 71aeb8246669d..e27db837dc287 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -26,8 +26,9 @@ function(llvm_update_compile_flags name)
# force EH
if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
- message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
- set(LLVM_REQUIRES_RTTI ON)
+ # XXX: still required?
+ #message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
+ #set(LLVM_REQUIRES_RTTI ON)
endif()
if(MSVC)
list(APPEND LLVM_COMPILE_CXXFLAGS "/EHsc")
@@ -1850,8 +1851,15 @@ function(add_unittest test_suite test_name)
# If it is not defined, fall back to llvm_gtest.
if(TARGET default_gtest)
target_link_libraries(${test_name} PRIVATE default_gtest_main default_gtest ${LLVM_PTHREAD_LIB})
+ # Runtime builds are too diverse in compiler flags/defines.
+ if(NOT LLVM_RUNTIMES_BUILD AND NOT LLVM_REQUIRES_RTTI AND NOT LLVM_REQUIRES_EH)
+ target_precompile_headers(${test_name} REUSE_FROM default_gtest)
+ endif()
else ()
target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB})
+ if(NOT LLVM_REQUIRES_RTTI AND NOT LLVM_REQUIRES_EH)
+ target_precompile_headers(${test_name} REUSE_FROM llvm_gtest)
+ endif()
endif ()
add_dependencies(${test_suite} ${test_name})
diff --git a/llvm/unittests/Support/raw_sha1_ostream_test.cpp b/llvm/unittests/Support/raw_sha1_ostream_test.cpp
index a3cb6f58d3e29..be8333237d81d 100644
--- a/llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ b/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_sha1_ostream.h"
#include "gtest/gtest.h"
@@ -14,20 +15,6 @@
using namespace llvm;
-static std::string toHex(ArrayRef<uint8_t> Input) {
- static const char *const LUT = "0123456789ABCDEF";
- size_t Length = Input.size();
-
- std::string Output;
- Output.reserve(2 * Length);
- for (size_t i = 0; i < Length; ++i) {
- const unsigned char c = Input[i];
- Output.push_back(LUT[c >> 4]);
- Output.push_back(LUT[c & 15]);
- }
- return Output;
-}
-
TEST(raw_sha1_ostreamTest, Basic) {
llvm::raw_sha1_ostream Sha1Stream;
Sha1Stream << "Hello World!";
diff --git a/third-party/unittest/CMakeLists.txt b/third-party/unittest/CMakeLists.txt
index 79535a1de4616..29dd670ba33f7 100644
--- a/third-party/unittest/CMakeLists.txt
+++ b/third-party/unittest/CMakeLists.txt
@@ -13,6 +13,8 @@
set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test")
+set(GTEST_PCH [["gtest/gtest.h"]])
+
if(LLVM_RUNTIMES_BUILD)
# This instance of GTest is use for unittests for the runtime libraries. It
# must not link to LLVMSupport (used for llvm::raw_ostream and llvm::cl
@@ -37,6 +39,7 @@ else()
set(GTEST_LLVM_COMPONENTS "Support")
set(gtest_name "llvm_gtest")
set(gtest_main_src UnitTestMain/TestMain.cpp)
+ list(APPEND GTEST_PCH [["llvm/Support/pch.h"]])
endif()
if(WIN32)
@@ -59,7 +62,6 @@ if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
add_definitions("-Wno-covered-switch-default")
endif()
-set(LLVM_REQUIRES_RTTI 1)
add_definitions( -DGTEST_HAS_RTTI=0 )
if (HAVE_LIBPTHREAD)
@@ -76,6 +78,9 @@ add_llvm_library("${gtest_name}"
googletest/src/gtest-all.cc
googlemock/src/gmock-all.cc
+ PRECOMPILE_HEADERS
+ ${GTEST_PCH}
+
LINK_LIBS
${LIBS}
>From f83f964d3a6f64802f31f5bbc24a969bcd54fb10 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 14:19:03 +0000
Subject: [PATCH 08/12] [Support][NFC] Move JSON::dump out-of-line to prevent
redundant compilation
---
llvm/include/llvm/Support/JSON.h | 5 +----
llvm/lib/Support/JSON.cpp | 7 +++++++
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h
index a58332c912942..72e5a65dfea12 100644
--- a/llvm/include/llvm/Support/JSON.h
+++ b/llvm/include/llvm/Support/JSON.h
@@ -477,10 +477,7 @@ class Value {
LLVM_ABI void print(llvm::raw_ostream &OS) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const {
- print(llvm::dbgs());
- llvm::dbgs() << '\n';
- }
+ LLVM_DUMP_METHOD void dump() const;
#endif // !NDEBUG || LLVM_ENABLE_DUMP
private:
diff --git a/llvm/lib/Support/JSON.cpp b/llvm/lib/Support/JSON.cpp
index 4652c0740dc4d..e9fd8f8fae1fa 100644
--- a/llvm/lib/Support/JSON.cpp
+++ b/llvm/lib/Support/JSON.cpp
@@ -175,6 +175,13 @@ void Value::destroy() {
void Value::print(llvm::raw_ostream &OS) const { OS << *this; }
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD void Value::dump() const {
+ print(llvm::dbgs());
+ llvm::dbgs() << '\n';
+}
+#endif
+
bool operator==(const Value &L, const Value &R) {
if (L.kind() != R.kind())
return false;
>From 45db8db4384d6312dd24833c9d726889d9dc7478 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 14:35:32 +0000
Subject: [PATCH 09/12] fixup! [CMake][LLVM] Add PCH infrastructure and
LLVMSupport PCH
---
llvm/cmake/modules/AddLLVM.cmake | 9 ++++-----
llvm/include/llvm/Support/pch.h | 3 ++-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index e27db837dc287..89d0191b27878 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -68,7 +68,7 @@ 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.
- return()
+ set(ARG_DISABLE_PCH_REUSE ON)
endif()
# Find PCH with highest priority from dependencies. We reuse the first PCH
@@ -84,7 +84,6 @@ function(llvm_update_pch name)
foreach(lib ${libs})
if(TARGET ${lib})
get_target_property(lib_pch_priority ${lib} LLVM_PCH_PRIORITY)
- #message(STATUS "PCH INFO: ${name} ${lib} ${lib_pch_priority}")
if(${lib_pch_priority} GREATER ${pch_priority})
set(pch_priority ${lib_pch_priority})
set(pch_reuse ${lib})
@@ -93,7 +92,7 @@ function(llvm_update_pch name)
endforeach()
if(ARG_PRECOMPILE_HEADERS)
- message(STATUS "Adding PCH ${ARG_PRECOMPILE_HEADERS} for ${name} (prio ${pch_priority})")
+ 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.
@@ -109,10 +108,10 @@ function(llvm_update_pch name)
endif()
set(pch_reuse ${pch_reuse_parent})
endwhile()
- message(STATUS "Using PCH ${pch_reuse} for ${name} (prio ${pch_priority})")
+ message(DEBUG "Using PCH ${pch_reuse} for ${name} (prio ${pch_priority})")
target_precompile_headers(${name} REUSE_FROM ${pch_reuse})
else()
- message(STATUS "Using NO PCH for ${name}")
+ message(DEBUG "Using NO PCH for ${name}")
endif()
endfunction()
diff --git a/llvm/include/llvm/Support/pch.h b/llvm/include/llvm/Support/pch.h
index b1ff8698827ff..9265f366df587 100644
--- a/llvm/include/llvm/Support/pch.h
+++ b/llvm/include/llvm/Support/pch.h
@@ -79,7 +79,8 @@
#include <fstream>
#include <functional>
#include <initializer_list>
-#include <iostream>
+// iostream is banned.
+// #include <iostream>
#include <istream>
#include <iterator>
#include <limits>
>From 92ca4a5d14610b697456d44981a535f40a50f931 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 17:32:31 +0000
Subject: [PATCH 10/12] [CMake][CodeGen] Add PCH for Clang CodeGen
---
clang/lib/CodeGen/CGLoopInfo.cpp | 5 ++++-
clang/lib/CodeGen/CMakeLists.txt | 4 ++++
clang/lib/CodeGen/pch.h | 22 ++++++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
create mode 100644 clang/lib/CodeGen/pch.h
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index b2b569a43038c..4a580fc58f940 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -18,9 +18,11 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include <optional>
-using namespace clang::CodeGen;
using namespace llvm;
+// No using namespace to avoid collision with llvm::LoopInfo.
+namespace clang::CodeGen {
+
MDNode *
LoopInfo::createFollowupMetadata(const char *FollowupName,
ArrayRef<llvm::Metadata *> LoopProperties) {
@@ -863,3 +865,4 @@ void LoopInfoStack::InsertHelper(Instruction *I) const {
return;
}
}
+} // end namespace clang::CodeGen
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index dbbc35b372f42..cf08938c349b2 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -158,6 +158,10 @@ add_clang_library(clangCodeGen
TrapReasonBuilder.cpp
VarBypassDetector.cpp
+ DISABLE_PCH_REUSE # PCH contains private headers
+ PRECOMPILE_HEADERS
+ [["pch.h"]]
+
DEPENDS
vt_gen
intrinsics_gen
diff --git a/clang/lib/CodeGen/pch.h b/clang/lib/CodeGen/pch.h
new file mode 100644
index 0000000000000..137fe034dd83b
--- /dev/null
+++ b/clang/lib/CodeGen/pch.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for clangCodeGen. Uses private headers.
+///
+//===----------------------------------------------------------------------===//
+
+#include "ABIInfoImpl.h"
+#include "Address.h"
+#include "CGBuilder.h"
+#include "CGCXXABI.h"
+#include "CGValue.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/pch.h"
+#include "llvm/IR/pch.h"
+#include "llvm/Support/pch.h"
>From 5be1e67e1dff3764ded8d46ff54a50e6560c5c4f Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 7 Jan 2026 17:32:59 +0000
Subject: [PATCH 11/12] [Transforms][NFC] Remove unused include in LoopUtils
This avoid pulling in LoopAccessAnalysis in ~45 source files.
---
llvm/include/llvm/Transforms/Utils/LoopUtils.h | 3 +--
llvm/lib/Transforms/Scalar/LoopFlatten.cpp | 1 +
llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index 42ed3c659edd9..0f7ee82a6ff64 100644
--- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -13,8 +13,6 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
-#include "llvm/Analysis/IVDescriptors.h"
-#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -37,6 +35,7 @@ class MemoryAccess;
class MemorySSA;
class MemorySSAUpdater;
class OptimizationRemarkEmitter;
+struct PointerDiffInfo;
class PredIteratorCache;
class ScalarEvolution;
class SCEV;
diff --git a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
index d8b611076efea..2796482f97b73 100644
--- a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp
@@ -53,6 +53,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopNestAnalysis.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index cdbd0af4cbeaf..b618aa198632c 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -40,6 +40,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/HashRecognize.h"
+#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemoryLocation.h"
>From 0b4660f3eef766995d5012d01abf4fa61fab4efd Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Thu, 8 Jan 2026 20:01:29 +0000
Subject: [PATCH 12/12] fixup! fixup! [CMake][LLVM] Add PCH infrastructure and
LLVMSupport PCH
Reduce number of Support PCH headers for GCC.
---
llvm/include/llvm/Support/pch.h | 56 ---------------------------------
1 file changed, 56 deletions(-)
diff --git a/llvm/include/llvm/Support/pch.h b/llvm/include/llvm/Support/pch.h
index 9265f366df587..ccfeceb231f61 100644
--- a/llvm/include/llvm/Support/pch.h
+++ b/llvm/include/llvm/Support/pch.h
@@ -32,100 +32,44 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JSON.h"
-#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <any>
#include <array>
#include <atomic>
#include <bitset>
#include <cassert>
-#include <cctype>
-#include <cerrno>
-#include <cfenv>
-#include <cfloat>
-#include <charconv>
#include <chrono>
-#include <cinttypes>
#include <climits>
#include <cmath>
-#include <complex.h>
-#include <complex>
-#include <condition_variable>
-#include <csetjmp>
-#include <csignal>
-#include <cstdarg>
#include <cstddef>
#include <cstdint>
-#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
-#include <ctype.h>
-#include <cuchar>
-#include <cwchar>
-#include <cwctype>
#include <deque>
-#include <errno.h>
-#include <exception>
-#include <execution>
-#include <fenv.h>
-#include <filesystem>
-#include <float.h>
-#include <forward_list>
-#include <fstream>
#include <functional>
#include <initializer_list>
-// iostream is banned.
-// #include <iostream>
-#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
-#include <math.h>
#include <memory>
-#include <memory_resource>
#include <mutex>
#include <new>
-#include <numeric>
#include <optional>
-#include <ostream>
#include <queue>
-#include <random>
-#include <ratio>
-#include <regex>
-#include <scoped_allocator>
#include <set>
-#include <shared_mutex>
#include <sstream>
-#include <stack>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdexcept>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <streambuf>
-#include <string.h>
#include <string>
#include <string_view>
#include <system_error>
-#include <tgmath.h>
-#include <thread>
#include <tuple>
#include <type_traits>
-#include <typeindex>
-#include <typeinfo>
-#include <uchar.h>
#include <unordered_map>
#include <unordered_set>
#include <utility>
-#include <valarray>
#include <variant>
#include <vector>
-#include <wchar.h>
-#include <wctype.h>
More information about the llvm-commits
mailing list