forked from OSchip/llvm-project
Speed up compilation of ASTImporter
Avoid recursively instantiating importSeq. Use initializer list expansion to stamp out a single instantiation of std::tuple of the deduced sequence of types, and thread the error around that tuple type. Avoids needlessly instantiating std::tuple N-1 times. new time to compile: 0m25.985s old time to compile: 0m35.563s new obj size: 10,000kb old obj size: 12,332kb I found the slow TU by looking at ClangBuildAnalyzer results, and looked at -ftime-trace for the file in chrome://tracing to find this. Tested with: clang-cl, MSVC, and GCC. Reviewed By: martong Differential Revision: https://reviews.llvm.org/D73667
This commit is contained in:
parent
b0d25fff9b
commit
af3e884956
|
@ -186,32 +186,33 @@ namespace clang {
|
||||||
return import(*From);
|
return import(*From);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
// Helper for error management in importSeq.
|
||||||
Expected<std::tuple<T>>
|
template <typename T> T checkImport(Error &Err, const T &From) {
|
||||||
importSeq(const T &From) {
|
// Don't attempt to import nodes if we hit an error earlier.
|
||||||
Expected<T> ToOrErr = import(From);
|
if (Err)
|
||||||
if (!ToOrErr)
|
return T{};
|
||||||
return ToOrErr.takeError();
|
Expected<T> MaybeVal = import(From);
|
||||||
return std::make_tuple<T>(std::move(*ToOrErr));
|
if (!MaybeVal) {
|
||||||
|
Err = MaybeVal.takeError();
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
|
return *MaybeVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import multiple objects with a single function call.
|
// Import multiple objects with a single function call.
|
||||||
// This should work for every type for which a variant of `import` exists.
|
// This should work for every type for which a variant of `import` exists.
|
||||||
// The arguments are processed from left to right and import is stopped on
|
// The arguments are processed from left to right and import is stopped on
|
||||||
// first error.
|
// first error.
|
||||||
template <class THead, class... TTail>
|
template <class... Args>
|
||||||
Expected<std::tuple<THead, TTail...>>
|
Expected<std::tuple<Args...>> importSeq(const Args &... args) {
|
||||||
importSeq(const THead &FromHead, const TTail &...FromTail) {
|
Error E = Error::success();
|
||||||
Expected<std::tuple<THead>> ToHeadOrErr = importSeq(FromHead);
|
std::tuple<Args...> Res{checkImport(E, args)...};
|
||||||
if (!ToHeadOrErr)
|
if (E)
|
||||||
return ToHeadOrErr.takeError();
|
return std::move(E);
|
||||||
Expected<std::tuple<TTail...>> ToTailOrErr = importSeq(FromTail...);
|
return std::move(Res);
|
||||||
if (!ToTailOrErr)
|
|
||||||
return ToTailOrErr.takeError();
|
|
||||||
return std::tuple_cat(*ToHeadOrErr, *ToTailOrErr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper for an overload set.
|
// Wrapper for an overload set.
|
||||||
template <typename ToDeclT> struct CallOverloadedCreateFun {
|
template <typename ToDeclT> struct CallOverloadedCreateFun {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
auto operator()(Args &&... args)
|
auto operator()(Args &&... args)
|
||||||
|
|
Loading…
Reference in New Issue