1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-22 18:40:59 +03:00

Parallelize comdat removal, which shortens it from 75ms to 37ms

This commit is contained in:
Rui Ueyama 2020-10-23 08:40:54 +09:00
parent 8e19148923
commit dca18cad13
3 changed files with 47 additions and 17 deletions

View File

@ -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;
}
for (uint32_t i : entries)
sections[i] = nullptr;
g->lock.clear(std::memory_order_release);
if (file)
file->remove_comdat_members(idx);
}
}

View File

@ -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
View File

@ -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;