PTH: Cache stat information for files in the PTH file.  Hook up FileManager
 to use this stat information in the PTH file using a 'StatSysCallCache' object.

Performance impact (Cocoa.h, PTH):
- number of stat calls reduces from 1230 to 425
- fsyntax-only: time improves by 4.2% 

We can reduce the number of stat calls to almost zero by caching negative stat
calls and directory stat calls in the PTH file as well.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64353 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/CacheTokens.cpp b/Driver/CacheTokens.cpp
index 6b9f96e..52ce082 100644
--- a/Driver/CacheTokens.cpp
+++ b/Driver/CacheTokens.cpp
@@ -47,6 +47,17 @@
   Out << (unsigned char)(V >> 24);
 }
 
+static void Emit64(llvm::raw_ostream& Out, uint64_t V) {
+  Out << (unsigned char)(V);
+  Out << (unsigned char)(V >>  8);
+  Out << (unsigned char)(V >> 16);
+  Out << (unsigned char)(V >> 24);
+  Out << (unsigned char)(V >> 32);
+  Out << (unsigned char)(V >> 40);
+  Out << (unsigned char)(V >> 48);
+  Out << (unsigned char)(V >> 56);
+}
+
 static void Pad(llvm::raw_fd_ostream& Out, unsigned A) {
   Offset off = (Offset) Out.tell();
   uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off;
@@ -149,7 +160,7 @@
         const std::pair<unsigned, unsigned>& Len = 
           Info::EmitKeyDataLength(out, I->key, I->data);
         Info::EmitKey(out, I->key, Len.first);
-        Info::EmitData(out, I->data, Len.second);
+        Info::EmitData(out, I->key, I->data, Len.second);
       }
     }
     
@@ -212,16 +223,23 @@
 
     unsigned n = strlen(FE->getName()) + 1;
     ::Emit16(Out, n);
-    return std::make_pair(n, 8);
+    return std::make_pair(n,(4*2)+(4+4+2+8+8));
   }
   
   static void EmitKey(llvm::raw_ostream& Out, const FileEntry* FE, unsigned n) {
     Out.write(FE->getName(), n);
   }
   
-  static void EmitData(llvm::raw_ostream& Out, const PCHEntry& E, unsigned) {
+  static void EmitData(llvm::raw_ostream& Out, const FileEntry* FE, 
+                       const PCHEntry& E, unsigned) {
     ::Emit32(Out, E.getTokenOffset());
     ::Emit32(Out, E.getPPCondTableOffset());
+    // Emit stat information.
+    ::Emit32(Out, FE->getInode());
+    ::Emit32(Out, FE->getDevice());
+    ::Emit16(Out, FE->getFileMode());
+    ::Emit64(Out, FE->getModificationTime());
+    ::Emit64(Out, FE->getSize());
   }        
 };
   
@@ -537,8 +555,6 @@
     if (!P.isAbsolute())
       continue;
 
-    // assert(!PM.count(FE) && "fileinfo's are not uniqued on FileEntry?");
-    
     const llvm::MemoryBuffer *B = C.getBuffer();
     if (!B) continue;
 
@@ -620,7 +636,8 @@
     Out.write(key->II->getName(), n);
   }
   
-  static void EmitData(llvm::raw_ostream& Out, uint32_t pID, unsigned) {
+  static void EmitData(llvm::raw_ostream& Out, PCHIdKey*, uint32_t pID,
+                       unsigned) {
     ::Emit32(Out, pID);
   }        
 };