]> granicus.if.org Git - clang/commitdiff
Add some timers to ASTUnit that are only enabled when the LIBCLANG_TIMING environment...
authorDouglas Gregor <dgregor@apple.com>
Fri, 30 Jul 2010 20:58:08 +0000 (20:58 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 30 Jul 2010 20:58:08 +0000 (20:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109890 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTUnit.h
lib/Frontend/ASTUnit.cpp

index 10cf3d50ba5290e73cbb0ea9707e365a84706107..56e73d9be4b50b881894611857d1c7ae5ebb721f 100644 (file)
@@ -22,6 +22,7 @@
 #include "clang/Index/ASTLocation.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/System/Path.h"
+#include "llvm/Support/Timer.h"
 #include <map>
 #include <string>
 #include <vector>
@@ -119,7 +120,7 @@ private:
   static const unsigned int CheckUnlocked = 9803453;
 
   /// \brief The file in which the precompiled preamble is stored.
-  llvm::sys::Path PreambleFile;
+  std::string PreambleFile;
   
   /// \brief The contents of the preamble that has been precompiled to
   /// \c PreambleFile.
@@ -140,6 +141,13 @@ private:
   /// preamble.
   llvm::MemoryBuffer *SavedMainFileBuffer;
   
+  /// \brief The group of timers associated with this translation unit.
+  llvm::OwningPtr<llvm::TimerGroup> TimerGroup;
+  
+  /// \brief The timers we've created from the various parses, reparses, etc.
+  /// involved in this translation unit.
+  std::vector<llvm::Timer *> Timers;
+  
   ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
   ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
   
index a035cd89f60b15b720f73bd7ba146cc68daf7bb7..7f42fa949e5bb2a3ef7e5a1b168685f441fa39d2 100644 (file)
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/System/Host.h"
 #include "llvm/System/Path.h"
+#include "llvm/Support/Timer.h"
 #include <cstdlib>
 #include <cstdio>
 using namespace clang;
 
 ASTUnit::ASTUnit(bool _MainFileIsAST)
   : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), 
-    ConcurrencyCheckValue(CheckUnlocked), SavedMainFileBuffer(0) { }
+    ConcurrencyCheckValue(CheckUnlocked), SavedMainFileBuffer(0) { 
+}
 
 ASTUnit::~ASTUnit() {
   ConcurrencyCheckValue = CheckLocked;
   CleanTemporaryFiles();
   if (!PreambleFile.empty())
-    PreambleFile.eraseFromDisk();
+    llvm::sys::Path(PreambleFile).eraseFromDisk();
   
   // Free the buffers associated with remapped files. We are required to
   // perform this operation here because we explicitly request that the
@@ -62,6 +64,9 @@ ASTUnit::~ASTUnit() {
   }
   
   delete SavedMainFileBuffer;
+  
+  for (unsigned I = 0, N = Timers.size(); I != N; ++I)
+    delete Timers[I];
 }
 
 void ASTUnit::CleanTemporaryFiles() {
@@ -398,7 +403,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
     PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
     PreprocessorOpts.PrecompiledPreambleBytes.second
                                                     = PreambleEndsAtStartOfLine;
-    PreprocessorOpts.ImplicitPCHInclude = PreambleFile.str();
+    PreprocessorOpts.ImplicitPCHInclude = PreambleFile;
     PreprocessorOpts.DisablePCHValidation = true;
     
     // Keep track of the override buffer;
@@ -600,7 +605,7 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
     // preamble, if we have one. It's obviously no good any more.
     Preamble.clear();
     if (!PreambleFile.empty()) {
-      PreambleFile.eraseFromDisk();
+      llvm::sys::Path(PreambleFile).eraseFromDisk();
       PreambleFile.clear();
     }
     if (CreatedPreambleBuffer)
@@ -633,10 +638,16 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
     
     // We can't reuse the previously-computed preamble. Build a new one.
     Preamble.clear();
-    PreambleFile.eraseFromDisk();
+    llvm::sys::Path(PreambleFile).eraseFromDisk();
   } 
     
   // We did not previously compute a preamble, or it can't be reused anyway.
+  llvm::Timer *PreambleTimer = 0;
+  if (TimerGroup.get()) {
+    PreambleTimer = new llvm::Timer("Precompiling preamble", *TimerGroup);
+    PreambleTimer->startTimer();
+    Timers.push_back(PreambleTimer);
+  }
   
   // Create a new buffer that stores the preamble. The buffer also contains
   // extra space for the original contents of the file (which will be present
@@ -672,10 +683,7 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
   FrontendOpts.ProgramAction = frontend::GeneratePCH;
   // FIXME: Set ChainedPCH, once it is ready.
   // FIXME: Generate the precompiled header into memory?
-  if (PreambleFile.isEmpty())
-    FrontendOpts.OutputFile = GetPreamblePCHPath();
-  else
-    FrontendOpts.OutputFile = PreambleFile.str();
+  FrontendOpts.OutputFile = GetPreamblePCHPath();
   
   // Create the compiler instance to use for building the precompiled preamble.
   CompilerInstance Clang;
@@ -695,6 +703,8 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
     Preamble.clear();
     if (CreatedPreambleBuffer)
       delete NewPreamble.first;
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
 
     return 0;
   }
