mirror of
https://github.com/rui314/mold.git
synced 2024-11-11 16:58:12 +03:00
Parallelize comdat removal, which shortens it from 75ms to 37ms
This commit is contained in:
parent
8e19148923
commit
dca18cad13
@ -60,9 +60,9 @@ void ObjectFile::initialize_sections() {
|
||||
if (entries[0] != GRP_COMDAT)
|
||||
error(toString(this) + ": unsupported SHT_GROUP format");
|
||||
|
||||
static ConcurrentMap<bool> map;
|
||||
bool *handle = map.insert(signature, false);
|
||||
comdat_groups.push_back({handle, entries});
|
||||
static ConcurrentMap<ComdatGroup> map;
|
||||
ComdatGroup *group = map.insert(signature, ComdatGroup(this, i));
|
||||
comdat_groups.push_back({group, i});
|
||||
num_comdats++;
|
||||
break;
|
||||
}
|
||||
@ -120,6 +120,14 @@ void ObjectFile::initialize_symbols() {
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFile::remove_comdat_members(uint32_t section_idx) {
|
||||
const ELF64LE::Shdr &shdr = elf_sections[section_idx];
|
||||
ArrayRef<ELF64LE::Word> entries =
|
||||
CHECK(obj.template getSectionContentsAsArray<ELF64LE::Word>(shdr), this);
|
||||
for (uint32_t i : entries)
|
||||
sections[i] = nullptr;
|
||||
}
|
||||
|
||||
void ObjectFile::read_string_pieces(const ELF64LE::Shdr &shdr) {
|
||||
static ConcurrentMap<StringPiece> map1;
|
||||
static ConcurrentMap<StringPiece> map2;
|
||||
@ -208,17 +216,28 @@ void ObjectFile::register_undefined_symbols() {
|
||||
}
|
||||
|
||||
void ObjectFile::eliminate_duplicate_comdat_groups() {
|
||||
for (std::pair<bool *, ArrayRef<ELF64LE::Word>> pair : comdat_groups) {
|
||||
bool *handle = pair.first;
|
||||
ArrayRef<ELF64LE::Word> entries = pair.second;
|
||||
for (auto &pair : comdat_groups) {
|
||||
ComdatGroup *g = pair.first;
|
||||
uint32_t section_idx = pair.second;
|
||||
|
||||
if (!*handle) {
|
||||
*handle = true;
|
||||
continue;
|
||||
ObjectFile *file = nullptr;
|
||||
uint32_t idx = 0;
|
||||
|
||||
while (g->lock.test_and_set(std::memory_order_acquire));
|
||||
if (g->file == nullptr) {
|
||||
g->file = this;
|
||||
g->section_idx = section_idx;
|
||||
} else if (g->file->priority < this->priority) {
|
||||
file = this;
|
||||
idx = section_idx;
|
||||
} else {
|
||||
file = g->file;
|
||||
idx = g->section_idx;
|
||||
}
|
||||
g->lock.clear(std::memory_order_release);
|
||||
|
||||
for (uint32_t i : entries)
|
||||
sections[i] = nullptr;
|
||||
if (file)
|
||||
file->remove_comdat_members(idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
3
main.cc
3
main.cc
@ -224,8 +224,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Eliminate duplicate comdat groups.
|
||||
comdat_timer.startTimer();
|
||||
for (ObjectFile *file : files)
|
||||
file->eliminate_duplicate_comdat_groups();
|
||||
for_each(files, [](ObjectFile *file) { file->eliminate_duplicate_comdat_groups(); });
|
||||
comdat_timer.stopTimer();
|
||||
|
||||
// Bin input sections into output sections
|
||||
|
18
mold.h
18
mold.h
@ -349,10 +349,21 @@ extern StringTableSection *shstrtab;
|
||||
// input_files.cc
|
||||
//
|
||||
|
||||
class StringPiece {
|
||||
public:
|
||||
struct ComdatGroup {
|
||||
ComdatGroup(ObjectFile *file, uint32_t i)
|
||||
: file(file), section_idx(i) {}
|
||||
ComdatGroup(const ComdatGroup &other)
|
||||
: file(other.file), section_idx(other.section_idx) {}
|
||||
|
||||
std::atomic_flag lock = ATOMIC_FLAG_INIT;
|
||||
ObjectFile *file = nullptr;
|
||||
uint32_t section_idx;
|
||||
};
|
||||
|
||||
struct StringPiece {
|
||||
StringPiece(StringRef data) : data(data) {}
|
||||
StringPiece(const StringPiece &other) : data(other.data) {}
|
||||
|
||||
StringRef data;
|
||||
std::atomic_flag flag = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
@ -377,11 +388,12 @@ public:
|
||||
private:
|
||||
void initialize_sections();
|
||||
void initialize_symbols();
|
||||
void remove_comdat_members(uint32_t section_idx);
|
||||
void read_string_pieces(const ELF64LE::Shdr &shdr);
|
||||
|
||||
MemoryBufferRef mb;
|
||||
std::vector<Symbol *> symbols;
|
||||
std::vector<std::pair<bool *, ArrayRef<ELF64LE::Word>>> comdat_groups;
|
||||
std::vector<std::pair<ComdatGroup *, uint32_t>> comdat_groups;
|
||||
std::vector<StringPiece *> merged_strings_alloc;
|
||||
std::vector<StringPiece *> merged_strings_noalloc;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user