Commit 6f7483b1 authored by Amy Huang's avatar Amy Huang
Browse files

Reland "[LLD] Remove global state in lld/COFF" after fixing asan and msan test failures

Original commit description:

  [LLD] Remove global state in lld/COFF

  This patch removes globals from the lldCOFF library, by moving globals
  into a context class (COFFLinkingContext) and passing it around wherever
  it's needed.

  See https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html for
  context about removing globals from LLD.

  I also haven't moved the `driver` or `config` variables yet.

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

This reverts commit a2fd05ad.

Original commits were b4fa71ee
and e03c7e36.
parent 27905eeb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ add_public_tablegen_target(COFFOptionsTableGen)
add_lld_library(lldCOFF
  CallGraphSort.cpp
  Chunks.cpp
  COFFLinkerContext.cpp
  DebugTypes.cpp
  DLL.cpp
  Driver.cpp
+40 −0
Original line number Diff line number Diff line
//===- COFFContext.cpp ----------------------------------------------------===//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Description
//
//===----------------------------------------------------------------------===//

#include "COFFLinkerContext.h"
#include "lld/Common/Memory.h"
#include "llvm/DebugInfo/CodeView/TypeHashing.h"

namespace lld {
namespace coff {

COFFLinkerContext::COFFLinkerContext()
    : symtab(*this), rootTimer("Total Linking Time"),
      inputFileTimer("Input File Reading", rootTimer),
      ltoTimer("LTO", rootTimer), gcTimer("GC", rootTimer),
      icfTimer("ICF", rootTimer), codeLayoutTimer("Code Layout", rootTimer),
      outputCommitTimer("Commit Output File", rootTimer),
      totalMapTimer("MAP Emission (Cumulative)", rootTimer),
      symbolGatherTimer("Gather Symbols", totalMapTimer),
      symbolStringsTimer("Build Symbol Strings", totalMapTimer),
      writeTimer("Write to File", totalMapTimer),
      totalPdbLinkTimer("PDB Emission (Cumulative)", rootTimer),
      addObjectsTimer("Add Objects", totalPdbLinkTimer),
      typeMergingTimer("Type Merging", addObjectsTimer),
      loadGHashTimer("Global Type Hashing", addObjectsTimer),
      mergeGHashTimer("GHash Type Merging", addObjectsTimer),
      symbolMergingTimer("Symbol Merging", addObjectsTimer),
      publicsLayoutTimer("Publics Stream Layout", totalPdbLinkTimer),
      tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer),
      diskCommitTimer("Commit to Disk", totalPdbLinkTimer) {}

} // namespace coff
} // namespace lld
+85 −0
Original line number Diff line number Diff line
//===- COFFLinkerContext.h --------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLD_COFF_COFFLinkerContext_H
#define LLD_COFF_COFFLinkerContext_H

#include "Chunks.h"
#include "Config.h"
#include "DebugTypes.h"
#include "InputFiles.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/Timer.h"

namespace lld {
namespace coff {

class COFFLinkerContext {
public:
  COFFLinkerContext();
  COFFLinkerContext(const COFFLinkerContext &) = delete;
  COFFLinkerContext &operator=(const COFFLinkerContext &) = delete;
  ~COFFLinkerContext() = default;

  void addTpiSource(TpiSource *tpi) { tpiSourceList.push_back(tpi); }

  SymbolTable symtab;

  std::vector<ObjFile *> objFileInstances;
  std::map<std::string, PDBInputFile *> pdbInputFileInstances;
  std::vector<ImportFile *> importFileInstances;
  std::vector<BitcodeFile *> bitcodeFileInstances;

  MergeChunk *mergeChunkInstances[Log2MaxSectionAlignment + 1] = {};

  /// All sources of type information in the program.
  std::vector<TpiSource *> tpiSourceList;

  std::map<llvm::codeview::GUID, TpiSource *> typeServerSourceMappings;
  std::map<uint32_t, TpiSource *> precompSourceMappings;

  /// List of all output sections. After output sections are finalized, this
  /// can be indexed by getOutputSection.
  std::vector<OutputSection *> outputSections;

  OutputSection *getOutputSection(const Chunk *c) const {
    return c->osidx == 0 ? nullptr : outputSections[c->osidx - 1];
  }

  // All timers used in the COFF linker.
  Timer rootTimer;
  Timer inputFileTimer;
  Timer ltoTimer;
  Timer gcTimer;
  Timer icfTimer;

  // Writer timers.
  Timer codeLayoutTimer;
  Timer outputCommitTimer;
  Timer totalMapTimer;
  Timer symbolGatherTimer;
  Timer symbolStringsTimer;
  Timer writeTimer;

  // PDB timers.
  Timer totalPdbLinkTimer;
  Timer addObjectsTimer;
  Timer typeMergingTimer;
  Timer loadGHashTimer;
  Timer mergeGHashTimer;
  Timer symbolMergingTimer;
  Timer publicsLayoutTimer;
  Timer tpiStreamLayoutTimer;
  Timer diskCommitTimer;
};

} // namespace coff
} // namespace lld

#endif
+7 −5
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "CallGraphSort.h"
#include "COFFLinkerContext.h"
#include "InputFiles.h"
#include "SymbolTable.h"
#include "Symbols.h"
@@ -48,7 +49,7 @@ struct Cluster {

class CallGraphSort {
public:
  CallGraphSort();
  CallGraphSort(const COFFLinkerContext &ctx);

  DenseMap<const SectionChunk *, int> run();

@@ -70,7 +71,7 @@ using SectionPair = std::pair<const SectionChunk *, const SectionChunk *>;
// Take the edge list in Config->CallGraphProfile, resolve symbol names to
// Symbols, and generate a graph between InputSections with the provided
// weights.
CallGraphSort::CallGraphSort() {
CallGraphSort::CallGraphSort(const COFFLinkerContext &ctx) {
  MapVector<SectionPair, uint64_t> &profile = config->callGraphProfile;
  DenseMap<const SectionChunk *, int> secToCluster;

@@ -95,7 +96,7 @@ CallGraphSort::CallGraphSort() {
    // output.  This messes with the cluster size and density calculations.  We
    // would also end up moving input sections in other output sections without
    // moving them closer to what calls them.
    if (fromSec->getOutputSection() != toSec->getOutputSection())
    if (ctx.getOutputSection(fromSec) != ctx.getOutputSection(toSec))
      continue;

    int from = getOrCreateNode(fromSec);
@@ -240,6 +241,7 @@ DenseMap<const SectionChunk *, int> CallGraphSort::run() {
// This first builds a call graph based on the profile data then merges sections
// according to the C³ heuristic. All clusters are then sorted by a density
// metric to further improve locality.
DenseMap<const SectionChunk *, int> coff::computeCallGraphProfileOrder() {
  return CallGraphSort().run();
DenseMap<const SectionChunk *, int>
coff::computeCallGraphProfileOrder(const COFFLinkerContext &ctx) {
  return CallGraphSort(ctx).run();
}
+3 −1
Original line number Diff line number Diff line
@@ -14,8 +14,10 @@
namespace lld {
namespace coff {
class SectionChunk;
class COFFLinkerContext;

llvm::DenseMap<const SectionChunk *, int> computeCallGraphProfileOrder();
llvm::DenseMap<const SectionChunk *, int>
computeCallGraphProfileOrder(const COFFLinkerContext &ctx);
} // namespace coff
} // namespace lld

Loading