@@ -737,7 +747,9 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
     Preamble.clear();
     if (CreatedPreambleBuffer)
       delete NewPreamble.first;
-    
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+
     return 0;
   }
   
@@ -754,13 +766,19 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
     Preamble.clear();
     if (CreatedPreambleBuffer)
       delete NewPreamble.first;
-    
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+    if (PreambleTimer)
+      PreambleTimer->stopTimer();
+
     return 0;
   }
   
   // Keep track of the preamble we precompiled.
   PreambleFile = FrontendOpts.OutputFile;
-  fprintf(stderr, "Preamble PCH: %s\n", FrontendOpts.OutputFile.c_str());
+  if (PreambleTimer)
+    PreambleTimer->stopTimer();
+  
   return CreatePaddedMainFileBuffer(NewPreamble.first, 
                                     CreatedPreambleBuffer,
                                     PreambleReservedSize,
@@ -788,15 +806,28 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
   AST->Invocation.reset(CI);
   CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
   
+  if (getenv("LIBCLANG_TIMING"))
+    AST->TimerGroup.reset(
+                  new llvm::TimerGroup(CI->getFrontendOpts().Inputs[0].second));
+  
+  
   llvm::MemoryBuffer *OverrideMainBuffer = 0;
   // FIXME: When C++ PCH is ready, allow use of it for a precompiled preamble.
   if (PrecompilePreamble && !CI->getLangOpts().CPlusPlus)
     OverrideMainBuffer = AST->BuildPrecompiledPreamble();
   
-  if (!AST->Parse(OverrideMainBuffer))
-    return AST.take();
+  llvm::Timer *ParsingTimer = 0;
+  if (AST->TimerGroup.get()) {
+    ParsingTimer = new llvm::Timer("Initial parse", *AST->TimerGroup);
+    ParsingTimer->startTimer();
+    AST->Timers.push_back(ParsingTimer);
+  }
   
-  return 0;
+  bool Failed = AST->Parse(OverrideMainBuffer);
+  if (ParsingTimer)
+    ParsingTimer->stopTimer();
+  
+  return Failed? 0 : AST.take();
 }
 
 ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
@@ -875,6 +906,13 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
   if (!Invocation.get())
     return true;
   
+  llvm::Timer *ReparsingTimer = 0;
+  if (TimerGroup.get()) {
+    ReparsingTimer = new llvm::Timer("Reparse", *TimerGroup);
+    ReparsingTimer->startTimer();
+    Timers.push_back(ReparsingTimer);
+  }
+  
   // If we have a preamble file lying around, build or reuse the precompiled
   // preamble.
   llvm::MemoryBuffer *OverrideMainBuffer = 0;
@@ -892,5 +930,7 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
 
   // Parse the sources
   bool Result = Parse(OverrideMainBuffer);  
+  if (ReparsingTimer)
+    ReparsingTimer->stopTimer();
   return Result;
 }