-ftime-report switch support in Clang.
The current support of the feature produces only 2 lines in report:
 -Some general Code Generation Time;
 -Total time of Backend Consumer actions.
This patch extends Clang time report with new lines related to Preprocessor, Include Filea Search, Parsing, etc.
Differential Revision: https://reviews.llvm.org/D43578

llvm-svn: 329684
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 93a5ad4..3d90846 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -30,11 +30,13 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Pass.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Capacity.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Timer.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -199,6 +201,9 @@
 }
 
 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
+  llvm::NamedRegionTimer T("lookupmodule", "Lookup Module", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
+
   // Look in the module map to determine if there is a module by this name.
   Module *Module = ModMap.findModule(ModuleName);
   if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
@@ -223,6 +228,8 @@
 }
 
 Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName) {
+  llvm::NamedRegionTimer T("lookupmodule", "Lookup Module", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
   Module *Module = nullptr;
 
   // Look through the various header search paths to load any available module
@@ -340,6 +347,8 @@
     bool &InUserSpecifiedSystemFramework,
     bool &HasBeenMapped,
     SmallVectorImpl<char> &MappedName) const {
+  llvm::NamedRegionTimer T("lookupfile", "Lookup File", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
   InUserSpecifiedSystemFramework = false;
   HasBeenMapped = false;
 
@@ -467,6 +476,8 @@
     SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
     ModuleMap::KnownHeader *SuggestedModule,
     bool &InUserSpecifiedSystemFramework) const {
+  llvm::NamedRegionTimer T("lookupfw", "Lookup Framework", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
   FileManager &FileMgr = HS.getFileMgr();
 
   // Framework names must have a '/' in the filename.
@@ -633,6 +644,8 @@
     SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
     Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
     bool *IsMapped, bool SkipCache, bool BuildSystemModule) {
+  llvm::NamedRegionTimer T("lookupfile2", "Lookup File2", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
   if (IsMapped)
     *IsMapped = false;
 
@@ -894,6 +907,8 @@
                          Module *RequestingModule,
                          ModuleMap::KnownHeader *SuggestedModule) {
   assert(ContextFileEnt && "No context file?");
+  llvm::NamedRegionTimer T("lookupsubfm", "Lookup SubFramework", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
 
   // Framework names must have a '/' in the filename.  Find it.
   // FIXME: Should we permit '\' on Windows?
@@ -1111,6 +1126,9 @@
 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
                                           const FileEntry *File, bool isImport,
                                           bool ModulesEnabled, Module *M) {
+  llvm::NamedRegionTimer T("shouldenterinc", "Should Enter Include File",
+                           IncGroupName, IncGroupDescription,
+                           llvm::TimePassesIsEnabled);
   ++NumIncluded; // Count # of attempted #includes.
 
   // Get information about this file.
@@ -1287,6 +1305,9 @@
 bool HeaderSearch::findUsableModuleForHeader(
     const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
     ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
+  llvm::NamedRegionTimer T("findmodule4header", "Find Usable Module For Header",
+                           IncGroupName, IncGroupDescription,
+                           llvm::TimePassesIsEnabled);
   if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
     // If there is a module that corresponds to this header, suggest it.
     hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
@@ -1299,6 +1320,9 @@
     const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
     ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
   // If we're supposed to suggest a module, look for one now.
+  llvm::NamedRegionTimer T(
+      "findmodule4fwheader", "Find Usable Module For Framework Header",
+      IncGroupName, IncGroupDescription, llvm::TimePassesIsEnabled);
   if (needModuleLookup(RequestingModule, SuggestedModule)) {
     // Find the top-level framework based on this framework.
     SmallVector<std::string, 4> SubmodulePath;
@@ -1483,6 +1507,8 @@
 }
 
 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
+  llvm::NamedRegionTimer T("allmodules", "Collect All Modules", IncGroupName,
+                           IncGroupDescription, llvm::TimePassesIsEnabled);
   Modules.clear();
 
   if (HSOpts->ImplicitModuleMaps) {
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 5af8ba5..7c44cc8 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -26,9 +26,9 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PTHLexer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorLexer.h"
-#include "clang/Lex/PTHLexer.h"
 #include "clang/Lex/Token.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -36,15 +36,16 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -57,6 +58,9 @@
 
 using namespace clang;
 
+static const char *const GroupName = "clangparser";
+static const char *const GroupDescription = "===== Clang Parser =====";
+
 MacroDirective *
 Preprocessor::getLocalMacroDirectiveHistory(const IdentifierInfo *II) const {
   if (!II->hadMacroDefinition())
@@ -69,6 +73,8 @@
 void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
   assert(MD && "MacroDirective should be non-zero!");
   assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
+  llvm::NamedRegionTimer NRT("appendmacro", "PP Append Macro", GroupName,
+                             GroupDescription, llvm::TimePassesIsEnabled);
 
   MacroState &StoredMD = CurSubmoduleState->Macros[II];
   auto *OldMD = StoredMD.getLatest();
@@ -131,6 +137,8 @@
                                           MacroInfo *Macro,
                                           ArrayRef<ModuleMacro *> Overrides,
                                           bool &New) {
+  llvm::NamedRegionTimer NRT("addmodulemacro", "PP Add Module Macro", GroupName,
+                             GroupDescription, llvm::TimePassesIsEnabled);
   llvm::FoldingSetNodeID ID;
   ModuleMacro::Profile(ID, Mod, II);
 
@@ -182,6 +190,9 @@
   assert(Info.ActiveModuleMacrosGeneration !=
              CurSubmoduleState->VisibleModules.getGeneration() &&
          "don't need to update this macro name info");
+  llvm::NamedRegionTimer NRT("updatemodulemacro", "PP Update Module Macro",
+                             GroupName, GroupDescription,
+                             llvm::TimePassesIsEnabled);
   Info.ActiveModuleMacrosGeneration =
       CurSubmoduleState->VisibleModules.getGeneration();
 
@@ -754,6 +765,8 @@
 MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
                                                    MacroInfo *MI,
                                                    SourceLocation &MacroEnd) {
+  llvm::NamedRegionTimer NRT("ppmacrocall", "PP Macro Call Args", GroupName,
+                             GroupDescription, llvm::TimePassesIsEnabled);
   // The number of fixed arguments to parse.
   unsigned NumFixedArgsLeft = MI->getNumParams();
   bool isVariadic = MI->isVariadic();
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index db32e45..a1944e3 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -39,11 +39,13 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Pass.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Timer.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -54,6 +56,8 @@
 #include <vector>
 
 using namespace clang;
+static const char *const GroupName = "clangparser";
+static const char *const GroupDescription = "===== Clang Parser =====";
 
 // Out-of-line destructor to provide a home for the class.
 PragmaHandler::~PragmaHandler() = default;
@@ -82,6 +86,8 @@
 /// the null handler isn't returned on failure to match.
 PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
                                             bool IgnoreNull) const {
+  llvm::NamedRegionTimer NRT("ppfindhandler", "PP Find Handler", GroupName,
+                             GroupDescription, llvm::TimePassesIsEnabled);
   if (PragmaHandler *Handler = Handlers.lookup(Name))
     return Handler;
   return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
@@ -128,6 +134,8 @@
 /// rest of the pragma, passing it to the registered pragma handlers.
 void Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
                                          PragmaIntroducerKind Introducer) {
+  llvm::NamedRegionTimer NRT("pppragma", "Handle Pragma Directive", GroupName,
+                             GroupDescription, llvm::TimePassesIsEnabled);
   if (Callbacks)
     Callbacks->PragmaDirective(IntroducerLoc, Introducer);