Skip to content

Commit 6f7483b

Browse files
committed
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 a2fd05a. Original commits were b4fa71e and e03c7e3.
1 parent 27905ee commit 6f7483b

38 files changed

+754
-609
lines changed

lld/COFF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_public_tablegen_target(COFFOptionsTableGen)
55
add_lld_library(lldCOFF
66
CallGraphSort.cpp
77
Chunks.cpp
8+
COFFLinkerContext.cpp
89
DebugTypes.cpp
910
DLL.cpp
1011
Driver.cpp

lld/COFF/COFFLinkerContext.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===- COFFContext.cpp ----------------------------------------------------===//
2+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3+
// See https://llvm.org/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
//
6+
//===----------------------------------------------------------------------===//
7+
//
8+
// Description
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#include "COFFLinkerContext.h"
13+
#include "lld/Common/Memory.h"
14+
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
15+
16+
namespace lld {
17+
namespace coff {
18+
19+
COFFLinkerContext::COFFLinkerContext()
20+
: symtab(*this), rootTimer("Total Linking Time"),
21+
inputFileTimer("Input File Reading", rootTimer),
22+
ltoTimer("LTO", rootTimer), gcTimer("GC", rootTimer),
23+
icfTimer("ICF", rootTimer), codeLayoutTimer("Code Layout", rootTimer),
24+
outputCommitTimer("Commit Output File", rootTimer),
25+
totalMapTimer("MAP Emission (Cumulative)", rootTimer),
26+
symbolGatherTimer("Gather Symbols", totalMapTimer),
27+
symbolStringsTimer("Build Symbol Strings", totalMapTimer),
28+
writeTimer("Write to File", totalMapTimer),
29+
totalPdbLinkTimer("PDB Emission (Cumulative)", rootTimer),
30+
addObjectsTimer("Add Objects", totalPdbLinkTimer),
31+
typeMergingTimer("Type Merging", addObjectsTimer),
32+
loadGHashTimer("Global Type Hashing", addObjectsTimer),
33+
mergeGHashTimer("GHash Type Merging", addObjectsTimer),
34+
symbolMergingTimer("Symbol Merging", addObjectsTimer),
35+
publicsLayoutTimer("Publics Stream Layout", totalPdbLinkTimer),
36+
tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer),
37+
diskCommitTimer("Commit to Disk", totalPdbLinkTimer) {}
38+
39+
} // namespace coff
40+
} // namespace lld

lld/COFF/COFFLinkerContext.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===- COFFLinkerContext.h --------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLD_COFF_COFFLinkerContext_H
10+
#define LLD_COFF_COFFLinkerContext_H
11+
12+
#include "Chunks.h"
13+
#include "Config.h"
14+
#include "DebugTypes.h"
15+
#include "InputFiles.h"
16+
#include "SymbolTable.h"
17+
#include "Writer.h"
18+
#include "lld/Common/Timer.h"
19+
20+
namespace lld {
21+
namespace coff {
22+
23+
class COFFLinkerContext {
24+
public:
25+
COFFLinkerContext();
26+
COFFLinkerContext(const COFFLinkerContext &) = delete;
27+
COFFLinkerContext &operator=(const COFFLinkerContext &) = delete;
28+
~COFFLinkerContext() = default;
29+
30+
void addTpiSource(TpiSource *tpi) { tpiSourceList.push_back(tpi); }
31+
32+
SymbolTable symtab;
33+
34+
std::vector<ObjFile *> objFileInstances;
35+
std::map<std::string, PDBInputFile *> pdbInputFileInstances;
36+
std::vector<ImportFile *> importFileInstances;
37+
std::vector<BitcodeFile *> bitcodeFileInstances;
38+
39+
MergeChunk *mergeChunkInstances[Log2MaxSectionAlignment + 1] = {};
40+
41+
/// All sources of type information in the program.
42+
std::vector<TpiSource *> tpiSourceList;
43+
44+
std::map<llvm::codeview::GUID, TpiSource *> typeServerSourceMappings;
45+
std::map<uint32_t, TpiSource *> precompSourceMappings;
46+
47+
/// List of all output sections. After output sections are finalized, this
48+
/// can be indexed by getOutputSection.
49+
std::vector<OutputSection *> outputSections;
50+
51+
OutputSection *getOutputSection(const Chunk *c) const {
52+
return c->osidx == 0 ? nullptr : outputSections[c->osidx - 1];
53+
}
54+
55+
// All timers used in the COFF linker.
56+
Timer rootTimer;
57+
Timer inputFileTimer;
58+
Timer ltoTimer;
59+
Timer gcTimer;
60+
Timer icfTimer;
61+
62+
// Writer timers.
63+
Timer codeLayoutTimer;
64+
Timer outputCommitTimer;
65+
Timer totalMapTimer;
66+
Timer symbolGatherTimer;
67+
Timer symbolStringsTimer;
68+
Timer writeTimer;
69+
70+
// PDB timers.
71+
Timer totalPdbLinkTimer;
72+
Timer addObjectsTimer;
73+
Timer typeMergingTimer;
74+
Timer loadGHashTimer;
75+
Timer mergeGHashTimer;
76+
Timer symbolMergingTimer;
77+
Timer publicsLayoutTimer;
78+
Timer tpiStreamLayoutTimer;
79+
Timer diskCommitTimer;
80+
};
81+
82+
} // namespace coff
83+
} // namespace lld
84+
85+
#endif

