[lld] 4bcaafe - [lld-macho] Add more TimeTraceScopes

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 25 11:51:57 PDT 2021


Author: Jez Ng
Date: 2021-03-25T14:51:31-04:00
New Revision: 4bcaafeb0e82ca268d9038e106339d4d92e98eec

URL: https://github.com/llvm/llvm-project/commit/4bcaafeb0e82ca268d9038e106339d4d92e98eec
DIFF: https://github.com/llvm/llvm-project/commit/4bcaafeb0e82ca268d9038e106339d4d92e98eec.diff

LOG: [lld-macho] Add more TimeTraceScopes

I added just enough to allow us to see a top-level breakdown of time taken. This
is the result of loading the time-trace output into `chrome:://tracing`:

https://gist.githubusercontent.com/int3/236c723cbb4b6fa3b2d340bb6395c797/raw/ef5e8234f3fdf609bf93b50f54f4e0d9bd439403/tracing.png

Reviewed By: oontvoo

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

Added: 
    

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/MapFile.cpp
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 611440185837..60c20a3f79f9 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -85,7 +85,7 @@ struct Configuration {
   uint32_t headerPad;
   uint32_t dylibCompatibilityVersion = 0;
   uint32_t dylibCurrentVersion = 0;
-  uint32_t timeTraceGranularity;
+  uint32_t timeTraceGranularity = 0;
   std::string progName;
   llvm::StringRef installName;
   llvm::StringRef mapFile;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 392adeffabb0..57ff369956c2 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -496,6 +496,7 @@ static void initLLVM() {
 }
 
 static void compileBitcodeFiles() {
+  TimeTraceScope timeScope("LTO");
   auto *lto = make<BitcodeCompiler>();
   for (InputFile *file : inputFiles)
     if (auto *bitcodeFile = dyn_cast<BitcodeFile>(file))
@@ -510,6 +511,7 @@ static void compileBitcodeFiles() {
 // all InputFiles have been loaded.) As a result, later operations won't see
 // any CommonSymbols.
 static void replaceCommonSymbols() {
+  TimeTraceScope timeScope("Replace common symbols");
   for (macho::Symbol *sym : symtab->getSymbols()) {
     auto *common = dyn_cast<CommonSymbol>(sym);
     if (common == nullptr)
@@ -772,6 +774,44 @@ static void handleSymbolPatterns(InputArgList &args,
   }
 }
 
+void createFiles(const InputArgList &args) {
+  TimeTraceScope timeScope("Load input files");
+  // This loop should be reserved for options whose exact ordering matters.
+  // Other options should be handled via filtered() and/or getLastArg().
+  for (const Arg *arg : args) {
+    const Option &opt = arg->getOption();
+    warnIfDeprecatedOption(opt);
+    warnIfUnimplementedOption(opt);
+
+    switch (opt.getID()) {
+    case OPT_INPUT:
+      addFile(arg->getValue(), false);
+      break;
+    case OPT_weak_library:
+      if (auto *dylibFile =
+              dyn_cast_or_null<DylibFile>(addFile(arg->getValue(), false)))
+        dylibFile->forceWeakImport = true;
+      break;
+    case OPT_filelist:
+      addFileList(arg->getValue());
+      break;
+    case OPT_force_load:
+      addFile(arg->getValue(), true);
+      break;
+    case OPT_l:
+    case OPT_weak_l:
+      addLibrary(arg->getValue(), opt.getID() == OPT_weak_l);
+      break;
+    case OPT_framework:
+    case OPT_weak_framework:
+      addFramework(arg->getValue(), opt.getID() == OPT_weak_framework);
+      break;
+    default:
+      break;
+    }
+  }
+}
+
 bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
                  raw_ostream &stdoutOS, raw_ostream &stderrOS) {
   lld::stdoutOS = &stdoutOS;
@@ -952,44 +992,10 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
     timeTraceProfilerInitialize(config->timeTraceGranularity, config->progName);
 
   {
-    llvm::TimeTraceScope timeScope("Link", StringRef("ExecuteLinker"));
+    TimeTraceScope timeScope("Link", StringRef("ExecuteLinker"));
 
     initLLVM(); // must be run before any call to addFile()
-
-    // This loop should be reserved for options whose exact ordering matters.
-    // Other options should be handled via filtered() and/or getLastArg().
-    for (const Arg *arg : args) {
-      const Option &opt = arg->getOption();
-      warnIfDeprecatedOption(opt);
-      warnIfUnimplementedOption(opt);
-
-      switch (opt.getID()) {
-      case OPT_INPUT:
-        addFile(arg->getValue(), false);
-        break;
-      case OPT_weak_library:
-        if (auto *dylibFile =
-                dyn_cast_or_null<DylibFile>(addFile(arg->getValue(), false)))
-          dylibFile->forceWeakImport = true;
-        break;
-      case OPT_filelist:
-        addFileList(arg->getValue());
-        break;
-      case OPT_force_load:
-        addFile(arg->getValue(), true);
-        break;
-      case OPT_l:
-      case OPT_weak_l:
-        addLibrary(arg->getValue(), opt.getID() == OPT_weak_l);
-        break;
-      case OPT_framework:
-      case OPT_weak_framework:
-        addFramework(arg->getValue(), opt.getID() == OPT_weak_framework);
-        break;
-      default:
-        break;
-      }
-    }
+    createFiles(args);
 
     config->isPic = config->outputType == MH_DYLIB ||
                     config->outputType == MH_BUNDLE || isPie(args);
@@ -1060,12 +1066,15 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
         inputFiles.insert(make<OpaqueFile>(*buffer, segName, sectName));
     }
 
-    // Initialize InputSections.
-    for (const InputFile *file : inputFiles) {
-      for (const SubsectionMap &map : file->subsections) {
-        for (const auto &p : map) {
-          InputSection *isec = p.second;
-          inputSections.push_back(isec);
+    {
+      TimeTraceScope timeScope("Gathering input sections");
+      // Gather all InputSections into one vector.
+      for (const InputFile *file : inputFiles) {
+        for (const SubsectionMap &map : file->subsections) {
+          for (const auto &p : map) {
+            InputSection *isec = p.second;
+            inputSections.push_back(isec);
+          }
         }
       }
     }

diff  --git a/lld/MachO/MapFile.cpp b/lld/MachO/MapFile.cpp
index e089136ee218..a10516f90d19 100644
--- a/lld/MachO/MapFile.cpp
+++ b/lld/MachO/MapFile.cpp
@@ -33,6 +33,7 @@
 #include "Symbols.h"
 #include "Target.h"
 #include "llvm/Support/Parallel.h"
+#include "llvm/Support/TimeProfiler.h"
 
 using namespace llvm;
 using namespace llvm::sys;
@@ -93,6 +94,8 @@ void macho::writeMapFile() {
   if (config->mapFile.empty())
     return;
 
+  TimeTraceScope timeScope("Write map file");
+
   // Open a map file for writing.
   std::error_code ec;
   raw_fd_ostream os(config->mapFile, ec, sys::fs::OF_None);

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 4070a2077937..9a28ade965fb 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/xxhash.h"
 
 #include <algorithm>
@@ -56,6 +57,7 @@ class Writer {
   void writeSections();
   void writeUuid();
   void writeCodeSignature();
+  void writeOutputFile();
 
   void run();
 
@@ -502,6 +504,7 @@ static void prepareSymbolRelocation(lld::macho::Symbol *sym,
 }
 
 void Writer::scanRelocations() {
+  TimeTraceScope timeScope("Scan relocations");
   for (InputSection *isec : inputSections) {
     if (isec->segname == segment_names::ld) {
       prepareCompactUnwind(isec);
@@ -534,6 +537,7 @@ void Writer::scanRelocations() {
 }
 
 void Writer::scanSymbols() {
+  TimeTraceScope timeScope("Scan symbols");
   for (const macho::Symbol *sym : symtab->getSymbols()) {
     if (const auto *defined = dyn_cast<Defined>(sym)) {
       if (defined->overridesWeakDef)
@@ -737,6 +741,8 @@ static std::function<bool(T, T)> compareByOrder(F ord) {
 // segments, output sections within each segment, and input sections within each
 // output segment.
 static void sortSegmentsAndSections() {
+  TimeTraceScope timeScope("Sort segments and sections");
+
   llvm::stable_sort(outputSegments,
                     compareByOrder<OutputSegment *>(segmentOrder));
 
@@ -777,6 +783,7 @@ static NamePair maybeRenameSection(NamePair key) {
 }
 
 void Writer::createOutputSections() {
+  TimeTraceScope timeScope("Create output sections");
   // First, create hidden sections
   stringTableSection = make<StringTableSection>();
   unwindInfoSection = make<UnwindInfoSection>(); // TODO(gkm): only when no -r
@@ -834,6 +841,7 @@ void Writer::createOutputSections() {
 }
 
 void Writer::finalizeAddressses() {
+  TimeTraceScope timeScope("Finalize addresses");
   // Ensure that segments (and the sections they contain) are allocated
   // addresses in ascending order, which dyld requires.
   //
@@ -848,6 +856,7 @@ void Writer::finalizeAddressses() {
 }
 
 void Writer::finalizeLinkEditSegment() {
+  TimeTraceScope timeScope("Finalize __LINKEDIT segment");
   // Fill __LINKEDIT contents.
   in.rebase->finalizeContents();
   in.binding->finalizeContents();
@@ -904,6 +913,7 @@ void Writer::writeSections() {
 }
 
 void Writer::writeUuid() {
+  TimeTraceScope timeScope("Computing UUID");
   uint64_t digest =
       xxHash64({buffer->getBufferStart(), buffer->getBufferEnd()});
   uuidCommand->writeUuid(digest);
@@ -914,6 +924,19 @@ void Writer::writeCodeSignature() {
     codeSignatureSection->writeHashes(buffer->getBufferStart());
 }
 
+void Writer::writeOutputFile() {
+  TimeTraceScope timeScope("Write output file");
+  openFile();
+  if (errorCount())
+    return;
+  writeSections();
+  writeUuid();
+  writeCodeSignature();
+
+  if (auto e = buffer->commit())
+    error("failed to write to the output file: " + toString(std::move(e)));
+}
+
 void Writer::run() {
   prepareBranchTarget(config->entry);
   scanRelocations();
@@ -927,15 +950,7 @@ void Writer::run() {
   finalizeAddressses();
   finalizeLinkEditSegment();
   writeMapFile();
-  openFile();
-  if (errorCount())
-    return;
-  writeSections();
-  writeUuid();
-  writeCodeSignature();
-
-  if (auto e = buffer->commit())
-    error("failed to write to the output file: " + toString(std::move(e)));
+  writeOutputFile();
 }
 
 void macho::writeResult() { Writer().run(); }


        


More information about the llvm-commits mailing list