arphaman created this revision.
arphaman added a reviewer: jkorous.
Herald added subscribers: ributzka, dexonsmith.
Herald added a project: clang.

[clang][Preprocessor] Replace the slow translateFile call by a new, faster 
isMainFile check

  
  The commit 3c28a2dc6bdc331e5a0d8097a5fa59d06682b9d0 introduced the check that 
checks if we're
  trying to re-enter a main file when building a preamble. Unfortunately this 
slowed down the preamble
  compilation by 80-90% in some test cases, as translateFile is really slow. 
This change checks
  to see if the FileEntry is the main file without calling translateFile, but 
by using the new
  isMainFile check instead. This speeds up preamble building by 1.5-2x for 
certain test cases that we have.
  
  rdar://59361291


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79834

Files:
  clang/include/clang/Basic/SourceManager.h
  clang/lib/Basic/SourceManager.cpp
  clang/lib/Lex/PPDirectives.cpp


Index: clang/lib/Lex/PPDirectives.cpp
===================================================================
--- clang/lib/Lex/PPDirectives.cpp
+++ clang/lib/Lex/PPDirectives.cpp
@@ -2054,8 +2054,7 @@
   // some directives (e.g. #endif of a header guard) will never be seen.
   // Since this will lead to confusing errors, avoid the inclusion.
   if (Action == Enter && File && PreambleConditionalStack.isRecording() &&
-      SourceMgr.translateFile(&File->getFileEntry()) ==
-          SourceMgr.getMainFileID()) {
+      SourceMgr.isMainFile(*File)) {
     Diag(FilenameTok.getLocation(),
          diag::err_pp_including_mainfile_in_preamble);
     return {ImportAction::None};
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -373,6 +373,7 @@
 
 void SourceManager::clearIDTables() {
   MainFileID = FileID();
+  CachedMainFileEntry = None;
   LocalSLocEntryTable.clear();
   LoadedSLocEntryTable.clear();
   SLocEntryLoaded.clear();
@@ -389,6 +390,15 @@
   createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1);
 }
 
+bool SourceManager::isMainFile(FileEntryRef SourceFile) {
+  assert(MainFileID.isValid() && "expected initialized SourceManager");
+  if (!CachedMainFileEntry) {
+    CachedMainFileEntry = getFileEntryRefForID(MainFileID);
+    assert(CachedMainFileEntry && "missing file entry for main file");
+  }
+  return CachedMainFileEntry->getUID() == SourceFile.getUID();
+}
+
 void SourceManager::initializeForReplay(const SourceManager &Old) {
   assert(MainFileID.isInvalid() && "expected uninitialized SourceManager");
 
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -35,6 +35,7 @@
 #define LLVM_CLANG_BASIC_SOURCEMANAGER_H
 
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
@@ -59,9 +60,6 @@
 
 class ASTReader;
 class ASTWriter;
-class FileManager;
-class FileEntry;
-class FileEntryRef;
 class LineTableInfo;
 class SourceManager;
 
@@ -706,6 +704,9 @@
   /// The file ID for the main source file of the translation unit.
   FileID MainFileID;
 
+  /// The file entry for the main source file.
+  Optional<FileEntryRef> CachedMainFileEntry;
+
   /// The file ID for the precompiled preamble there is one.
   FileID PreambleFileID;
 
@@ -813,6 +814,9 @@
     MainFileID = FID;
   }
 
+  /// Returns true when the given FileEntry corresponds to the main file.
+  bool isMainFile(FileEntryRef SourceFile);
+
   /// Set the file ID for the precompiled preamble.
   void setPreambleFileID(FileID Preamble) {
     assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");


Index: clang/lib/Lex/PPDirectives.cpp
===================================================================
--- clang/lib/Lex/PPDirectives.cpp
+++ clang/lib/Lex/PPDirectives.cpp
@@ -2054,8 +2054,7 @@
   // some directives (e.g. #endif of a header guard) will never be seen.
   // Since this will lead to confusing errors, avoid the inclusion.
   if (Action == Enter && File && PreambleConditionalStack.isRecording() &&
-      SourceMgr.translateFile(&File->getFileEntry()) ==
-          SourceMgr.getMainFileID()) {
+      SourceMgr.isMainFile(*File)) {
     Diag(FilenameTok.getLocation(),
          diag::err_pp_including_mainfile_in_preamble);
     return {ImportAction::None};
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -373,6 +373,7 @@
 
 void SourceManager::clearIDTables() {
   MainFileID = FileID();
+  CachedMainFileEntry = None;
   LocalSLocEntryTable.clear();
   LoadedSLocEntryTable.clear();
   SLocEntryLoaded.clear();
@@ -389,6 +390,15 @@
   createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1);
 }
 
+bool SourceManager::isMainFile(FileEntryRef SourceFile) {
+  assert(MainFileID.isValid() && "expected initialized SourceManager");
+  if (!CachedMainFileEntry) {
+    CachedMainFileEntry = getFileEntryRefForID(MainFileID);
+    assert(CachedMainFileEntry && "missing file entry for main file");
+  }
+  return CachedMainFileEntry->getUID() == SourceFile.getUID();
+}
+
 void SourceManager::initializeForReplay(const SourceManager &Old) {
   assert(MainFileID.isInvalid() && "expected uninitialized SourceManager");
 
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -35,6 +35,7 @@
 #define LLVM_CLANG_BASIC_SOURCEMANAGER_H
 
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
@@ -59,9 +60,6 @@
 
 class ASTReader;
 class ASTWriter;
-class FileManager;
-class FileEntry;
-class FileEntryRef;
 class LineTableInfo;
 class SourceManager;
 
@@ -706,6 +704,9 @@
   /// The file ID for the main source file of the translation unit.
   FileID MainFileID;
 
+  /// The file entry for the main source file.
+  Optional<FileEntryRef> CachedMainFileEntry;
+
   /// The file ID for the precompiled preamble there is one.
   FileID PreambleFileID;
 
@@ -813,6 +814,9 @@
     MainFileID = FID;
   }
 
+  /// Returns true when the given FileEntry corresponds to the main file.
+  bool isMainFile(FileEntryRef SourceFile);
+
   /// Set the file ID for the precompiled preamble.
   void setPreambleFileID(FileID Preamble) {
     assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to