[lld] [lld][Macho]Multi-threaded disk i/o. 20% speedup linking a large project. (PR #147134)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 5 01:51:01 PDT 2025


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- lld/MachO/Config.h lld/MachO/Driver.cpp
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index a244f2781..afe4eae4e 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -44,10 +44,10 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Parallel.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TimeProfiler.h"
-#include "llvm/Support/Process.h"
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TextAPI/Architecture.h"
 #include "llvm/TextAPI/PackedVersion.h"
@@ -446,8 +446,8 @@ static InputFile *addFile(StringRef path, LoadType loadType,
                           bool isLazy = false, bool isExplicit = true,
                           bool isBundleLoader = false,
                           bool isForceHidden = false) {
-    return deferredAddFile(readFile(path), path, loadType, isLazy,
-                           isExplicit, isBundleLoader, isForceHidden);
+  return deferredAddFile(readFile(path), path, loadType, isLazy, isExplicit,
+                         isBundleLoader, isForceHidden);
 }
 
 static std::vector<StringRef> missingAutolinkWarnings;
@@ -573,10 +573,14 @@ void macho::resolveLCLinkerOptions() {
   }
 }
 
-typedef struct { StringRef path; std::optional<MemoryBufferRef> buffer; } DeferredFile;
+typedef struct {
+  StringRef path;
+  std::optional<MemoryBufferRef> buffer;
+} DeferredFile;
 
 static void addFileList(StringRef path, bool isLazy,
-  std::vector<DeferredFile> &deferredFiles, int readThreads) {
+                        std::vector<DeferredFile> &deferredFiles,
+                        int readThreads) {
   std::optional<MemoryBufferRef> buffer = readFile(path);
   if (!buffer)
     return;
@@ -585,8 +589,7 @@ static void addFileList(StringRef path, bool isLazy,
     if (readThreads) {
       StringRef rrpath = rerootPath(path);
       deferredFiles.push_back({rrpath, readFile(rrpath)});
-    }
-    else
+    } else
       addFile(rerootPath(path), LoadType::CommandLine, isLazy);
 }
 
@@ -1236,46 +1239,51 @@ static void handleSymbolPatterns(InputArgList &args,
 // This code forces the page-ins on multiple threads so
 // the process is not stalled waiting on disk buffer i/o.
 void multiThreadedPageIn(std::vector<DeferredFile> &deferred, int nthreads) {
-    typedef struct {
-        std::vector<DeferredFile> &deferred;
-        size_t counter, total, pageSize;
-        pthread_mutex_t mutex;
-    } PageInState;
-    PageInState state = {deferred, 0, 0,
-        llvm::sys::Process::getPageSizeEstimate(), pthread_mutex_t()};
-    pthread_mutex_init(&state.mutex, NULL);
-
-    pthread_t running[200];
-    int maxthreads = sizeof running / sizeof running[0];
-    if (nthreads > maxthreads)
-        nthreads = maxthreads;
-    for (int t=0; t<nthreads; t++)
-        pthread_create(&running[t], nullptr, [](void* ptr) -> void*{
-            PageInState &state = *(PageInState *)ptr;
-            static int total = 0;
-            while (true) {
-                pthread_mutex_lock(&state.mutex);
-                if (state.counter >= state.deferred.size()) {
-                    pthread_mutex_unlock(&state.mutex);
-                    return nullptr;
-                }
-                DeferredFile &add = state.deferred[state.counter];
-                state.counter += 1;
-                pthread_mutex_unlock(&state.mutex);
-
-                int t = 0; // Reference each page to load it into memory.
-                for (const char *start = add.buffer->getBuffer().data(),
-                     *page = start; page<start+add.buffer->getBuffer().size();
-                     page += state.pageSize)
-                    t += *page;
-                state.total += t; // Avoids whole section being optimised out.
+  typedef struct {
+    std::vector<DeferredFile> &deferred;
+    size_t counter, total, pageSize;
+    pthread_mutex_t mutex;
+  } PageInState;
+  PageInState state = {deferred, 0, 0,
+                       llvm::sys::Process::getPageSizeEstimate(),
+                       pthread_mutex_t()};
+  pthread_mutex_init(&state.mutex, NULL);
+
+  pthread_t running[200];
+  int maxthreads = sizeof running / sizeof running[0];
+  if (nthreads > maxthreads)
+    nthreads = maxthreads;
+  for (int t = 0; t < nthreads; t++)
+    pthread_create(
+        &running[t], nullptr,
+        [](void *ptr) -> void * {
+          PageInState &state = *(PageInState *)ptr;
+          static int total = 0;
+          while (true) {
+            pthread_mutex_lock(&state.mutex);
+            if (state.counter >= state.deferred.size()) {
+              pthread_mutex_unlock(&state.mutex);
+              return nullptr;
             }
-        }, &state);
+            DeferredFile &add = state.deferred[state.counter];
+            state.counter += 1;
+            pthread_mutex_unlock(&state.mutex);
+
+            int t = 0; // Reference each page to load it into memory.
+            for (const char *start = add.buffer->getBuffer().data(),
+                            *page = start;
+                 page < start + add.buffer->getBuffer().size();
+                 page += state.pageSize)
+              t += *page;
+            state.total += t; // Avoids whole section being optimised out.
+          }
+        },
+        &state);
 
-    for (int t=0; t<nthreads; t++)
-        pthread_join(running[t], nullptr);
+  for (int t = 0; t < nthreads; t++)
+    pthread_join(running[t], nullptr);
 
-    pthread_mutex_destroy(&state.mutex);
+  pthread_mutex_destroy(&state.mutex);
 }
 
 void createFiles(const InputArgList &args, int readThreads) {
@@ -1296,7 +1304,7 @@ void createFiles(const InputArgList &args, int readThreads) {
     case OPT_INPUT:
       if (readThreads) {
         StringRef rrpath = rerootPath(arg->getValue());
-        deferredFiles.push_back({rrpath,readFile(rrpath)});
+        deferredFiles.push_back({rrpath, readFile(rrpath)});
         break;
       }
       addFile(rerootPath(arg->getValue()), LoadType::CommandLine, isLazy);

``````````

</details>


https://github.com/llvm/llvm-project/pull/147134


More information about the llvm-commits mailing list