Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -175,6 +175,7 @@ llvm::Optional ImageBase; uint64_t MaxPageSize; uint64_t ZStackSize; + unsigned BloomFilterBits; unsigned LTOPartitions; unsigned LTOO; unsigned Optimize; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -594,6 +594,7 @@ Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs"); Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); + Config->BloomFilterBits = args::getInteger(Args, OPT_bloom_filter_bits, 8); Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); Config->Chroot = Args.getLastArgValue(OPT_chroot); Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -13,6 +13,8 @@ def auxiliary: S<"auxiliary">, HelpText<"Set DT_AUXILIARY field to the specified name">; +defm bloom_filter_bits: Eq<"bloom-filter-bits">; + def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">; def Bsymbolic_functions: F<"Bsymbolic-functions">, Index: lld/ELF/SyntheticSections.cpp =================================================================== --- lld/ELF/SyntheticSections.cpp +++ lld/ELF/SyntheticSections.cpp @@ -1706,7 +1706,7 @@ if (Symbols.empty()) MaskWords = 1; else - MaskWords = NextPowerOf2((Symbols.size() - 1) / Config->Wordsize); + MaskWords = NextPowerOf2(Symbols.size() * Config->BloomFilterBits / Config->Wordsize / 8); Size = 16; // Header Size += Config->Wordsize * MaskWords; // Bloom filter @@ -1749,6 +1749,14 @@ Val |= uint64_t(1) << ((Sym.Hash >> getShift2()) % C); writeUint(Buf + I * Config->Wordsize, Val); } + + ArrayRef Arr(Buf, Config->Wordsize * MaskWords); + message("Bloom filter size in bits: " + Twine(Arr.size() * 8)); + + size_t Ones = 0; + for (uint8_t Byte : Arr) + Ones += __builtin_popcount(Byte); + message(" # of 1 bits: " + Twine(Ones) + " (" + Twine((int)((double)Ones / Arr.size() * 8)) + "%)"); } void GnuHashTableSection::writeHashTable(uint8_t *Buf) {