[ELF] Change --call-graph-profile-sort to accept an argument

Change the FF form --call-graph-profile-sort to --call-graph-profile-sort={none,hfsort}.
This will be extended to support llvm/lib/Transforms/Utils/CodeLayout.cpp.

--call-graph-profile-sort is not used in the wild but
--no-call-graph-profile-sort is (Chromium). Make --no-call-graph-profile-sort an
alias for --call-graph-profile-sort=none.

Reviewed By: rahmanl

Differential Revision: https://reviews.llvm.org/D159544
This commit is contained in:
Fangrui Song 2023-09-25 09:49:40 -07:00
parent 1db42fa6f0
commit 8c556b7e2b
6 changed files with 46 additions and 10 deletions

View File

@ -59,6 +59,9 @@ enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All };
// For --build-id.
enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
// For --call-graph-profile-sort={none,hfsort}.
enum class CGProfileSortKind { None, Hfsort };
// For --discard-{all,locals,none}.
enum class DiscardPolicy { Default, All, Locals, None };
@ -215,7 +218,7 @@ struct Config {
bool asNeeded = false;
bool armBe8 = false;
BsymbolicKind bsymbolic = BsymbolicKind::None;
bool callGraphProfileSort;
CGProfileSortKind callGraphProfileSort;
bool checkSections;
bool checkDynamicRelocs;
llvm::DebugCompressionType compressDebugSections;

View File

@ -1094,6 +1094,15 @@ static void ltoValidateAllVtablesHaveTypeInfos(opt::InputArgList &args) {
}
}
static CGProfileSortKind getCGProfileSortKind(opt::InputArgList &args) {
StringRef s = args.getLastArgValue(OPT_call_graph_profile_sort, "hfsort");
if (s == "hfsort")
return CGProfileSortKind::Hfsort;
if (s != "none")
error("unknown --call-graph-profile-sort= value: " + s);
return CGProfileSortKind::None;
}
static DebugCompressionType getCompressionType(StringRef s, StringRef option) {
DebugCompressionType type = StringSwitch<DebugCompressionType>(s)
.Case("zlib", DebugCompressionType::Zlib)
@ -1229,6 +1238,7 @@ static void readConfigs(opt::InputArgList &args) {
else if (arg->getOption().matches(OPT_Bsymbolic))
config->bsymbolic = BsymbolicKind::All;
}
config->callGraphProfileSort = getCGProfileSortKind(args);
config->checkSections =
args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
config->chroot = args.getLastArgValue(OPT_chroot);
@ -1249,8 +1259,6 @@ static void readConfigs(opt::InputArgList &args) {
args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
config->emitLLVM = args.hasArg(OPT_plugin_opt_emit_llvm, false);
config->emitRelocs = args.hasArg(OPT_emit_relocs);
config->callGraphProfileSort = args.hasFlag(
OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
config->enableNewDtags =
args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
config->entry = args.getLastArgValue(OPT_entry);
@ -1669,7 +1677,7 @@ static void readConfigs(opt::InputArgList &args) {
config->symbolOrderingFile = getSymbolOrderingFile(*buffer);
// Also need to disable CallGraphProfileSort to prevent
// LLD order symbols with CGProfile
config->callGraphProfileSort = false;
config->callGraphProfileSort = CGProfileSortKind::None;
}
}
@ -3072,7 +3080,7 @@ void LinkerDriver::link(opt::InputArgList &args) {
}
// Read the callgraph now that we know what was gced or icfed
if (config->callGraphProfileSort) {
if (config->callGraphProfileSort != CGProfileSortKind::None) {
if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
if (std::optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
readCallGraph(*buffer);

View File

@ -128,9 +128,12 @@ defm as_needed: B<"as-needed",
defm call_graph_ordering_file:
Eq<"call-graph-ordering-file", "Layout sections to optimize the given callgraph">;
defm call_graph_profile_sort: BB<"call-graph-profile-sort",
"Reorder sections with call graph profile (default)",
"Do not reorder sections with call graph profile">;
def call_graph_profile_sort: JJ<"call-graph-profile-sort=">,
HelpText<"Reorder input sections with call graph profile using the specified algorithm (default: hfsort)">,
MetaVarName<"[none,hfsort]">,
Values<"none,hfsort">;
def : FF<"no-call-graph-profile-sort">, Alias<call_graph_profile_sort>, AliasArgs<["none"]>,
Flags<[HelpHidden]>;
// --chroot doesn't have a help text because it is an internal option.
def chroot: Separate<["--"], "chroot">;

View File

@ -120,6 +120,17 @@ is not intended to be cryptographically secure.
.It Fl -build-id
Synonym for
.Fl -build-id Ns = Ns Cm fast .
.It Fl -call-graph-profile-sort Ns = Ns Ar algorithm
.Ar algorithm
may be:
.Pp
.Bl -tag -width 2n -compact
.It Cm none
Ignore call graph profile.
.It Cm hfsort
Use hfsort (default).
.El
.Pp
.It Fl -color-diagnostics Ns = Ns Ar value
Use colors in diagnostics.
.Ar value

View File

@ -3,8 +3,11 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld -e A %t.o -o %t
# RUN: llvm-nm --no-sort %t | FileCheck %s
# RUN: ld.lld --no-call-graph-profile-sort -e A %t.o -o %t
# RUN: ld.lld --call-graph-profile-sort=none -e A %t.o -o %t
# RUN: llvm-nm --no-sort %t | FileCheck %s --check-prefix=NO-CG
## --no-call-graph-profile-sort is an alias for --call-graph-profile-sort=none.
# RUN: ld.lld --no-call-graph-profile-sort -e A %t.o -o %t1
# RUN: cmp %t %t1
.section .text.D,"ax",@progbits
D:

View File

@ -24,8 +24,16 @@
# RUN: echo "TooManyPreds8 TooManyPreds 10" >> %t.call_graph
# RUN: echo "TooManyPreds9 TooManyPreds 10" >> %t.call_graph
# RUN: echo "TooManyPreds10 TooManyPreds 11" >> %t.call_graph
# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph --call-graph-profile-sort=hfsort -o %t2
# RUN: llvm-readobj --symbols %t2 | FileCheck %s
## --call-graph-profile-sort=hfsort is the default.
# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2b
# RUN: cmp %t2 %t2b
# RUN: not ld.lld -e A %t --call-graph-ordering-file %t.call_graph --call-graph-profile-sort=sort \
# RUN: -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNKNOWN
# UNKNOWN: error: unknown --call-graph-profile-sort= value: sort
.section .text.D,"ax",@progbits
D: