Skip to content

Commit acec641

Browse files
authored
[SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (llvm#74128)
Today `-split-machine-functions` and `-fbasic-block-sections={all,list}` cannot be combined with `-basic-block-sections=labels` (the labels option will be ignored). The inconsistency comes from the way basic block address map -- the underlying mechanism for basic block labels -- encodes basic block addresses (https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html). Specifically, basic block offsets are computed relative to the function begin symbol. This relies on functions being contiguous which is not the case for MFS and basic block section binaries. This means Propeller cannot use binary profiles collected from these binaries, which limits the applicability of Propeller for iterative optimization. To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section binaries, we propose modifying the encoding of this section as follows. First let us review the current encoding which emits the address of each function and its number of basic blocks, followed by basic block entries for each basic block. | | | |--|--| | Address of the function | Function Address | | Number of basic blocks in this function | NumBlocks | | BB entry 1 | BB entry 2 | ... | BB entry #NumBlocks To make this work for basic block sections, we treat each basic block section similar to a function, except that basic block sections of the same function must be encapsulated in the same structure so we can map all of them to their single function. We modify the encoding to first emit the number of basic block sections (BB ranges) in the function. Then we emit the address map of each basic block section section as before: the base address of the section, its number of blocks, and BB entries for its basic block. The first section in the BB address map is always the function entry section. | | | |--|--| | Number of sections for this function | NumBBRanges | | Section 1 begin address | BaseAddress[1] | | Number of basic blocks in section 1 | NumBlocks[1] | | BB entries for Section 1 |..................| | Section #NumBBRanges begin address | BaseAddress[NumBBRanges] | | Number of basic blocks in section #NumBBRanges | NumBlocks[NumBBRanges] | | BB entries for Section #NumBBRanges The encoding of basic block entries remains as before with the minor change that each basic block offset is now computed relative to the begin symbol of its containing BB section. This patch adds a new boolean codegen option `-basic-block-address-map`. Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD flag `--lto-basic-block-address-map` are introduced. Analogously, we add a new TargetOption field `BBAddrMap`. This means BB address maps are either generated for all functions in the compiling unit, or for none (depending on `TargetOptions::BBAddrMap`). This patch keeps the functionality of the old `-fbasic-block-sections=labels` option but does not remove it. A subsequent patch will remove the obsolete option. We refactor the `BasicBlockSections` pass by separating the BB address map and BB sections handing to their own functions (named `handleBBAddrMap` and `handleBBSections`). `handleBBSections` renumbers basic blocks and places them in their assigned sections. `handleBBAddrMap` is invoked after `handleBBSections` (if requested) and only renumbers the blocks. - New tests added: - Two tests basic-block-address-map-with-basic-block-sections.ll and basic-block-address-map-with-mfs.ll to exercise the combination of `-basic-block-address-map` with `-basic-block-sections=list` and '-split-machine-functions`. - A driver sanity test for the `-fbasic-block-address-map` option (basic-block-address-map.c). - An LLD test for testing the `--lto-basic-block-address-map` option. This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`. - Renamed and modified the two existing codegen tests for basic block address map (`basic-block-sections-labels-functions-sections.ll` and `basic-block-sections-labels.ll`) - Removed `SHT_LLVM_BB_ADDR_MAP_V0` tests. Full deprecation of `SHT_LLVM_BB_ADDR_MAP_V0` and `SHT_LLVM_BB_ADDR_MAP` version less than 2 will happen in a separate PR in a few months.
1 parent 70eab12 commit acec641

39 files changed

+1697
-1051
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT)
9696
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
9797
///< are required.
9898
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
99+
CODEGENOPT(BBAddrMap , 1, 0) ///< Set when -fbasic-block-address-map is enabled.
99100
CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
100101
///< enabled.
101102
CODEGENOPT(InstrumentFunctionsAfterInlining , 1, 0) ///< Set when

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,6 +3988,10 @@ defm function_sections : BoolFOption<"function-sections",
39883988
PosFlag<SetTrue, [], [ClangOption, CC1Option],
39893989
"Place each function in its own section">,
39903990
NegFlag<SetFalse>>;
3991+
defm basic_block_address_map : BoolFOption<"basic-block-address-map",
3992+
CodeGenOpts<"BBAddrMap">, DefaultFalse,
3993+
PosFlag<SetTrue, [], [CC1Option], "Emit the basic block address map section.">,
3994+
NegFlag<SetFalse>>;
39913995
def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group<f_Group>,
39923996
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
39933997
HelpText<"Place each function's basic blocks in unique sections (ELF Only)">,

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
374374
LangOptions::FPModeKind::FPM_FastHonorPragmas);
375375
Options.ApproxFuncFPMath = LangOpts.ApproxFunc;
376376

