Index: include/clang/Lex/Preprocessor.h =================================================================== --- include/clang/Lex/Preprocessor.h +++ include/clang/Lex/Preprocessor.h @@ -33,6 +33,7 @@ #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Registry.h" +#include "llvm/Support/Timer.h" #include #include @@ -624,6 +625,9 @@ unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste; unsigned NumSkipped; + // A timer to keep track of how much time was spent on preprocessing. + llvm::Timer PreprocessingTimer; + /// \brief The predefined macros that preprocessor should use from the /// command line etc. std::string Predefines; Index: include/clang/Lex/PreprocessorOptions.h =================================================================== --- include/clang/Lex/PreprocessorOptions.h +++ include/clang/Lex/PreprocessorOptions.h @@ -127,7 +127,11 @@ /// manipulation of the compiler invocation object, in cases where the /// compiler invocation and its buffers will be reused. bool RetainRemappedFileBuffers; - + + /// \brief Whether to measure the amount of time spent in code related to + /// preprocessing. This flag defaults to false. + bool ShowTimers; + /// \brief The Objective-C++ ARC standard library that we should support, /// by providing appropriate definitions to retrofit the standard library /// with support for lifetime-qualified pointers. @@ -164,6 +168,7 @@ GeneratePreamble(false), RemappedFilesKeepOriginalName(true), RetainRemappedFileBuffers(false), + ShowTimers(false), ObjCXXARCStandardLibrary(ARCXX_nolib) { } void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); } Index: lib/Frontend/CompilerInstance.cpp =================================================================== --- lib/Frontend/CompilerInstance.cpp +++ lib/Frontend/CompilerInstance.cpp @@ -367,7 +367,9 @@ // Preprocessor void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { - const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + PreprocessorOptions &PPOpts = getPreprocessorOpts(); + if (getFrontendOpts().ShowTimers) + PPOpts.ShowTimers = true; // Create a PTH manager if we are using some form of a token cache. PTHManager *PTHMgr = nullptr; Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -871,6 +871,8 @@ /// lexer/preprocessor state, and advances the lexer(s) so that the next token /// read is the correct one. void Preprocessor::HandleDirective(Token &Result) { + llvm::TimeRegion(PPOpts->ShowTimers ? &PreprocessingTimer : nullptr); + // FIXME: Traditional: # with whitespace before it not recognized by K&R? // We just parsed a # character at the start of a line, so we're in directive Index: lib/Lex/Preprocessor.cpp =================================================================== --- lib/Lex/Preprocessor.cpp +++ lib/Lex/Preprocessor.cpp @@ -88,6 +88,7 @@ CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurLexerSubmodule(nullptr), Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr), + PreprocessingTimer("preprocessor", "Preprocessing"), Record(nullptr), MIChainHead(nullptr) { OwnsHeaderSearch = OwnsHeaders; @@ -656,6 +657,8 @@ IdentifierInfo &II = *Identifier.getIdentifierInfo(); + llvm::TimeRegion(PPOpts->ShowTimers ? &PreprocessingTimer : nullptr); + // If the information about this identifier is out of date, update it from // the external source. // We have to treat __VA_ARGS__ in a special way, since it gets