Skip to content

Commit dc3fbc0

Browse files
committed
[lld-macho] Implement symbol string deduplication
1 parent 4564ac9 commit dc3fbc0

File tree

6 files changed

+35
-2
lines changed

6 files changed

+35
-2
lines changed

lld/MachO/Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ struct Configuration {
256256
llvm::MachO::PlatformType platform() const {
257257
return platformInfo.target.Platform;
258258
}
259+
260+
bool deduplicateSymbolStrings = true;
259261
};
260262

261263
extern std::unique_ptr<Configuration> config;

lld/MachO/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,8 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
18061806
config->keepICFStabs = args.hasArg(OPT_keep_icf_stabs);
18071807
config->dedupStrings =
18081808
args.hasFlag(OPT_deduplicate_strings, OPT_no_deduplicate_strings, true);
1809+
config->deduplicateSymbolStrings =
1810+
!args.hasArg(OPT_no_deduplicate_symbol_strings);
18091811
config->deadStripDuplicates = args.hasArg(OPT_dead_strip_duplicates);
18101812
config->warnDylibInstallName = args.hasFlag(
18111813
OPT_warn_dylib_install_name, OPT_no_warn_dylib_install_name, false);

lld/MachO/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,3 +1476,8 @@ def no_warn_duplicate_libraries : Flag<["-"], "no_warn_duplicate_libraries">,
14761476
HelpText<"Do not warn if the input contains duplicate library options.">,
14771477
Flags<[HelpHidden]>,
14781478
Group<grp_ignored_silently>;
1479+
1480+
// Add this with the other flags in the rare options group
1481+
def no_deduplicate_symbol_strings : Flag<["-"], "no-deduplicate-symbol-strings">,
1482+
HelpText<"Do not deduplicate strings in the symbol string table. Might result in larger binaries but slightly faster link times.">,
1483+
Group<grp_rare>;

lld/MachO/SyntheticSections.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,9 +1540,24 @@ StringTableSection::StringTableSection()
15401540
: LinkEditSection(segment_names::linkEdit, section_names::stringTable) {}
15411541

15421542
uint32_t StringTableSection::addString(StringRef str) {
1543+
// If deduplication is disabled, just add the string
1544+
if (!config->deduplicateSymbolStrings) {
1545+
uint32_t strx = size;
1546+
strings.push_back(str);
1547+
size += str.size() + 1; // +1 for null terminator
1548+
return strx;
1549+
}
1550+
1551+
// Deduplicate strings
1552+
llvm::CachedHashStringRef hashedStr(str);
1553+
auto it = stringMap.find(hashedStr);
1554+
if (it != stringMap.end())
1555+
return it->second;
1556+
15431557
uint32_t strx = size;
1544-
strings.push_back(str); // TODO: consider deduplicating strings
1545-
size += str.size() + 1; // account for null terminator
1558+
stringMap[hashedStr] = strx;
1559+
strings.push_back(str);
1560+
size += str.size() + 1;
15461561
return strx;
15471562
}
15481563

lld/MachO/SyntheticSections.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ class StringTableSection final : public LinkEditSection {
447447
// match its behavior here since some tools depend on it.
448448
// Consequently, the empty string will be at index 1, not zero.
449449
std::vector<StringRef> strings{" "};
450+
llvm::DenseMap<llvm::CachedHashStringRef, uint32_t> stringMap;
450451
size_t size = 2;
451452
};
452453

lld/test/MachO/cfstring-dedup.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
# RUN: %lld -dylib -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
88
# RUN: llvm-objdump --no-print-imm-hex --macho --rebase --bind --syms -d %t/foo | FileCheck %s --check-prefix=LITERALS
99

10+
# Check that string deduplication for symbol names is working
11+
# RUN: %lld -dylib -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo_no_dedup -no-deduplicate-symbol-strings
12+
# RUN: count1=$((`llvm-strings %t/foo | grep _named_cfstring | wc -l`))
13+
# RUN: test $count1 -eq 1
14+
# RUN: count2=$((`llvm-strings %t/foo_no_dedup | grep _named_cfstring | wc -l`))
15+
# RUN: test $count2 -eq 2
16+
17+
1018
# CHECK: (__TEXT,__text) section
1119
# CHECK-NEXT: _foo1:
1220
# CHECK-NEXT: _foo2:

0 commit comments

Comments
 (0)