377+
Options.BBAddrMap = CodeGenOpts.BBAddrMap;
377378
Options.BBSections =
378379
llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
379380
.Case("all", llvm::BasicBlockSection::All)

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5944,6 +5944,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
59445944
CmdArgs.push_back("-ffunction-sections");
59455945
}
59465946

5947+
if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map,
5948+
options::OPT_fno_basic_block_address_map)) {
5949+
if (Triple.isX86() && Triple.isOSBinFormatELF()) {
5950+
if (A->getOption().matches(options::OPT_fbasic_block_address_map))
5951+
A->render(Args, CmdArgs);
5952+
} else {
5953+
D.Diag(diag::err_drv_unsupported_opt_for_target)
5954+
<< A->getAsString(Args) << TripleStr;
5955+
}
5956+
}
5957+
59475958
if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_sections_EQ)) {
59485959
StringRef Val = A->getValue();
59495960
if (Triple.isX86() && Triple.isOSBinFormatELF()) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang -### -target x86_64 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s
2+
// CHECK-PRESENT: -fbasic-block-address-map
3+
4+
// RUN: %clang -### -target x86_64 -fno-basic-block-address-map %s -S 2>&1 | FileCheck %s --check-prefix=CHECK-ABSENT
5+
// CHECK-ABSENT-NOT: -fbasic-block-address-map
6+
7+
// RUN: not %clang -c -target x86_64-apple-darwin10 -fbasic-block-address-map %s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s
8+
// CHECK-TRIPLE: error: unsupported option '-fbasic-block-address-map' for target

lld/ELF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ struct Config {
187187
llvm::StringRef cmseOutputLib;
188188
StringRef zBtiReport = "none";
189189
StringRef zCetReport = "none";
190+
bool ltoBBAddrMap;
190191
llvm::StringRef ltoBasicBlockSections;
191192
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
192193
llvm::StringRef thinLTOPrefixReplaceOld;

lld/ELF/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,9 @@ static void readConfigs(opt::InputArgList &args) {
12981298
config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
12991299
config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
13001300
config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
1301+
config->ltoBBAddrMap =
1302+
args.hasFlag(OPT_lto_basic_block_address_map,
1303+
OPT_no_lto_basic_block_address_map, false);
13011304
config->ltoBasicBlockSections =
13021305
args.getLastArgValue(OPT_lto_basic_block_sections);
13031306
config->ltoUniqueBasicBlockSectionNames =

lld/ELF/LTO.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ static lto::Config createConfig() {
6161
c.Options.FunctionSections = true;
6262
c.Options.DataSections = true;
6363

64+
c.Options.BBAddrMap = config->ltoBBAddrMap;
65+
6466
// Check if basic block sections must be used.
6567
// Allowed values for --lto-basic-block-sections are "all", "labels",
6668
// "<file name specifying basic block ids>", or none. This is the equivalent

lld/ELF/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,9 @@ def save_temps_eq: JJ<"save-temps=">, HelpText<"Save select intermediate LTO com
637637
Values<"resolution,preopt,promote,internalize,import,opt,precodegen,prelink,combinedindex">;
638638
def lto_basic_block_sections: JJ<"lto-basic-block-sections=">,
639639
HelpText<"Enable basic block sections for LTO">;
640+
defm lto_basic_block_address_map: BB<"lto-basic-block-address-map",
641+
"Emit basic block address map for LTO",
642+
"Do not emit basic block address map for LTO (default)">;
640643
defm lto_unique_basic_block_section_names: BB<"lto-unique-basic-block-section-names",
641644
"Give unique names to every basic block section for LTO",
642645
"Do not give unique names to every basic block section for LTO (default)">;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; REQUIRES: x86
2+
; RUN: llvm-as %s -o %t.o
3+
; RUN: ld.lld %t.o -o %t --lto-basic-block-address-map --lto-O0 --save-temps
4+
; RUN: llvm-readobj --sections %t.lto.o | FileCheck --check-prefix=SECNAMES %s
5+
6+
; SECNAMES: Type: SHT_LLVM_BB_ADDR_MAP
7+
8+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
9+
target triple = "x86_64-unknown-linux-gnu"
10+
11+
; Function Attrs: nounwind uwtable
12+
define dso_local void @foo(i32 %b) local_unnamed_addr {
13+
entry:
14+
%tobool.not = icmp eq i32 %b, 0
15+
br i1 %tobool.not, label %if.end, label %if.then
16+
17+
if.then: ; preds = %entry
18+
tail call void @foo(i32 0)
19+
br label %if.end
20+
21+
if.end: ; preds = %entry, %if.then
22+
ret void
23+
}
24+
25+
define void @_start() {
26+
call void @foo(i32 1)
27+
ret void
28+
}

0 commit comments

Comments
 (0)