diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 60f76d1214104..d41ca5382c692 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -222,11 +222,12 @@ struct Configuration { bool callGraphProfileSort = false; llvm::StringRef printSymbolOrder; - llvm::StringRef irpgoProfileSortProfilePath; - bool compressionSortStartupFunctions = false; - bool functionOrderForCompression = false; - bool dataOrderForCompression = false; - bool verboseBpSectionOrderer = false; + llvm::StringRef irpgoProfilePath; + bool bpStartupFunctionSort = false; + bool bpCompressionSortStartupFunctions = false; + bool bpFunctionOrderForCompression = false; + bool bpDataOrderForCompression = false; + bool bpVerboseSectionOrderer = false; SectionRenameMap sectionRenameMap; SegmentRenameMap segmentRenameMap; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index c95841d3a8ade..7550b0b9fa531 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1838,26 +1838,47 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, if (const Arg *arg = args.getLastArgNoClaim(OPT_call_graph_profile_sort)) error(firstArgStr + " is incompatible with " + arg->getSpelling()); }; + if (args.hasArg(OPT_irpgo_profile_sort) || + args.hasArg(OPT_irpgo_profile_sort_eq)) + warn("--irpgo-profile-sort is deprecated. Please use " + "--bp-startup-sort=function"); + if (const Arg *arg = args.getLastArg(OPT_irpgo_profile_eq)) + config->irpgoProfilePath = arg->getValue(); + if (const Arg *arg = args.getLastArg(OPT_irpgo_profile_sort)) { - config->irpgoProfileSortProfilePath = arg->getValue(); + config->irpgoProfilePath = arg->getValue(); + config->bpStartupFunctionSort = true; 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)) { + config->bpCompressionSortStartupFunctions = + args.hasFlag(OPT_bp_compression_sort_startup_functions, + OPT_no_bp_compression_sort_startup_functions, false); + if (const Arg *arg = args.getLastArg(OPT_bp_startup_sort)) { + StringRef startupSortStr = arg->getValue(); + if (startupSortStr == "function") { + config->bpStartupFunctionSort = true; + } else if (startupSortStr != "none") { + error("unknown value `" + startupSortStr + "` for " + arg->getSpelling()); + } + if (startupSortStr != "none") + IncompatWithCGSort(arg->getSpelling()); + } + if (!config->bpStartupFunctionSort && + config->bpCompressionSortStartupFunctions) + error("--bp-compression-sort-startup-functions must be used with " + "--bp-startup-sort=function"); + if (config->irpgoProfilePath.empty() && config->bpStartupFunctionSort) + error("--bp-startup-sort=function must be used with " + "--irpgo-profile"); + if (const Arg *arg = args.getLastArg(OPT_bp_compression_sort)) { StringRef compressionSortStr = arg->getValue(); if (compressionSortStr == "function") { - config->functionOrderForCompression = true; + config->bpFunctionOrderForCompression = true; } else if (compressionSortStr == "data") { - config->dataOrderForCompression = true; + config->bpDataOrderForCompression = true; } else if (compressionSortStr == "both") { - config->functionOrderForCompression = true; - config->dataOrderForCompression = true; + config->bpFunctionOrderForCompression = true; + config->bpDataOrderForCompression = true; } else if (compressionSortStr != "none") { error("unknown value `" + compressionSortStr + "` for " + arg->getSpelling()); @@ -1865,7 +1886,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, if (compressionSortStr != "none") IncompatWithCGSort(arg->getSpelling()); } - config->verboseBpSectionOrderer = args.hasArg(OPT_verbose_bp_section_orderer); + config->bpVerboseSectionOrderer = args.hasArg(OPT_verbose_bp_section_orderer); for (const Arg *arg : args.filtered(OPT_alias)) { config->aliasedSymbols.push_back( diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 485e5968ff556..1d7f1d806cc7f 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -126,19 +126,34 @@ def no_call_graph_profile_sort : Flag<["--"], "no-call-graph-profile-sort">, def print_symbol_order_eq: Joined<["--"], "print-symbol-order=">, HelpText<"Print a symbol order specified by --call-graph-profile-sort into the specified file">, Group; +def irpgo_profile_eq: Joined<["--"], "irpgo-profile=">, + HelpText<"Read the IRPGO profile for use with -bp-startup-sort and other profile-guided optimizations">, + Group; +def bp_startup_sort: Joined<["--"], "bp-startup-sort=">, + MetaVarName<"[none,function]">, + HelpText<"Order sections based on profile data to improve startup time">, + Group; +def bp_compression_sort_startup_functions: Flag<["--"], "bp-compression-sort-startup-functions">, + HelpText<"Order startup functions to improve compressed size in addition to startup time">, + Group; +def no_bp_compression_sort_startup_functions: Flag<["--"], "no-bp-compression-sort-startup-functions">, + HelpText<"Do not order startup function for compression">, Group; +def bp_compression_sort: Joined<["--"], "bp-compression-sort=">, + MetaVarName<"[none,function,data,both]">, + HelpText<"Order sections to improve compressed size">, Group; def irpgo_profile_sort: Separate<["--"], "irpgo-profile-sort">, Group; def irpgo_profile_sort_eq: Joined<["--"], "irpgo-profile-sort=">, Alias(irpgo_profile_sort)>, MetaVarName<"">, - HelpText<"Read the IRPGO profile at to order sections to improve startup time">, + HelpText<"Deprecated. Please use --irpgo-profile and --bp-startup-sort=function">, Group; def compression_sort_startup_functions: Flag<["--"], "compression-sort-startup-functions">, - HelpText<"Order startup functions to improve compressed size in addition to startup time">, - Group; + Alias(bp_compression_sort_startup_functions)>, HelpText<"Deprecated. Please use --bp-compression-sort-startup-functions">, Group; def no_compression_sort_startup_functions: Flag<["--"], "no-compression-sort-startup-functions">, - HelpText<"Do not order startup function for compression">, Group; + Alias(no_bp_compression_sort_startup_functions)>, HelpText<"Deprecated. Please use --no-bp-compression-sort-startup-functions">, Group; def compression_sort: Joined<["--"], "compression-sort=">, MetaVarName<"[none,function,data,both]">, - HelpText<"Order sections to improve compressed size">, Group; + Alias(bp_compression_sort)>, + HelpText<"Deprecated. Please use --bp-compression-sort=">, Group; def verbose_bp_section_orderer: Flag<["--"], "verbose-bp-section-orderer">, HelpText<"Print information on how many sections were ordered by balanced partitioning and a measure of the expected number of page faults">, Group; diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp index 1e7fb5973b808..0a15112c1250d 100644 --- a/lld/MachO/SectionPriorities.cpp +++ b/lld/MachO/SectionPriorities.cpp @@ -353,14 +353,16 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) { DenseMap macho::PriorityBuilder::buildInputSectionPriorities() { DenseMap sectionPriorities; - if (!config->irpgoProfileSortProfilePath.empty() || - config->functionOrderForCompression || config->dataOrderForCompression) { + if (config->bpStartupFunctionSort || config->bpFunctionOrderForCompression || + config->bpDataOrderForCompression) { TimeTraceScope timeScope("Balanced Partitioning Section Orderer"); sectionPriorities = runBalancedPartitioning( - highestAvailablePriority, config->irpgoProfileSortProfilePath, - config->functionOrderForCompression, config->dataOrderForCompression, - config->compressionSortStartupFunctions, - config->verboseBpSectionOrderer); + highestAvailablePriority, + config->bpStartupFunctionSort ? config->irpgoProfilePath : "", + config->bpFunctionOrderForCompression, + config->bpDataOrderForCompression, + config->bpCompressionSortStartupFunctions, + config->bpVerboseSectionOrderer); } else if (config->callGraphProfileSort) { // Sort sections by the profile data provided by __LLVM,__cg_profile // sections. diff --git a/lld/test/MachO/bp-section-orderer-errs.s b/lld/test/MachO/bp-section-orderer-errs.s index 682eb0c08bf1f..8d19e01c716ea 100644 --- a/lld/test/MachO/bp-section-orderer-errs.s +++ b/lld/test/MachO/bp-section-orderer-errs.s @@ -1,12 +1,21 @@ -# RUN: not %lld -o /dev/null --irpgo-profile-sort %s --call-graph-profile-sort 2>&1 | FileCheck %s --check-prefix=IRPGO-ERR -# RUN: not %lld -o /dev/null --irpgo-profile-sort=%s --call-graph-profile-sort 2>&1 | FileCheck %s --check-prefix=IRPGO-ERR +# RUN: not %no-fatal-warnings-lld -o /dev/null --irpgo-profile-sort %s --call-graph-profile-sort 2>&1 | FileCheck %s --check-prefix=IRPGO-ERR +# RUN: not %no-fatal-warnings-lld -o /dev/null --irpgo-profile-sort=%s --call-graph-profile-sort 2>&1 | FileCheck %s --check-prefix=IRPGO-ERR # IRPGO-ERR: --irpgo-profile-sort is incompatible with --call-graph-profile-sort # RUN: not %lld -o /dev/null --compression-sort=function --call-graph-profile-sort %s 2>&1 | FileCheck %s --check-prefix=COMPRESSION-ERR -# COMPRESSION-ERR: --compression-sort= is incompatible with --call-graph-profile-sort +# RUN: not %lld -o /dev/null --bp-compression-sort=function --call-graph-profile-sort %s 2>&1 | FileCheck %s --check-prefix=COMPRESSION-ERR +# COMPRESSION-ERR: --bp-compression-sort= is incompatible with --call-graph-profile-sort # 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 --bp-compression-sort=malformed 2>&1 | FileCheck %s --check-prefix=COMPRESSION-MALFORM +# COMPRESSION-MALFORM: unknown value `malformed` for --bp-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 +# RUN: not %lld -o /dev/null --bp-compression-sort-startup-functions 2>&1 | FileCheck %s --check-prefix=STARTUP +# STARTUP: --bp-compression-sort-startup-functions must be used with --bp-startup-sort=function + +# RUN: not %lld -o /dev/null --irpgo-profile=%s --bp-startup-sort=function --call-graph-profile-sort 2>&1 | FileCheck %s --check-prefix=IRPGO-STARTUP +# IRPGO-STARTUP: --bp-startup-sort= is incompatible with --call-graph-profile-sort + +# RUN: not %lld -o /dev/null --bp-startup-sort=function 2>&1 | FileCheck %s --check-prefix=STARTUP-COMPRESSION +# STARTUP-COMPRESSION: --bp-startup-sort=function must be used with --irpgo-profile \ No newline at end of file diff --git a/lld/test/MachO/bp-section-orderer-stress.s b/lld/test/MachO/bp-section-orderer-stress.s index 986e2d8fd1069..0bfd99eb3dd86 100644 --- a/lld/test/MachO/bp-section-orderer-stress.s +++ b/lld/test/MachO/bp-section-orderer-stress.s @@ -7,10 +7,13 @@ # 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-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: %no-fatal-warnings-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: %no-fatal-warnings-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 +# RUN: %lld -arch arm64 -lSystem -e _main --icf=all -o - %t.o --irpgo-profile=%t.profdata --bp-startup-sort=function --bp-compression-sort-startup-functions --bp-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=%t.profdata --bp-startup-sort=function --bp-compression-sort-startup-functions --bp-compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - > %t.order2.txt +# RUN: diff %t.order1.txt %t.order2.txt import random import sys diff --git a/lld/test/MachO/bp-section-orderer.s b/lld/test/MachO/bp-section-orderer.s index f220a08aff0f8..e5d0e7137b30d 100644 --- a/lld/test/MachO/bp-section-orderer.s +++ b/lld/test/MachO/bp-section-orderer.s @@ -4,15 +4,20 @@ # RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/a.s -o %t/a.o # RUN: llvm-profdata merge %t/a.proftext -o %t/a.profdata -# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP -# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer --icf=all --compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP +# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP +# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer --icf=all --compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile=%t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile=%t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer --icf=all --bp-compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP # STARTUP: Ordered 3 sections using balanced partitioning # Check that orderfiles take precedence over BP -# RUN: %lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --irpgo-profile-sort=%t/a.profdata | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE +# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --irpgo-profile-sort=%t/a.profdata | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE # RUN: %lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE +# RUN: %lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --irpgo-profile=%t/a.profdata --bp-startup-sort=function | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE +# RUN: %lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --bp-compression-sort=both | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE + # Functions # ORDERFILE: A # ORDERFILE: F @@ -34,7 +39,12 @@ # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --compression-sort=function 2>&1 | FileCheck %s --check-prefix=COMPRESSION-FUNC # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --compression-sort=data 2>&1 | FileCheck %s --check-prefix=COMPRESSION-DATA # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --compression-sort=both 2>&1 | FileCheck %s --check-prefix=COMPRESSION-BOTH -# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --compression-sort=both --irpgo-profile-sort=%t/a.profdata 2>&1 | FileCheck %s --check-prefix=COMPRESSION-BOTH +# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --compression-sort=both --irpgo-profile-sort=%t/a.profdata 2>&1 | FileCheck %s --check-prefix=COMPRESSION-BOTH + +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --bp-compression-sort=function 2>&1 | FileCheck %s --check-prefix=COMPRESSION-FUNC +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --bp-compression-sort=data 2>&1 | FileCheck %s --check-prefix=COMPRESSION-DATA +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --bp-compression-sort=both 2>&1 | FileCheck %s --check-prefix=COMPRESSION-BOTH +# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --verbose-bp-section-orderer --bp-compression-sort=both --irpgo-profile=%t/a.profdata --bp-startup-sort=function 2>&1 | FileCheck %s --check-prefix=COMPRESSION-BOTH # COMPRESSION-FUNC: Ordered 7 sections using balanced partitioning # COMPRESSION-DATA: Ordered 7 sections using balanced partitioning