lld/COFF/CallGraphSort.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "CallGraphSort.h"
15+
#include "COFFLinkerContext.h"
1516
#include "InputFiles.h"
1617
#include "SymbolTable.h"
1718
#include "Symbols.h"
@@ -48,7 +49,7 @@ struct Cluster {
4849

4950
class CallGraphSort {
5051
public:
51-
CallGraphSort();
52+
CallGraphSort(const COFFLinkerContext &ctx);
5253

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

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

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

101102
int from = getOrCreateNode(fromSec);
@@ -240,6 +241,7 @@ DenseMap<const SectionChunk *, int> CallGraphSort::run() {
240241
// This first builds a call graph based on the profile data then merges sections
241242
// according to the C³ heuristic. All clusters are then sorted by a density
242243
// metric to further improve locality.
243-
DenseMap<const SectionChunk *, int> coff::computeCallGraphProfileOrder() {
244-
return CallGraphSort().run();
244+
DenseMap<const SectionChunk *, int>
245+
coff::computeCallGraphProfileOrder(const COFFLinkerContext &ctx) {
246+
return CallGraphSort(ctx).run();
245247
}

lld/COFF/CallGraphSort.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
namespace lld {
1515
namespace coff {
1616
class SectionChunk;
17+
class COFFLinkerContext;
1718

18-
llvm::DenseMap<const SectionChunk *, int> computeCallGraphProfileOrder();
19+
llvm::DenseMap<const SectionChunk *, int>
20+
computeCallGraphProfileOrder(const COFFLinkerContext &ctx);
1921
} // namespace coff
2022
} // namespace lld
2123

lld/COFF/Chunks.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "Chunks.h"
10+
#include "COFFLinkerContext.h"
1011
#include "InputFiles.h"
12+
#include "SymbolTable.h"
1113
#include "Symbols.h"
1214
#include "Writer.h"
13-
#include "SymbolTable.h"
1415
#include "lld/Common/ErrorHandler.h"
1516
#include "llvm/ADT/Twine.h"
1617
#include "llvm/BinaryFormat/COFF.h"
@@ -385,7 +386,7 @@ void SectionChunk::applyRelocation(uint8_t *off,
385386
// section is needed to compute SECREL and SECTION relocations used in debug
386387
// info.
387388
Chunk *c = sym ? sym->getChunk() : nullptr;
388-
OutputSection *os = c ? c->getOutputSection() : nullptr;
389+
OutputSection *os = c ? file->ctx.getOutputSection(c) : nullptr;
389390

390391
// Skip the relocation if it refers to a discarded section, and diagnose it
391392
// as an error if appropriate. If a symbol was discarded early, it may be
@@ -938,18 +939,16 @@ uint8_t Baserel::getDefaultType() {
938939
}
939940
}
940941

941-
MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {};
942-
943942
MergeChunk::MergeChunk(uint32_t alignment)
944943
: builder(StringTableBuilder::RAW, alignment) {
945944
setAlignment(alignment);
946945
}
947946

948-
void MergeChunk::addSection(SectionChunk *c) {
947+
void MergeChunk::addSection(COFFLinkerContext &ctx, SectionChunk *c) {
949948
assert(isPowerOf2_32(c->getAlignment()));
950949
uint8_t p2Align = llvm::Log2_32(c->getAlignment());
951-
assert(p2Align < array_lengthof(instances));
952-
auto *&mc = instances[p2Align];
950+
assert(p2Align < array_lengthof(ctx.mergeChunkInstances));
951+
auto *&mc = ctx.mergeChunkInstances[p2Align];
953952
if (!mc)
954953
mc = make<MergeChunk>(c->getAlignment());
955954
mc->sections.push_back(c);

lld/COFF/Chunks.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ class Chunk {
101101
// chunk has a back pointer to an output section.
102102
void setOutputSectionIdx(uint16_t o) { osidx = o; }
103103
uint16_t getOutputSectionIdx() const { return osidx; }
104-
OutputSection *getOutputSection() const;
105104

106105
// Windows-specific.
107106
// Collect all locations that contain absolute addresses for base relocations.
@@ -415,7 +414,7 @@ inline StringRef Chunk::getDebugName() const {
415414
class MergeChunk : public NonSectionChunk {
416415
public:
417416
MergeChunk(uint32_t alignment);
418-
static void addSection(SectionChunk *c);
417+
static void addSection(COFFLinkerContext &ctx, SectionChunk *c);
419418
void finalizeContents();
420419
void assignSubsectionRVAs();
421420

@@ -424,7 +423,6 @@ class MergeChunk : public NonSectionChunk {
424423
size_t getSize() const override;
425424
void writeTo(uint8_t *buf) const override;
426425

427-
static MergeChunk *instances[Log2MaxSectionAlignment + 1];
428426
std::vector<SectionChunk *> sections;
429427

430428
private:

lld/COFF/DLL.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//===----------------------------------------------------------------------===//
1919

2020
#include "DLL.h"
21+
#include "COFFLinkerContext.h"
2122
#include "Chunks.h"
2223
#include "SymbolTable.h"
2324
#include "llvm/Object/COFF.h"
@@ -631,7 +632,7 @@ uint64_t DelayLoadContents::getDirSize() {
631632
return dirs.size() * sizeof(delay_import_directory_table_entry);
632633
}
633634

634-
void DelayLoadContents::create(Defined *h) {
635+
void DelayLoadContents::create(COFFLinkerContext &ctx, Defined *h) {
635636
helper = h;
636637
std::vector<std::vector<DefinedImportData *>> v = binImports(imports);
637638

@@ -660,13 +661,13 @@ void DelayLoadContents::create(Defined *h) {
660661
// call targets for Control Flow Guard.
661662
StringRef symName = saver.save("__imp_load_" + extName);
662663
s->loadThunkSym =
663-
cast<DefinedSynthetic>(symtab->addSynthetic(symName, t));
664+
cast<DefinedSynthetic>(ctx.symtab.addSynthetic(symName, t));
664665
}
665666
}
666667
thunks.push_back(tm);
667668
StringRef tmName =
668669
saver.save("__tailMerge_" + syms[0]->getDLLName().lower());
669-
symtab->addSynthetic(tmName, tm);
670+
ctx.symtab.addSynthetic(tmName, tm);
670671
// Terminate with null values.
671672
addresses.push_back(make<NullChunk>(8));
672673
names.push_back(make<NullChunk>(8));

lld/COFF/DLL.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class DelayLoadContents {
4040
public:
4141
void add(DefinedImportData *sym) { imports.push_back(sym); }
4242
bool empty() { return imports.empty(); }
43-
void create(Defined *helper);
43+
void create(COFFLinkerContext &ctx, Defined *helper);
4444
std::vector<Chunk *> getChunks();
4545
std::vector<Chunk *> getDataChunks();
4646
ArrayRef<Chunk *> getCodeChunks() { return thunks; }

0 commit comments

Comments
 (0)