Skip to content

Commit 16f9bc5

Browse files
committed
[CMAKE][llvm-libraries] Add Precompiled Headers option to improve build times
1 parent 92dfe20 commit 16f9bc5

15 files changed

+338
-249
lines changed

Diff for: llvm/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1410,3 +1410,6 @@ endif()
14101410
if (LLVM_INCLUDE_UTILS AND LLVM_INCLUDE_TOOLS)
14111411
add_subdirectory(utils/llvm-locstats)
14121412
endif()
1413+
1414+
include(LLVMPrecompiledHeaders)
1415+
llvm_lib_precompiled_headers()

Diff for: llvm/cmake/modules/HandleLLVMOptions.cmake

+7-1
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ endif()
538538

539539
option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
540540

541+
option(LLVM_ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers to improve build times." ON)
542+
541543
if( MSVC )
542544

543545
# Add definitions that make MSVC much less annoying.
@@ -593,7 +595,11 @@ if( MSVC )
593595
# PDBs without changing codegen.
594596
option(LLVM_ENABLE_PDB OFF)
595597
if (LLVM_ENABLE_PDB AND uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
596-
append("/Zi" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
598+
if (LLVM_ENABLE_PRECOMPILED_HEADERS)
599+
append("/Z7" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
600+
else()
601+
append("/Zi" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
602+
endif()
597603
# /DEBUG disables linker GC and ICF, but we want those in Release mode.
598604
append("/DEBUG /OPT:REF /OPT:ICF"
599605
CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS

Diff for: llvm/cmake/modules/LLVMPrecompiledHeaders.cmake

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
macro(get_all_targets_recursive targets dir)
2+
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
3+
foreach(subdir ${subdirectories})
4+
get_all_targets_recursive(${targets} ${subdir})
5+
endforeach()
6+
7+
get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
8+
list(APPEND ${targets} ${current_targets})
9+
endmacro()
10+
11+
function(get_all_targets dir outvar)
12+
set(targets)
13+
get_all_targets_recursive(targets ${dir})
14+
set(${outvar} ${targets} PARENT_SCOPE)
15+
endfunction()
16+
17+
function(add_llvm_lib_precompiled_headers target)
18+
if (LLVM_ENABLE_PRECOMPILED_HEADERS)
19+
get_target_property(target_type ${target} TYPE)
20+
if (target_type STREQUAL "STATIC_LIBRARY")
21+
target_precompile_headers(
22+
${target}
23+
PRIVATE
24+
"$<$<COMPILE_LANGUAGE:CXX>:${LLVM_MAIN_INCLUDE_DIR}/llvm/PrecompiledHeaders.h>"
25+
)
26+
endif()
27+
endif()
28+
endfunction()
29+
30+
function(llvm_lib_precompiled_headers)
31+
get_all_targets("${LLVM_MAIN_SRC_DIR}/lib" lib_targets)
32+
foreach(target ${lib_targets})
33+
add_llvm_lib_precompiled_headers(${target})
34+
endforeach()
35+
endfunction()

Diff for: llvm/include/llvm/Demangle/ItaniumDemangle.h

+6
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,12 @@ class EnableIfAttr : public Node {
586586

587587
class ObjCProtoName : public Node {
588588
const Node *Ty;
589+
#if LLVM_ENABLE_PRECOMPILED_HEADERS
590+
public:
591+
// When PCH is enabled, Protocol is unable to be read by the PointerType
592+
// friend class, make it public to avoid this issue.
593+
// TODO: Fix friend class interaction when PCH is enabled.
594+
#endif
589595
std::string_view Protocol;
590596

591597
friend class PointerType;

Diff for: llvm/include/llvm/PrecompiledHeaders.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===-- llvm/PrecompiledHeaders.h - Precompiled Headers ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file contains the most common headers used within the LLVM library.
11+
/// It is intended to be used as a precompiled header.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_PRECOMPILEDHEADERS_H
16+
#define LLVM_PRECOMPILEDHEADERS_H
17+
18+
#include "ADT/ArrayRef.h"
19+
20+
#include "CodeGen/SelectionDAG.h"
21+
#include "CodeGen/TargetInstrInfo.h"
22+
23+
#include "IR/IntrinsicInst.h"
24+
#include "IR/PassManager.h"
25+
26+
#include "MC/MCContext.h"
27+
28+
#endif // LLVM_PRECOMPILEDHEADERS_H

Diff for: llvm/lib/BinaryFormat/Dwarf.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,9 @@ StringRef llvm::dwarf::RLEString(unsigned RLE) {
858858
}
859859
}
860860

861-
constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[];
862-
constexpr char llvm::dwarf::EnumTraits<Form>::Type[];
863-
constexpr char llvm::dwarf::EnumTraits<Index>::Type[];
864-
constexpr char llvm::dwarf::EnumTraits<Tag>::Type[];
865-
constexpr char llvm::dwarf::EnumTraits<LineNumberOps>::Type[];
866-
constexpr char llvm::dwarf::EnumTraits<LocationAtom>::Type[];
861+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::Attribute>::Type[];
862+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::Form>::Type[];
863+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::Index>::Type[];
864+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::Tag>::Type[];
865+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::LineNumberOps>::Type[];
866+
constexpr char llvm::dwarf::EnumTraits<llvm::dwarf::LocationAtom>::Type[];

Diff for: llvm/lib/BinaryFormat/MsgPackDocumentYAML.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,18 @@ template <> struct TaggedScalarTraits<ScalarDocNode> {
184184

185185
static QuotingType mustQuote(const ScalarDocNode &S, StringRef ScalarStr) {
186186
switch (S.getKind()) {
187-
case Type::Int:
187+
case msgpack::Type::Int:
188188
return ScalarTraits<int64_t>::mustQuote(ScalarStr);
189-
case Type::UInt:
189+
case msgpack::Type::UInt:
190190
return ScalarTraits<uint64_t>::mustQuote(ScalarStr);
191-
case Type::Nil:
191+
case msgpack::Type::Nil:
192192
return ScalarTraits<StringRef>::mustQuote(ScalarStr);
193-
case Type::Boolean:
193+
case msgpack::Type::Boolean:
194194
return ScalarTraits<bool>::mustQuote(ScalarStr);
195-
case Type::Float:
195+
case msgpack::Type::Float:
196196
return ScalarTraits<double>::mustQuote(ScalarStr);
197-
case Type::Binary:
198-
case Type::String:
197+
case msgpack::Type::Binary:
198+
case msgpack::Type::String:
199199
return ScalarTraits<std::string>::mustQuote(ScalarStr);
200200
default:
201201
llvm_unreachable("unrecognized ScalarKind");

Diff for: llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, uint64_t *OffsetPtr) {
6868

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

Diff for: llvm/lib/Object/Minidump.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Expected<ArrayRef<T>> MinidumpFile::getListStream(StreamType Type) const {
9292

9393
return getDataSliceAs<T>(*Stream, ListOffset, ListSize);
9494
}
95-
template Expected<ArrayRef<Module>>
95+
template Expected<ArrayRef<minidump::Module>>
9696
MinidumpFile::getListStream(StreamType) const;
9797
template Expected<ArrayRef<Thread>>
9898
MinidumpFile::getListStream(StreamType) const;

Diff for: llvm/lib/ObjectYAML/MinidumpYAML.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
499499
if (!ExpectedList)
500500
return ExpectedList.takeError();
501501
std::vector<ModuleListStream::entry_type> Modules;
502-
for (const Module &M : *ExpectedList) {
502+
for (const minidump::Module &M : *ExpectedList) {
503503
auto ExpectedName = File.getString(M.ModuleNameRVA);
504504
if (!ExpectedName)
505505
return ExpectedName.takeError();

Diff for: llvm/lib/Remarks/Remark.cpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,24 @@ std::string Remark::getArgsAsMsg() const {
2727
}
2828

2929
/// Returns the value of a specified key parsed from StringRef.
30-
std::optional<int> Argument::getValAsInt() const {
30+
std::optional<int> llvm::remarks::Argument::getValAsInt() const {
3131
APInt KeyVal;
3232
if (Val.getAsInteger(10, KeyVal))
3333
return std::nullopt;
3434
return KeyVal.getSExtValue();
3535
}
3636

37-
bool Argument::isValInt() const { return getValAsInt().has_value(); }
37+
bool llvm::remarks::Argument::isValInt() const {
38+
return getValAsInt().has_value();
39+
}
3840

3941
void RemarkLocation::print(raw_ostream &OS) const {
4042
OS << "{ "
4143
<< "File: " << SourceFilePath << ", Line: " << SourceLine
4244
<< " Column:" << SourceColumn << " }\n";
4345
}
4446

45-
void Argument::print(raw_ostream &OS) const {
47+
void llvm::remarks::Argument::print(raw_ostream &OS) const {
4648
OS << Key << ": " << Val << "\n";
4749
}
4850

@@ -146,12 +148,12 @@ extern "C" uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark) {
146148

147149
extern "C" LLVMRemarkArgRef
148150
LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark) {
149-
ArrayRef<Argument> Args = unwrap(Remark)->Args;
151+
ArrayRef<remarks::Argument> Args = unwrap(Remark)->Args;
150152
// No arguments to iterate on.
151153
if (Args.empty())
152154
return nullptr;
153155
return reinterpret_cast<LLVMRemarkArgRef>(
154-
const_cast<Argument *>(Args.begin()));
156+
const_cast<remarks::Argument *>(Args.begin()));
155157
}
156158

157159
extern "C" LLVMRemarkArgRef
@@ -160,10 +162,11 @@ LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef ArgIt, LLVMRemarkEntryRef Remark) {
160162
if (ArgIt == nullptr)
161163
return nullptr;
162164

163-
auto It = (ArrayRef<Argument>::const_iterator)ArgIt;
165+
auto It = (ArrayRef<remarks::Argument>::const_iterator)ArgIt;
164166
auto Next = std::next(It);
165167
if (Next == unwrap(Remark)->Args.end())
166168
return nullptr;
167169

168-
return reinterpret_cast<LLVMRemarkArgRef>(const_cast<Argument *>(Next));
170+
return reinterpret_cast<LLVMRemarkArgRef>(
171+
const_cast<remarks::Argument *>(Next));
169172
}

Diff for: llvm/lib/Remarks/YAMLRemarkParser.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,16 @@ YAMLRemarkParser::parseRemark(yaml::Document &RemarkEntry) {
260260
}
261261

262262
// Check if any of the mandatory fields are missing.
263-
if (TheRemark.RemarkType == Type::Unknown || TheRemark.PassName.empty() ||
264-
TheRemark.RemarkName.empty() || TheRemark.FunctionName.empty())
263+
if (TheRemark.RemarkType == remarks::Type::Unknown ||
264+
TheRemark.PassName.empty() || TheRemark.RemarkName.empty() ||
265+
TheRemark.FunctionName.empty())
265266
return error("Type, Pass, Name or Function missing.",
266267
*RemarkEntry.getRoot());
267268

268269
return std::move(Result);
269270
}
270271

271-
Expected<Type> YAMLRemarkParser::parseType(yaml::MappingNode &Node) {
272+
Expected<remarks::Type> YAMLRemarkParser::parseType(yaml::MappingNode &Node) {
272273
auto Type = StringSwitch<remarks::Type>(Node.getRawTag())
273274
.Case("!Passed", remarks::Type::Passed)
274275
.Case("!Missed", remarks::Type::Missed)
@@ -362,7 +363,7 @@ YAMLRemarkParser::parseDebugLoc(yaml::KeyValueNode &Node) {
362363
return RemarkLocation{*File, *Line, *Column};
363364
}
364365

365-
Expected<Argument> YAMLRemarkParser::parseArg(yaml::Node &Node) {
366+
Expected<remarks::Argument> YAMLRemarkParser::parseArg(yaml::Node &Node) {
366367
auto *ArgMap = dyn_cast<yaml::MappingNode>(&Node);
367368
if (!ArgMap)
368369
return error("expected a value of mapping type.", Node);

Diff for: llvm/lib/Remarks/YAMLRemarkSerializer.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ template <typename T>
2525
static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName,
2626
std::optional<RemarkLocation> RL, T FunctionName,
2727
std::optional<uint64_t> Hotness,
28-
ArrayRef<Argument> Args) {
28+
ArrayRef<remarks::Argument> Args) {
2929
io.mapRequired("Pass", PassName);
3030
io.mapRequired("Name", RemarkName);
3131
io.mapOptional("DebugLoc", RL);
@@ -41,19 +41,23 @@ template <> struct MappingTraits<remarks::Remark *> {
4141
static void mapping(IO &io, remarks::Remark *&Remark) {
4242
assert(io.outputting() && "input not yet implemented");
4343

44-
if (io.mapTag("!Passed", (Remark->RemarkType == Type::Passed)))
44+
if (io.mapTag("!Passed", (Remark->RemarkType == remarks::Type::Passed)))
4545
;
46-
else if (io.mapTag("!Missed", (Remark->RemarkType == Type::Missed)))
46+
else if (io.mapTag("!Missed",
47+
(Remark->RemarkType == remarks::Type::Missed)))
4748
;
48-
else if (io.mapTag("!Analysis", (Remark->RemarkType == Type::Analysis)))
49+
else if (io.mapTag("!Analysis",
50+
(Remark->RemarkType == remarks::Type::Analysis)))
4951
;
50-
else if (io.mapTag("!AnalysisFPCommute",
51-
(Remark->RemarkType == Type::AnalysisFPCommute)))
52+
else if (io.mapTag(
53+
"!AnalysisFPCommute",
54+
(Remark->RemarkType == remarks::Type::AnalysisFPCommute)))
5255
;
5356
else if (io.mapTag("!AnalysisAliasing",
54-
(Remark->RemarkType == Type::AnalysisAliasing)))
57+
(Remark->RemarkType == remarks::Type::AnalysisAliasing)))
5558
;
56-
else if (io.mapTag("!Failure", (Remark->RemarkType == Type::Failure)))
59+
else if (io.mapTag("!Failure",
60+
(Remark->RemarkType == remarks::Type::Failure)))
5761
;
5862
else
5963
llvm_unreachable("Unknown remark type");
@@ -124,16 +128,16 @@ template <> struct BlockScalarTraits<StringBlockVal> {
124128
/// Keep this in this file so that it doesn't get misused from YAMLTraits.h.
125129
template <typename T> struct SequenceTraits<ArrayRef<T>> {
126130
static size_t size(IO &io, ArrayRef<T> &seq) { return seq.size(); }
127-
static Argument &element(IO &io, ArrayRef<T> &seq, size_t index) {
131+
static remarks::Argument &element(IO &io, ArrayRef<T> &seq, size_t index) {
128132
assert(io.outputting() && "input not yet implemented");
129133
// The assert above should make this "safer" to satisfy the YAMLTraits.
130134
return const_cast<T &>(seq[index]);
131135
}
132136
};
133137

134138
/// Implement this as a mapping for now to get proper quotation for the value.
135-
template <> struct MappingTraits<Argument> {
136-
static void mapping(IO &io, Argument &A) {
139+
template <> struct MappingTraits<remarks::Argument> {
140+
static void mapping(IO &io, remarks::Argument &A) {
137141
assert(io.outputting() && "input not yet implemented");
138142

139143
if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
@@ -155,7 +159,7 @@ template <> struct MappingTraits<Argument> {
155159
} // end namespace yaml
156160
} // end namespace llvm
157161

158-
LLVM_YAML_IS_SEQUENCE_VECTOR(Argument)
162+
LLVM_YAML_IS_SEQUENCE_VECTOR(remarks::Argument)
159163

160164
YAMLRemarkSerializer::YAMLRemarkSerializer(raw_ostream &OS, SerializerMode Mode,
161165
std::optional<StringTable> StrTabIn)

0 commit comments

Comments
 (0)