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)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
main.cc
3
main.cc
@ -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
18
mold.h
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user