Instrument things.
llvm-svn: 182789
diff --git a/lld/include/lld/Core/Instrumentation.h b/lld/include/lld/Core/Instrumentation.h
index 582c212..3059d0c 100644
--- a/lld/include/lld/Core/Instrumentation.h
+++ b/lld/include/lld/Core/Instrumentation.h
@@ -15,6 +15,10 @@
 #ifndef LLD_CORE_INSTRUMENTATION_H
 #define LLD_CORE_INSTRUMENTATION_H
 
+#include "llvm/Support/Compiler.h"
+
+#include <utility>
+
 #ifdef LLD_HAS_VTUNE
 # include <ittnotify.h>
 #endif
diff --git a/lld/lib/Core/PassManager.cpp b/lld/lib/Core/PassManager.cpp
index f5d998d..238fb0a 100644
--- a/lld/lib/Core/PassManager.cpp
+++ b/lld/lib/Core/PassManager.cpp
@@ -17,7 +17,6 @@
 namespace lld {
 ErrorOr<void> PassManager::runOnFile(MutableFile &mf) {
   for (auto &pass : _passes) {
-    ScopedTask task(getDefaultDomain(), "Pass");
     pass->perform(mf);
   }
   return llvm::error_code::success();
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index ccbecd7..e95aa9c 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -10,6 +10,7 @@
 #include "lld/Core/Atom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/InputFiles.h"
+#include "lld/Core/Instrumentation.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Resolver.h"
 #include "lld/Core/SymbolTable.h"
@@ -71,6 +72,7 @@
 
 // add all atoms from all initial .o files
 void Resolver::buildInitialAtomList() {
+  ScopedTask task(getDefaultDomain(), "buildInitialAtomList");
  DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver initial atom list:\n");
 
   // each input files contributes initial atoms
@@ -184,6 +186,7 @@
 // ask symbol table if any definitionUndefined atoms still exist
 // if so, keep searching libraries until no more atoms being added
 void Resolver::resolveUndefines() {
+  ScopedTask task(getDefaultDomain(), "resolveUndefines");
   const bool searchArchives =
       _targetInfo.searchArchivesToOverrideTentativeDefinitions();
   const bool searchSharedLibs =
@@ -234,6 +237,7 @@
 // switch all references to undefined or coalesced away atoms
 // to the new defined atom
 void Resolver::updateReferences() {
+  ScopedTask task(getDefaultDomain(), "updateReferences");
   for(const Atom *atom : _atoms) {
     if (const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom)) {
       for (const Reference *ref : *defAtom) {
@@ -267,6 +271,7 @@
 
 // remove all atoms not actually used
 void Resolver::deadStripOptimize() {
+  ScopedTask task(getDefaultDomain(), "deadStripOptimize");
   // only do this optimization with -dead_strip
   if (!_targetInfo.deadStrip())
     return;
@@ -354,6 +359,7 @@
 
 // remove from _atoms all coaleseced away atoms
 void Resolver::removeCoalescedAwayAtoms() {
+  ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms");
   _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
                               AtomCoalescedAway(_symbolTable)), _atoms.end());
 }
@@ -361,6 +367,7 @@
 // check for interactions between symbols defined in this linkage unit
 // and same symbol name in linked dynamic shared libraries
 void Resolver::checkDylibSymbolCollisions() {
+  ScopedTask task(getDefaultDomain(), "checkDylibSymbolCollisions");
   for ( const Atom *atom : _atoms ) {
     const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom);
     if (defAtom == nullptr)
@@ -420,6 +427,7 @@
 
 
 void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
+  ScopedTask task(getDefaultDomain(), "addAtoms");
   DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
   for ( const Atom *atom : all ) {
     DEBUG_WITH_TYPE("resolver", llvm::dbgs()
diff --git a/lld/lib/Driver/Driver.cpp b/lld/lib/Driver/Driver.cpp
index 983c9dc..a0233fe 100644
--- a/lld/lib/Driver/Driver.cpp
+++ b/lld/lib/Driver/Driver.cpp
@@ -11,6 +11,7 @@
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/InputFiles.h"
+#include "lld/Core/Instrumentation.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Core/Parallel.h"
 #include "lld/Core/Resolver.h"
@@ -41,6 +42,7 @@
   }
 
   // Read inputs
+  ScopedTask readTask(getDefaultDomain(), "Read Args");
   std::vector<std::vector<std::unique_ptr<File>>> files(
       targetInfo.inputFiles().size());
   size_t index = 0;
@@ -61,6 +63,7 @@
     ++index;
   }
   tg.sync();
+  readTask.end();
 
   if (fail)
     return true;
@@ -76,19 +79,24 @@
   inputs.assignFileOrdinals();
 
   // Do core linking.
+  ScopedTask resolveTask(getDefaultDomain(), "Resolve");
   Resolver resolver(targetInfo, inputs);
   if (resolver.resolve()) {
     if (!targetInfo.allowRemainingUndefines())
       return true;
   }
   MutableFile &merged = resolver.resultFile();
+  resolveTask.end();
 
   // Run passes on linked atoms.
+  ScopedTask passTask(getDefaultDomain(), "Passes");
   PassManager pm;
   targetInfo.addPasses(pm);
   pm.runOnFile(merged);
+  passTask.end();
 
   // Give linked atoms to Writer to generate output file.
+  ScopedTask writeTask(getDefaultDomain(), "Write");
   if (error_code ec = targetInfo.writeFile(merged)) {
     diagnostics << "Failed to write file '" << targetInfo.outputPath() 
                 << "': " << ec.message() << "\n";
diff --git a/lld/lib/Passes/LayoutPass.cpp b/lld/lib/Passes/LayoutPass.cpp
index 6dc9e0b..8add722 100644
--- a/lld/lib/Passes/LayoutPass.cpp
+++ b/lld/lib/Passes/LayoutPass.cpp
@@ -397,6 +397,7 @@
 
 /// Perform the actual pass
 void LayoutPass::perform(MutableFile &mergedFile) {
+  ScopedTask task(getDefaultDomain(), "LayoutPass");
   MutableFile::DefinedAtomRange atomRange = mergedFile.definedAtoms();
 
   // Build follow on tables
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
index 8c520ff..f0bafc1 100644
--- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h
+++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h
@@ -16,6 +16,7 @@
 #include "SectionChunks.h"
 #include "SegmentChunks.h"
 
+#include "lld/Core/Instrumentation.h"
 #include "lld/Core/STDExtras.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -211,6 +212,7 @@
   }
 
   inline void finalize() {
+    ScopedTask task(getDefaultDomain(), "Finalize layout");
     for (auto &si : _sections)
       si->finalize();
   }
@@ -544,6 +546,7 @@
 }
 
 template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
+  ScopedTask task(getDefaultDomain(), "assignSectionsToSegments");
   // TODO: Do we want to give a chance for the targetHandlers
   // to sort segments in an arbitrary order ?
   // sort the sections by their order as defined by the layout
diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
index e273d38..ebb4a68 100644
--- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp
@@ -96,6 +96,7 @@
 error_code
 ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
                          std::vector<std::unique_ptr<File> > &result) const {
+  ScopedTask task(getDefaultDomain(), "parseFile");
   error_code ec = _elfReader->parseFile(mb, result);
   if (ec) {
     // Not an ELF file, check file extension to see if it might be yaml
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index 7a3fedb..5880ed1 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -9,16 +9,16 @@
 #ifndef LLD_READER_WRITER_OUTPUT_ELF_WRITER_H
 #define LLD_READER_WRITER_OUTPUT_ELF_WRITER_H
 
+#include "lld/Core/Instrumentation.h"
+#include "lld/ReaderWriter/ELFTargetInfo.h"
 #include "lld/ReaderWriter/Writer.h"
 
+#include "llvm/ADT/StringSet.h"
+
 #include "DefaultLayout.h"
 #include "TargetLayout.h"
 #include "ExecutableAtoms.h"
 
-#include "lld/ReaderWriter/ELFTargetInfo.h"
-
-#include "llvm/ADT/StringSet.h"
-
 namespace lld {
 namespace elf {
 using namespace llvm;
@@ -125,6 +125,7 @@
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildChunks(const File &file) {
+  ScopedTask task(getDefaultDomain(), "buildChunks");
   for (const DefinedAtom *definedAtom : file.defined()) {
     _layout->addAtom(definedAtom);
   }
@@ -134,6 +135,7 @@
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildStaticSymbolTable(const File &file) {
+  ScopedTask task(getDefaultDomain(), "buildStaticSymbolTable");
   for (auto sec : _layout->sections())
     if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms())
@@ -146,6 +148,7 @@
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
+  ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
   for (const auto sla : file.sharedLibrary()) {
     _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
     _soNeeded.insert(sla->loadName());
@@ -169,6 +172,7 @@
 
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildAtomToAddressMap(const File &file) {
+  ScopedTask task(getDefaultDomain(), "buildAtomToAddressMap");
   int64_t totalAbsAtoms = _layout->absoluteAtoms().size();
   int64_t totalUndefinedAtoms = file.undefined().size();
   int64_t totalDefinedAtoms = 0;
@@ -190,6 +194,7 @@
 
 template<class ELFT>
 void OutputELFWriter<ELFT>::buildSectionHeaderTable() {
+  ScopedTask task(getDefaultDomain(), "buildSectionHeaderTable");
   for (auto mergedSec : _layout->mergedSections()) {
     if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
         mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
@@ -201,6 +206,7 @@
 
 template<class ELFT>
 void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() {
+  ScopedTask task(getDefaultDomain(), "assignSectionsWithNoSegments");
   for (auto mergedSec : _layout->mergedSections()) {
     if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
         mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
@@ -321,15 +327,19 @@
 
 template <class ELFT>
 error_code OutputELFWriter<ELFT>::writeFile(const File &file, StringRef path) {
-
+  ScopedTask buildTask(getDefaultDomain(), "ELF Writer buildOutput");
   buildOutput(file);
+  buildTask.end();
 
   uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
 
   OwningPtr<FileOutputBuffer> buffer;
+  ScopedTask createOutputTask(getDefaultDomain(), "ELF Writer Create Output");
   error_code ec = FileOutputBuffer::create(path,
                                            totalSize, buffer,
                                            FileOutputBuffer::F_executable);
+  createOutputTask.end();
+
   if (ec)
     return ec;
 
@@ -362,12 +372,15 @@
   // HACK: We have to write out the header and program header here even though
   // they are a member of a segment because only sections are written in the
   // following loop.
+  ScopedTask writeTask(getDefaultDomain(), "ELF Writer write to memory");
   _Header->write(this, *buffer);
   _programHeader->write(this, *buffer);
 
   for (auto section : _layout->sections())
     section->write(this, *buffer);
+  writeTask.end();
 
+  ScopedTask commitTask(getDefaultDomain(), "ELF Writer commit to disk");
   return buffer->commit();
 }
 } // namespace elf
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
index b4c1239..8321fff 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.cpp
@@ -11,6 +11,7 @@
 #include "X86_64TargetInfo.h"
 
 #include "lld/Core/File.h"
+#include "lld/Core/Instrumentation.h"
 #include "lld/Core/Pass.h"
 #include "lld/Core/PassManager.h"
 #include "lld/ReaderWriter/Simple.h"
@@ -213,6 +214,7 @@
   /// After all references are handled, the atoms created during that are all
   /// added to mf.
   virtual void perform(MutableFile &mf) {
+    ScopedTask task(getDefaultDomain(), "X86-64 GOT/PLT Pass");
     // Process all references.
     for (const auto &atom : mf.defined())
       for (const auto &ref : *atom)