The final result of all this refactoring: instead of doing stat immediately
followed by an open for every source file we open, probe the file system with
'open' and then do an fstat when it succeeds.  open+fstat is faster than
stat+open because the kernel only has to perform the string->inode mapping
once.  Presumably it gets faster the deeper in your filesystem a lookup
happens.

For -Eonly on cocoa.h, this reduces system time from 0.042s to 0.039s on
my machine, a 7.7% speedup.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120066 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index 00c449e..a80fae7 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -400,11 +400,24 @@
 
 llvm::MemoryBuffer *FileManager::
 getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) {
-  llvm::StringRef Filename = Entry->getName();
-  if (FileSystemOpts.WorkingDir.empty())
+  if (FileSystemOpts.WorkingDir.empty()) {
+    const char *Filename = Entry->getName();
+    // If the file is already open, use the open file descriptor.
+    if (Entry->FD != -1) {
+      llvm::MemoryBuffer *Buf =
+        llvm::MemoryBuffer::getOpenFile(Entry->FD, Filename, ErrorStr,
+                                        Entry->getSize());
+      // getOpenFile will have closed the file descriptor, don't reuse or
+      // reclose it.
+      Entry->FD = -1;
+      return Buf;
+    }
+
+    // Otherwise, open the file.
     return llvm::MemoryBuffer::getFile(Filename, ErrorStr, Entry->getSize());
+  }
   
-  llvm::sys::Path FilePath(Filename);
+  llvm::sys::Path FilePath(Entry->getName());
   FixupRelativePath(FilePath, FileSystemOpts);
   return llvm::MemoryBuffer::getFile(FilePath.c_str(), ErrorStr,
                                      Entry->getSize());