1
1
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:
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) if (entries[0] != GRP_COMDAT)
error(toString(this) + ": unsupported SHT_GROUP format"); error(toString(this) + ": unsupported SHT_GROUP format");
static ConcurrentMap<bool> map; static ConcurrentMap<ComdatGroup> map;
bool *handle = map.insert(signature, false); ComdatGroup *group = map.insert(signature, ComdatGroup(this, i));
comdat_groups.push_back({handle, entries}); comdat_groups.push_back({group, i});
num_comdats++; num_comdats++;
break; 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) { void ObjectFile::read_string_pieces(const ELF64LE::Shdr &shdr) {
static ConcurrentMap<StringPiece> map1; static ConcurrentMap<StringPiece> map1;
static ConcurrentMap<StringPiece> map2; static ConcurrentMap<StringPiece> map2;
@ -208,17 +216,28 @@ void ObjectFile::register_undefined_symbols() {
} }
void ObjectFile::eliminate_duplicate_comdat_groups() { void ObjectFile::eliminate_duplicate_comdat_groups() {
for (std::pair<bool *, ArrayRef<ELF64LE::Word>> pair : comdat_groups) { for (auto &pair : comdat_groups) {
bool *handle = pair.first; ComdatGroup *g = pair.first;
ArrayRef<ELF64LE::Word> entries = pair.second; uint32_t section_idx = pair.second;
if (!*handle) { ObjectFile *file = nullptr;
*handle = true; uint32_t idx = 0;
continue;
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);
} }
} }

View File

@ -224,8 +224,7 @@ int main(int argc, char **argv) {
// Eliminate duplicate comdat groups. // Eliminate duplicate comdat groups.
comdat_timer.startTimer(); comdat_timer.startTimer();
for (ObjectFile *file : files) for_each(files, [](ObjectFile *file) { file->eliminate_duplicate_comdat_groups(); });
file->eliminate_duplicate_comdat_groups();
comdat_timer.stopTimer(); comdat_timer.stopTimer();
// Bin input sections into output sections // Bin input sections into output sections

18
mold.h
View File

@ -349,10 +349,21 @@ extern StringTableSection *shstrtab;
// input_files.cc // input_files.cc
// //
class StringPiece { struct ComdatGroup {
public: 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(StringRef data) : data(data) {}
StringPiece(const StringPiece &other) : data(other.data) {} StringPiece(const StringPiece &other) : data(other.data) {}
StringRef data; StringRef data;
std::atomic_flag flag = ATOMIC_FLAG_INIT; std::atomic_flag flag = ATOMIC_FLAG_INIT;
}; };
@ -377,11 +388,12 @@ public:
private: private:
void initialize_sections(); void initialize_sections();
void initialize_symbols(); void initialize_symbols();
void remove_comdat_members(uint32_t section_idx);
void read_string_pieces(const ELF64LE::Shdr &shdr); void read_string_pieces(const ELF64LE::Shdr &shdr);
MemoryBufferRef mb; MemoryBufferRef mb;
std::vector<Symbol *> symbols; 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_alloc;
std::vector<StringPiece *> merged_strings_noalloc; std::vector<StringPiece *> merged_strings_noalloc;