[lld] 439341b - [lld][ELF] Add additional time trace categories

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 10 02:29:39 PST 2020


Author: James Henderson
Date: 2020-11-10T10:28:46Z
New Revision: 439341b9bf0d9c91d1fc7a896cb85dbbb958f924

URL: https://github.com/llvm/llvm-project/commit/439341b9bf0d9c91d1fc7a896cb85dbbb958f924
DIFF: https://github.com/llvm/llvm-project/commit/439341b9bf0d9c91d1fc7a896cb85dbbb958f924.diff

LOG: [lld][ELF] Add additional time trace categories

I noticed when running a large link with the --time-trace option that
there were several areas which were missing any specific time trace
categories (aside from the generic link/ExecuteLinker categories). This
patch adds new categories to fill most of the "gaps", or to provide more
detail than was previously provided.

Reviewed by: MaskRay, grimar, russell.gallop

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

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/DriverUtils.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/LinkerScript.cpp
    lld/ELF/MapFile.cpp
    lld/ELF/OutputSections.cpp
    lld/ELF/ScriptParser.cpp
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index fbc5e44baa05..318c231088a0 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1321,6 +1321,7 @@ static bool isFormatBinary(StringRef s) {
 }
 
 void LinkerDriver::createFiles(opt::InputArgList &args) {
+  llvm::TimeTraceScope timeScope("Load input files");
   // For --{push,pop}-state.
   std::vector<std::tuple<bool, bool, bool>> stack;
 
@@ -1659,6 +1660,7 @@ static void writeDependencyFile() {
 // result, the passes after the symbol resolution won't see any
 // symbols of type CommonSymbol.
 static void replaceCommonSymbols() {
+  llvm::TimeTraceScope timeScope("Replace common symbols");
   for (Symbol *sym : symtab->symbols()) {
     auto *s = dyn_cast<CommonSymbol>(sym);
     if (!s)
@@ -1678,6 +1680,7 @@ static void replaceCommonSymbols() {
 // created from the DSO. Otherwise, they become dangling references
 // that point to a non-existent DSO.
 static void demoteSharedSymbols() {
+  llvm::TimeTraceScope timeScope("Demote shared symbols");
   for (Symbol *sym : symtab->symbols()) {
     auto *s = dyn_cast<SharedSymbol>(sym);
     if (!s || s->getFile().isNeeded)
@@ -1974,10 +1977,14 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // Fail early if the output file or map file is not writable. If a user has a
   // long link, e.g. due to a large LTO link, they do not wish to run it and
   // find that it failed because there was a mistake in their command-line.
-  if (auto e = tryCreateFile(config->outputFile))
-    error("cannot open output file " + config->outputFile + ": " + e.message());
-  if (auto e = tryCreateFile(config->mapFile))
-    error("cannot open map file " + config->mapFile + ": " + e.message());
+  {
+    llvm::TimeTraceScope timeScope("Create output files");
+    if (auto e = tryCreateFile(config->outputFile))
+      error("cannot open output file " + config->outputFile + ": " +
+            e.message());
+    if (auto e = tryCreateFile(config->mapFile))
+      error("cannot open map file " + config->mapFile + ": " + e.message());
+  }
   if (errorCount())
     return;
 
@@ -2004,8 +2011,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // appended to the Files vector.
   {
     llvm::TimeTraceScope timeScope("Parse input files");
-    for (size_t i = 0; i < files.size(); ++i)
+    for (size_t i = 0; i < files.size(); ++i) {
+      llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName());
       parseFile(files[i]);
+    }
   }
 
   // Now that we have every file, we can decide if we will need a
@@ -2092,8 +2101,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   // For a relocatable output, version scripts don't make sense, and
   // parsing a symbol version string (e.g. dropping "@ver1" from a symbol
   // name "foo at ver1") rather do harm, so we don't call this if -r is given.
-  if (!config->relocatable)
+  if (!config->relocatable) {
+    llvm::TimeTraceScope timeScope("Process symbol versions");
     symtab->scanVersionScript();
+  }
 
   // Do link-time optimization if given files are LLVM bitcode files.
   // This compiles bitcode files into real object files.
@@ -2123,37 +2134,43 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   if (!wrapped.empty())
     wrapSymbols(wrapped);
 
-  // Now that we have a complete list of input files.
-  // Beyond this point, no new files are added.
-  // Aggregate all input sections into one place.
-  for (InputFile *f : objectFiles)
-    for (InputSectionBase *s : f->getSections())
-      if (s && s != &InputSection::discarded)
-        inputSections.push_back(s);
-  for (BinaryFile *f : binaryFiles)
-    for (InputSectionBase *s : f->getSections())
-      inputSections.push_back(cast<InputSection>(s));
-
-  llvm::erase_if(inputSections, [](InputSectionBase *s) {
-    if (s->type == SHT_LLVM_SYMPART) {
-      readSymbolPartitionSection<ELFT>(s);
-      return true;
-    }
+  {
+    llvm::TimeTraceScope timeScope("Aggregate sections");
+    // Now that we have a complete list of input files.
+    // Beyond this point, no new files are added.
+    // Aggregate all input sections into one place.
+    for (InputFile *f : objectFiles)
+      for (InputSectionBase *s : f->getSections())
+        if (s && s != &InputSection::discarded)
+          inputSections.push_back(s);
+    for (BinaryFile *f : binaryFiles)
+      for (InputSectionBase *s : f->getSections())
+        inputSections.push_back(cast<InputSection>(s));
+  }
 
-    // We do not want to emit debug sections if --strip-all
-    // or -strip-debug are given.
-    if (config->strip == StripPolicy::None)
-      return false;
+  {
+    llvm::TimeTraceScope timeScope("Strip sections");
+    llvm::erase_if(inputSections, [](InputSectionBase *s) {
+      if (s->type == SHT_LLVM_SYMPART) {
+        readSymbolPartitionSection<ELFT>(s);
+        return true;
+      }
 
-    if (isDebugSection(*s))
-      return true;
-    if (auto *isec = dyn_cast<InputSection>(s))
-      if (InputSectionBase *rel = isec->getRelocatedSection())
-        if (isDebugSection(*rel))
-          return true;
+      // We do not want to emit debug sections if --strip-all
+      // or -strip-debug are given.
+      if (config->strip == StripPolicy::None)
+        return false;
 
-    return false;
-  });
+      if (isDebugSection(*s))
+        return true;
+      if (auto *isec = dyn_cast<InputSection>(s))
+        if (InputSectionBase *rel = isec->getRelocatedSection())
+          if (isDebugSection(*rel))
+            return true;
+
+      return false;
+    });
+  }
 
   // Since we now have a complete set of input files, we can create
   // a .d file to record build dependencies.
@@ -2225,23 +2242,33 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   if (!config->relocatable)
     combineEhSections();
 
-  // Create output sections described by SECTIONS commands.
-  script->processSectionCommands();
-
-  // Linker scripts control how input sections are assigned to output sections.
-  // Input sections that were not handled by scripts are called "orphans", and
-  // they are assigned to output sections by the default rule. Process that.
-  script->addOrphanSections();
-
-  // Migrate InputSectionDescription::sectionBases to sections. This includes
-  // merging MergeInputSections into a single MergeSyntheticSection. From this
-  // point onwards InputSectionDescription::sections should be used instead of
-  // sectionBases.
-  for (BaseCommand *base : script->sectionCommands)
-    if (auto *sec = dyn_cast<OutputSection>(base))
-      sec->finalizeInputSections();
-  llvm::erase_if(inputSections,
-                 [](InputSectionBase *s) { return isa<MergeInputSection>(s); });
+  {
+    llvm::TimeTraceScope timeScope("Assign sections");
+
+    // Create output sections described by SECTIONS commands.
+    script->processSectionCommands();
+
+    // Linker scripts control how input sections are assigned to output
+    // sections. Input sections that were not handled by scripts are called
+    // "orphans", and they are assigned to output sections by the default rule.
+    // Process that.
+    script->addOrphanSections();
+  }
+
+  {
+    llvm::TimeTraceScope timeScope("Merge/finalize input sections");
+
+    // Migrate InputSectionDescription::sectionBases to sections. This includes
+    // merging MergeInputSections into a single MergeSyntheticSection. From this
+    // point onwards InputSectionDescription::sections should be used instead of
+    // sectionBases.
+    for (BaseCommand *base : script->sectionCommands)
+      if (auto *sec = dyn_cast<OutputSection>(base))
+        sec->finalizeInputSections();
+    llvm::erase_if(inputSections, [](InputSectionBase *s) {
+      return isa<MergeInputSection>(s);
+    });
+  }
 
   // Two input sections with 
diff erent output sections should not be folded.
   // ICF runs after processSectionCommands() so that we know the output sections.

diff  --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index e33b07c0c9c9..03173565e578 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -26,6 +26,7 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/TimeProfiler.h"
 
 using namespace llvm;
 using namespace llvm::sys;
@@ -238,6 +239,7 @@ Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
 
 // This is for -l<namespec>.
 Optional<std::string> elf::searchLibrary(StringRef name) {
+  llvm::TimeTraceScope timeScope("Locate library", name);
   if (name.startswith(":"))
     return findFromSearchPaths(name.substr(1));
   return searchLibraryBaseName(name);

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 70134d5ca0ef..f44260959d27 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -105,6 +105,8 @@ InputFile::InputFile(Kind k, MemoryBufferRef m)
 }
 
 Optional<MemoryBufferRef> elf::readFile(StringRef path) {
+  llvm::TimeTraceScope timeScope("Load input files", path);
+
   // The --chroot option changes our virtual root directory.
   // This is useful when you are dealing with files created by --reproduce.
   if (!config->chroot.empty() && path.startswith("/"))

diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9d612ae4aba0..8ae95fbe1e94 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Parallel.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/TimeProfiler.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -765,6 +766,7 @@ void LinkerScript::addOrphanSections() {
 }
 
 void LinkerScript::diagnoseOrphanHandling() const {
+  llvm::TimeTraceScope timeScope("Diagnose orphan sections");
   for (const InputSectionBase *sec : orphanSections) {
     // Input SHT_REL[A] retained by --emit-relocs are ignored by
     // computeInputSections(). Don't warn/error.

diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 12cffead1f80..239c6c394840 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -29,6 +29,7 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/Support/Parallel.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
@@ -142,6 +143,8 @@ void elf::writeMapFile() {
   if (config->mapFile.empty())
     return;
 
+  llvm::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/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 1b7f26a7d79f..518af1ee0548 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Parallel.h"
 #include "llvm/Support/SHA1.h"
+#include "llvm/Support/TimeProfiler.h"
 #include <regex>
 #include <unordered_set>
 
@@ -285,6 +286,8 @@ template <class ELFT> void OutputSection::maybeCompress() {
       !name.startswith(".debug_"))
     return;
 
+  llvm::TimeTraceScope timeScope("Compress debug sections");
+
   // Create a section header.
   zDebugHeader.resize(sizeof(Elf_Chdr));
   auto *hdr = reinterpret_cast<Elf_Chdr *>(zDebugHeader.data());

diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index eae1d17b2f43..5a8131166b14 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TimeProfiler.h"
 #include <cassert>
 #include <limits>
 #include <vector>
@@ -1620,17 +1621,23 @@ std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
 }
 
 void elf::readLinkerScript(MemoryBufferRef mb) {
+  llvm::TimeTraceScope timeScope("Read linker script",
+                                 mb.getBufferIdentifier());
   ScriptParser(mb).readLinkerScript();
 }
 
 void elf::readVersionScript(MemoryBufferRef mb) {
+  llvm::TimeTraceScope timeScope("Read version script",
+                                 mb.getBufferIdentifier());
   ScriptParser(mb).readVersionScript();
 }
 
 void elf::readDynamicList(MemoryBufferRef mb) {
+  llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
   ScriptParser(mb).readDynamicList();
 }
 
 void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
+  llvm::TimeTraceScope timeScope("Read defsym input", name);
   ScriptParser(mb).readDefsym(name);
 }

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a02b08204d80..1bb88a25351c 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -158,7 +158,6 @@ static bool needsInterpSection() {
 }
 
 template <class ELFT> void elf::writeResult() {
-  llvm::TimeTraceScope timeScope("Write output file");
   Writer<ELFT>().run();
 }
 
@@ -205,6 +204,7 @@ void elf::copySectionsIntoPartitions() {
 }
 
 void elf::combineEhSections() {
+  llvm::TimeTraceScope timeScope("Combine EH sections");
   for (InputSectionBase *&s : inputSections) {
     // Ignore dead sections and the partition end marker (.part.end),
     // whose partition number is out of bounds.
@@ -634,30 +634,34 @@ template <class ELFT> void Writer<ELFT>::run() {
     checkSections();
 
   // It does not make sense try to open the file if we have error already.
-  if (errorCount())
-    return;
-  // Write the result down to a file.
-  openFile();
   if (errorCount())
     return;
 
-  if (!config->oFormatBinary) {
-    if (config->zSeparate != SeparateSegmentKind::None)
-      writeTrapInstr();
-    writeHeader();
-    writeSections();
-  } else {
-    writeSectionsBinary();
-  }
+  {
+    llvm::TimeTraceScope timeScope("Write output file");
+    // Write the result down to a file.
+    openFile();
+    if (errorCount())
+      return;
 
-  // Backfill .note.gnu.build-id section content. This is done at last
-  // because the content is usually a hash value of the entire output file.
-  writeBuildId();
-  if (errorCount())
-    return;
+    if (!config->oFormatBinary) {
+      if (config->zSeparate != SeparateSegmentKind::None)
+        writeTrapInstr();
+      writeHeader();
+      writeSections();
+    } else {
+      writeSectionsBinary();
+    }
+
+    // Backfill .note.gnu.build-id section content. This is done at last
+    // because the content is usually a hash value of the entire output file.
+    writeBuildId();
+    if (errorCount())
+      return;
 
-  if (auto e = buffer->commit())
-    error("failed to write to the output file: " + toString(std::move(e)));
+    if (auto e = buffer->commit())
+      error("failed to write to the output file: " + toString(std::move(e)));
+  }
 }
 
 template <class ELFT, class RelTy>
@@ -763,6 +767,7 @@ static bool includeInSymtab(const Symbol &b) {
 template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
   if (!in.symTab)
     return;
+  llvm::TimeTraceScope timeScope("Add local symbols");
   if (config->copyRelocs && config->discard != DiscardPolicy::None)
     markUsedLocalSymbols<ELFT>();
   for (InputFile *file : objectFiles) {
@@ -1504,6 +1509,7 @@ template <class ELFT> void Writer<ELFT>::sortInputSections() {
 }
 
 template <class ELFT> void Writer<ELFT>::sortSections() {
+  llvm::TimeTraceScope timeScope("Sort sections");
   script->adjustSectionsBeforeSorting();
 
   // Don't sort if using -r. It is not necessary and we want to preserve the
@@ -1637,6 +1643,7 @@ static bool compareByFilePosition(InputSection *a, InputSection *b) {
 }
 
 template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
+  llvm::TimeTraceScope timeScope("Resolve SHF_LINK_ORDER");
   for (OutputSection *sec : outputSections) {
     if (!(sec->flags & SHF_LINK_ORDER))
       continue;
@@ -1679,8 +1686,10 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
 }
 
 static void finalizeSynthetic(SyntheticSection *sec) {
-  if (sec && sec->isNeeded() && sec->getParent())
+  if (sec && sec->isNeeded() && sec->getParent()) {
+    llvm::TimeTraceScope timeScope("Finalize synthetic sections", sec->name);
     sec->finalizeContents();
+  }
 }
 
 // We need to generate and finalize the content that depends on the address of
@@ -1688,6 +1697,7 @@ static void finalizeSynthetic(SyntheticSection *sec) {
 // addresses we must converge to a fixed point. We do that here. See the comment
 // in Writer<ELFT>::finalizeSections().
 template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
+  llvm::TimeTraceScope timeScope("Finalize address dependent content");
   ThunkCreator tc;
   AArch64Err843419Patcher a64p;
   ARMErr657417Patcher a32p;
@@ -1944,11 +1954,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     }
   }
 
-  // This responsible for splitting up .eh_frame section into
-  // pieces. The relocation scan uses those pieces, so this has to be
-  // earlier.
-  for (Partition &part : partitions)
-    finalizeSynthetic(part.ehFrame);
+  {
+    llvm::TimeTraceScope timeScope("Finalize .eh_frame");
+    // This responsible for splitting up .eh_frame section into
+    // pieces. The relocation scan uses those pieces, so this has to be
+    // earlier.
+    for (Partition &part : partitions)
+      finalizeSynthetic(part.ehFrame);
+  }
 
   for (Symbol *sym : symtab->symbols())
     sym->isPreemptible = computeIsPreemptible(*sym);
@@ -1957,14 +1970,17 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   // by declareSymbols) to actual definitions.
   script->processSymbolAssignments();
 
-  // Scan relocations. This must be done after every symbol is declared so that
-  // we can correctly decide if a dynamic relocation is needed. This is called
-  // after processSymbolAssignments() because it needs to know whether a
-  // linker-script-defined symbol is absolute.
-  ppc64noTocRelax.clear();
-  if (!config->relocatable) {
-    forEachRelSec(scanRelocations<ELFT>);
-    reportUndefinedSymbols<ELFT>();
+  {
+    llvm::TimeTraceScope timeScope("Scan relocations");
+    // Scan relocations. This must be done after every symbol is declared so
+    // that we can correctly decide if a dynamic relocation is needed. This is
+    // called after processSymbolAssignments() because it needs to know whether
+    // a linker-script-defined symbol is absolute.
+    ppc64noTocRelax.clear();
+    if (!config->relocatable) {
+      forEachRelSec(scanRelocations<ELFT>);
+      reportUndefinedSymbols<ELFT>();
+    }
   }
 
   if (in.plt && in.plt->isNeeded())
@@ -1994,31 +2010,34 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
                         toString(*sym) + " [--no-allow-shlib-undefined]");
   }
 
-  // Now that we have defined all possible global symbols including linker-
-  // synthesized ones. Visit all symbols to give the finishing touches.
-  for (Symbol *sym : symtab->symbols()) {
-    if (!includeInSymtab(*sym))
-      continue;
-    if (in.symTab)
-      in.symTab->addSymbol(sym);
-
-    if (sym->includeInDynsym()) {
-      partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
-      if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
-        if (file->isNeeded && !sym->isUndefined())
-          addVerneed(sym);
+  {
+    llvm::TimeTraceScope timeScope("Add symbols to symtabs");
+    // Now that we have defined all possible global symbols including linker-
+    // synthesized ones. Visit all symbols to give the finishing touches.
+    for (Symbol *sym : symtab->symbols()) {
+      if (!includeInSymtab(*sym))
+        continue;
+      if (in.symTab)
+        in.symTab->addSymbol(sym);
+
+      if (sym->includeInDynsym()) {
+        partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
+        if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
+          if (file->isNeeded && !sym->isUndefined())
+            addVerneed(sym);
+      }
     }
-  }
 
-  // We also need to scan the dynamic relocation tables of the other partitions
-  // and add any referenced symbols to the partition's dynsym.
-  for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
-    DenseSet<Symbol *> syms;
-    for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
-      syms.insert(e.sym);
-    for (DynamicReloc &reloc : part.relaDyn->relocs)
-      if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
-        part.dynSymTab->addSymbol(reloc.sym);
+    // We also need to scan the dynamic relocation tables of the other
+    // partitions and add any referenced symbols to the partition's dynsym.
+    for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
+      DenseSet<Symbol *> syms;
+      for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
+        syms.insert(e.sym);
+      for (DynamicReloc &reloc : part.relaDyn->relocs)
+        if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
+          part.dynSymTab->addSymbol(reloc.sym);
+    }
   }
 
   // Do not proceed if there was an undefined symbol.
@@ -2099,35 +2118,39 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   // have the headers, we can find out which sections they point to.
   setReservedSymbolSections();
 
-  finalizeSynthetic(in.bss);
-  finalizeSynthetic(in.bssRelRo);
-  finalizeSynthetic(in.symTabShndx);
-  finalizeSynthetic(in.shStrTab);
-  finalizeSynthetic(in.strTab);
-  finalizeSynthetic(in.got);
-  finalizeSynthetic(in.mipsGot);
-  finalizeSynthetic(in.igotPlt);
-  finalizeSynthetic(in.gotPlt);
-  finalizeSynthetic(in.relaIplt);
-  finalizeSynthetic(in.relaPlt);
-  finalizeSynthetic(in.plt);
-  finalizeSynthetic(in.iplt);
-  finalizeSynthetic(in.ppc32Got2);
-  finalizeSynthetic(in.partIndex);
-
-  // Dynamic section must be the last one in this list and dynamic
-  // symbol table section (dynSymTab) must be the first one.
-  for (Partition &part : partitions) {
-    finalizeSynthetic(part.dynSymTab);
-    finalizeSynthetic(part.gnuHashTab);
-    finalizeSynthetic(part.hashTab);
-    finalizeSynthetic(part.verDef);
-    finalizeSynthetic(part.relaDyn);
-    finalizeSynthetic(part.relrDyn);
-    finalizeSynthetic(part.ehFrameHdr);
-    finalizeSynthetic(part.verSym);
-    finalizeSynthetic(part.verNeed);
-    finalizeSynthetic(part.dynamic);
+  {
+    llvm::TimeTraceScope timeScope("Finalize synthetic sections");
+
+    finalizeSynthetic(in.bss);
+    finalizeSynthetic(in.bssRelRo);
+    finalizeSynthetic(in.symTabShndx);
+    finalizeSynthetic(in.shStrTab);
+    finalizeSynthetic(in.strTab);
+    finalizeSynthetic(in.got);
+    finalizeSynthetic(in.mipsGot);
+    finalizeSynthetic(in.igotPlt);
+    finalizeSynthetic(in.gotPlt);
+    finalizeSynthetic(in.relaIplt);
+    finalizeSynthetic(in.relaPlt);
+    finalizeSynthetic(in.plt);
+    finalizeSynthetic(in.iplt);
+    finalizeSynthetic(in.ppc32Got2);
+    finalizeSynthetic(in.partIndex);
+
+    // Dynamic section must be the last one in this list and dynamic
+    // symbol table section (dynSymTab) must be the first one.
+    for (Partition &part : partitions) {
+      finalizeSynthetic(part.dynSymTab);
+      finalizeSynthetic(part.gnuHashTab);
+      finalizeSynthetic(part.hashTab);
+      finalizeSynthetic(part.verDef);
+      finalizeSynthetic(part.relaDyn);
+      finalizeSynthetic(part.relrDyn);
+      finalizeSynthetic(part.ehFrameHdr);
+      finalizeSynthetic(part.verSym);
+      finalizeSynthetic(part.verNeed);
+      finalizeSynthetic(part.dynamic);
+    }
   }
 
   if (!script->hasSectionsCommand && !config->relocatable)
@@ -2158,9 +2181,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
   if (errorCount())
     return;
 
-  // finalizeAddressDependentContent may have added local symbols to the static symbol table.
-  finalizeSynthetic(in.symTab);
-  finalizeSynthetic(in.ppc64LongBranchTarget);
+  {
+    llvm::TimeTraceScope timeScope("Finalize synthetic sections");
+    // finalizeAddressDependentContent may have added local symbols to the
+    // static symbol table.
+    finalizeSynthetic(in.symTab);
+    finalizeSynthetic(in.ppc64LongBranchTarget);
+  }
 
   // Relaxation to delete inter-basic block jumps created by basic block
   // sections. Run after in.symTab is finalized as optimizeBasicBlockJumps


        


More information about the llvm-commits mailing list