[clang] 29e2a4e - [clang] Unconditionally add autolink hints for frameworks.

Juergen Ributzka via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 16 15:31:38 PDT 2023


Author: Juergen Ributzka
Date: 2023-03-16T15:31:17-07:00
New Revision: 29e2a4eff8f62d12754f31f90d70e9a346bc2075

URL: https://github.com/llvm/llvm-project/commit/29e2a4eff8f62d12754f31f90d70e9a346bc2075
DIFF: https://github.com/llvm/llvm-project/commit/29e2a4eff8f62d12754f31f90d70e9a346bc2075.diff

LOG: [clang] Unconditionally add autolink hints for frameworks.

Clang infers framework autolink hints when parsing a modulemap. In order to do
so, it checks if the module is a framework and if there is a framework binary
or TBD file in the SDK. Only when Clang finds the filei, then the autolink hint
is added to the module metadata.

During a project build many clang processes perform this check, which causes
many stat calls - even for modules/frameworks that are not even used.

The linker is already resilient to non-existing framework links that come from
the autolink metadata, so there is no need for Clang to do this check.

Instead the autolink hints are now added unconditionally and the linker only
needs to do the check once. This reduces the overall number of stat calls.

This fixes rdar://106578342.

Differential Revision: https://reviews.llvm.org/D146255

Added: 
    

Modified: 
    clang/lib/Lex/ModuleMap.cpp
    clang/test/Modules/use-exportas-for-link.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 5973b4ae06240..8dead93b03734 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -930,27 +930,13 @@ Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
 
 /// For a framework module, infer the framework against which we
 /// should link.
-static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
-                               FileManager &FileMgr) {
+static void inferFrameworkLink(Module *Mod) {
   assert(Mod->IsFramework && "Can only infer linking for framework modules");
   assert(!Mod->isSubFramework() &&
          "Can only infer linking for top-level frameworks");
 
-  SmallString<128> LibName;
-  LibName += FrameworkDir->getName();
-  llvm::sys::path::append(LibName, Mod->Name);
-
-  // The library name of a framework has more than one possible extension since
-  // the introduction of the text-based dynamic library format. We need to check
-  // for both before we give up.
-  for (const char *extension : {"", ".tbd"}) {
-    llvm::sys::path::replace_extension(LibName, extension);
-    if (FileMgr.getFile(LibName)) {
-      Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
-                                                       /*IsFramework=*/true));
-      return;
-    }
-  }
+  Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
+                                                   /*IsFramework=*/true));
 }
 
 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
@@ -1129,9 +1115,8 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
 
   // If the module is a top-level framework, automatically link against the
   // framework.
-  if (!Result->isSubFramework()) {
-    inferFrameworkLink(Result, FrameworkDir, FileMgr);
-  }
+  if (!Result->isSubFramework())
+    inferFrameworkLink(Result);
 
   return Result;
 }
@@ -2185,9 +2170,8 @@ void ModuleMapParser::parseModuleDecl() {
   // If the active module is a top-level framework, and there are no link
   // libraries, automatically link against the framework.
   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
-      ActiveModule->LinkLibraries.empty()) {
-    inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
-  }
+      ActiveModule->LinkLibraries.empty())
+    inferFrameworkLink(ActiveModule);
 
   // If the module meets all requirements but is still unavailable, mark the
   // whole tree as unavailable to prevent it from building.

diff  --git a/clang/test/Modules/use-exportas-for-link.m b/clang/test/Modules/use-exportas-for-link.m
index 6f5fd596b4e69..722c65c2973a7 100644
--- a/clang/test/Modules/use-exportas-for-link.m
+++ b/clang/test/Modules/use-exportas-for-link.m
@@ -31,15 +31,17 @@
 #endif
 
 // RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DE -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_E %s
-// CHECK_E: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
-// CHECK_E: ![[MODULE]] = !{!"-framework", !"SomeKitCore"}
+// CHECK_E: !llvm.linker.options = !{![[MODULE1:[0-9]+]], ![[MODULE2:[0-9]+]]}
+// CHECK_E: ![[MODULE1]] = !{!"-framework", !"OtherKit"}
+// CHECK_E: ![[MODULE2]] = !{!"-framework", !"SomeKitCore"}
 #ifdef E
 @import OtherKit;
 #endif
 
 // RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DF -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_F %s
-// CHECK_F: !llvm.linker.options = !{![[MODULE:[0-9]+]]}
-// CHECK_F: ![[MODULE]] = !{!"-framework", !"SomeKit"}
+// CHECK_F: !llvm.linker.options = !{![[MODULE1:[0-9]+]], ![[MODULE2:[0-9]+]]}
+// CHECK_F: ![[MODULE1]] = !{!"-framework", !"OtherKit"}
+// CHECK_F: ![[MODULE2]] = !{!"-framework", !"SomeKit"}
 #ifdef F
 @import OtherKit;
 #endif


        


More information about the cfe-commits mailing list