Skip to content

[lld][InstrProf] Sort startup functions for compression #107348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions lld/MachO/BPSectionOrderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ static SmallVector<std::pair<unsigned, UtilityNodes>> getUnsForCompression(

DenseMap<const InputSection *, size_t> lld::macho::runBalancedPartitioning(
size_t &highestAvailablePriority, StringRef profilePath,
bool forFunctionCompression, bool forDataCompression, bool verbose) {
bool forFunctionCompression, bool forDataCompression,
bool compressionSortStartupFunctions, bool verbose) {

SmallVector<const InputSection *> sections;
DenseMap<const InputSection *, uint64_t> sectionToIdx;
Expand Down Expand Up @@ -268,8 +269,24 @@ DenseMap<const InputSection *, size_t> lld::macho::runBalancedPartitioning(
}
}

// Map a section index (to be ordered for compression) to a list of duplicate
// section indices (not ordered for compression).
if (compressionSortStartupFunctions) {
SmallVector<unsigned> startupIdxs;
for (auto &[sectionIdx, uns] : startupSectionIdxUNs)
startupIdxs.push_back(sectionIdx);
auto unsForStartupFunctionCompression =
getUnsForCompression(sections, sectionToIdx, startupIdxs,
/*duplicateSectionIdxs=*/nullptr, maxUN);
for (auto &[sectionIdx, compressionUns] :
unsForStartupFunctionCompression) {
auto &uns = startupSectionIdxUNs[sectionIdx];
uns.append(compressionUns);
llvm::sort(uns);
uns.erase(std::unique(uns.begin(), uns.end()), uns.end());
}
}

// Map a section index (order directly) to a list of duplicate section indices
// (not ordered directly).
DenseMap<unsigned, SmallVector<unsigned>> duplicateSectionIdxs;
auto unsForFunctionCompression = getUnsForCompression(
sections, sectionToIdx, sectionIdxsForFunctionCompression,
Expand Down
2 changes: 1 addition & 1 deletion lld/MachO/BPSectionOrderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ llvm::DenseMap<const lld::macho::InputSection *, size_t>
runBalancedPartitioning(size_t &highestAvailablePriority,
llvm::StringRef profilePath,
bool forFunctionCompression, bool forDataCompression,
bool verbose);
bool compressionSortStartupFunctions, bool verbose);

} // namespace lld::macho

Expand Down
1 change: 1 addition & 0 deletions lld/MachO/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ struct Configuration {
llvm::StringRef printSymbolOrder;

llvm::StringRef irpgoProfileSortProfilePath;
bool compressionSortStartupFunctions = false;
bool functionOrderForCompression = false;
bool dataOrderForCompression = false;
bool verboseBpSectionOrderer = false;
Expand Down
7 changes: 7 additions & 0 deletions lld/MachO/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,13 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->irpgoProfileSortProfilePath = arg->getValue();
IncompatWithCGSort(arg->getSpelling());
}
config->compressionSortStartupFunctions =
args.hasFlag(OPT_compression_sort_startup_functions,
OPT_no_compression_sort_startup_functions, false);
if (config->irpgoProfileSortProfilePath.empty() &&
config->compressionSortStartupFunctions)
error("--compression-sort-startup-functions must be used with "
"--irpgo-profile-sort");
if (const Arg *arg = args.getLastArg(OPT_compression_sort)) {
StringRef compressionSortStr = arg->getValue();
if (compressionSortStr == "function") {
Expand Down
5 changes: 5 additions & 0 deletions lld/MachO/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ def irpgo_profile_sort_eq: Joined<["--"], "irpgo-profile-sort=">,
Alias<!cast<Separate>(irpgo_profile_sort)>, MetaVarName<"<profile>">,
HelpText<"Read the IRPGO profile at <profile> to order sections to improve startup time">,
Group<grp_lld>;
def compression_sort_startup_functions: Flag<["--"], "compression-sort-startup-functions">,
HelpText<"Order startup functions to improve compressed size in addition to startup time">,
Group<grp_lld>;
def no_compression_sort_startup_functions: Flag<["--"], "no-compression-sort-startup-functions">,
HelpText<"Do not order startup function for compression">, Group<grp_lld>;
def compression_sort: Joined<["--"], "compression-sort=">,
MetaVarName<"[none,function,data,both]">,
HelpText<"Order sections to improve compressed size">, Group<grp_lld>;
Expand Down
1 change: 1 addition & 0 deletions lld/MachO/SectionPriorities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ macho::PriorityBuilder::buildInputSectionPriorities() {
sectionPriorities = runBalancedPartitioning(
highestAvailablePriority, config->irpgoProfileSortProfilePath,
config->functionOrderForCompression, config->dataOrderForCompression,
config->compressionSortStartupFunctions,
config->verboseBpSectionOrderer);
} else if (config->callGraphProfileSort) {
// Sort sections by the profile data provided by __LLVM,__cg_profile
Expand Down
3 changes: 3 additions & 0 deletions lld/test/MachO/bp-section-orderer-errs.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@

# RUN: not %lld -o /dev/null --compression-sort=malformed 2>&1 | FileCheck %s --check-prefix=COMPRESSION-MALFORM
# COMPRESSION-MALFORM: unknown value `malformed` for --compression-sort=

# RUN: not %lld -o /dev/null --compression-sort-startup-functions 2>&1 | FileCheck %s --check-prefix=STARTUP
# STARTUP: --compression-sort-startup-functions must be used with --irpgo-profile-sort
4 changes: 2 additions & 2 deletions lld/test/MachO/bp-section-orderer-stress.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t.s -o %t.o
# RUN: llvm-profdata merge %t.proftext -o %t.profdata

# RUN: %lld -arch arm64 -lSystem -e _main --icf=all -o - %t.o --irpgo-profile-sort=%t.profdata --compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - > %t.order1.txt
# RUN: %lld -arch arm64 -lSystem -e _main --icf=all -o - %t.o --irpgo-profile-sort=%t.profdata --compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - > %t.order2.txt
# RUN: %lld -arch arm64 -lSystem -e _main --icf=all -o - %t.o --irpgo-profile-sort=%t.profdata --compression-sort-startup-functions --compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - > %t.order1.txt
# RUN: %lld -arch arm64 -lSystem -e _main --icf=all -o - %t.o --irpgo-profile-sort=%t.profdata --compression-sort-startup-functions --compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - > %t.order2.txt
# RUN: diff %t.order1.txt %t.order2.txt

import random
Expand Down
Loading