mirror of
https://github.com/rui314/mold.git
synced 2024-11-11 16:58:12 +03:00
wip
This commit is contained in:
parent
50330975fe
commit
f28b7fc737
47
icf.cc
47
icf.cc
@ -1,16 +1,17 @@
|
||||
#include "mold.h"
|
||||
|
||||
#include <tbb/parallel_for_each.h>
|
||||
#include <tbb/partitioner.h>
|
||||
#include <tbb/task_arena.h>
|
||||
|
||||
static i64 current = 0;
|
||||
static i64 slot = 0;
|
||||
static thread_local i64 noneligible_id = 0;
|
||||
|
||||
static bool is_eligible(InputSection &x) {
|
||||
return (x.shdr.sh_flags & SHF_ALLOC) &&
|
||||
!(x.shdr.sh_flags & SHF_WRITE) &&
|
||||
!(x.shdr.sh_type == SHT_INIT_ARRAY || x.name == ".init") &&
|
||||
!(x.shdr.sh_type == SHT_FINI_ARRAY || x.name == ".fini");
|
||||
static bool is_eligible(InputSection &isec) {
|
||||
return (isec.shdr.sh_flags & SHF_ALLOC) &&
|
||||
!(isec.shdr.sh_flags & SHF_WRITE) &&
|
||||
!(isec.shdr.sh_type == SHT_INIT_ARRAY || isec.name == ".init") &&
|
||||
!(isec.shdr.sh_type == SHT_FINI_ARRAY || isec.name == ".fini");
|
||||
}
|
||||
|
||||
static u64 hash(u64 x) {
|
||||
@ -28,13 +29,13 @@ inline void hash_combine(u64 &seed, const T &val) {
|
||||
seed ^= hash(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
static u64 hash(InputSection &x) {
|
||||
static u64 hash(InputSection &isec) {
|
||||
u64 hv = 0;
|
||||
hash_combine(hv, x.shdr.sh_flags);
|
||||
hash_combine(hv, x.rels.size());
|
||||
hash_combine(hv, x.get_contents());
|
||||
hash_combine(hv, isec.shdr.sh_flags);
|
||||
hash_combine(hv, isec.rels.size());
|
||||
hash_combine(hv, isec.get_contents());
|
||||
|
||||
for (ElfRela &rel : x.rels) {
|
||||
for (ElfRela &rel : isec.rels) {
|
||||
hash_combine(hv, rel.r_offset);
|
||||
hash_combine(hv, rel.r_type);
|
||||
hash_combine(hv, rel.r_addend);
|
||||
@ -42,6 +43,14 @@ static u64 hash(InputSection &x) {
|
||||
return hv;
|
||||
}
|
||||
|
||||
static void propagate(InputSection &isec) {
|
||||
for (ElfRela &rel : isec.rels) {
|
||||
Symbol &sym = *isec.file->symbols[rel.r_sym];
|
||||
if (sym.input_section)
|
||||
sym.input_section->eq_class[slot] += isec.eq_class[slot ^ 1];
|
||||
}
|
||||
}
|
||||
|
||||
static bool equal(InputSection &x, InputSection &y) {
|
||||
if (x.shdr.sh_flags != y.shdr.sh_flags)
|
||||
return false;
|
||||
@ -79,7 +88,7 @@ static bool equal(InputSection &x, InputSection &y) {
|
||||
|
||||
InputSection &isecx = *symx.input_section;
|
||||
InputSection &isecy = *symy.input_section;
|
||||
if (isecx.eq_class[current] != isecy.eq_class[current])
|
||||
if (isecx.eq_class[slot] != isecy.eq_class[slot])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -101,4 +110,18 @@ void icf_sections() {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
slot ^= 1;
|
||||
|
||||
{
|
||||
Timer t2("propagate");
|
||||
for (i64 i = 0; i < 2; i++) {
|
||||
tbb::parallel_for_each(out::objs, [&](ObjectFile *file) {
|
||||
for (InputSection *isec : file->sections)
|
||||
if (isec)
|
||||
propagate(*isec);
|
||||
});
|
||||
slot ^= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user