Background
Today -split-machine-functions (MFS) 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.
New Encoding for BB Address Map
To make the BB address map feature work with BB section binaries, we propose modifying the encoding of the BB address map as follows.
The current encoding 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 | Address | -> 8 bytes (pointer size) |
Number of basic blocks in this function | NumBlocks | -> ULEB128 |
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) | -> ULEB128 |
Section 0 begin address | BaseAddress[0] | -> 8 bytes (pointer size) |
Number of basic blocks in section 0 | NumBlocks[0] | -> ULEB128 |
BB entries for Section 0 | ||
.
.
.
Section K begin address | BaseAddress[K] | -> 8 bytes (pointer size) |
Number of basic blocks in section K | NumBlocks[K] | -> ULEB128 |
BB entries for Section K | ||
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.
Option Processing
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 disables the old -fbasic-block-sections=labels value option but does not remove it. A subsequent patch will remove the obsolete option.
Pass Changes
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.
Tests
- New tests added:
- A codgen test basic-block-labels-with-sections.ll to exercise the combination of -basic-block-address-map with -basic-block-sections=list.
- A driver sanity test for the -fbasic-block-address-map option.
- 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)
Upstream will ask you to break up this patch, same thing happened with -funique-internal-linkage-names. I can think of the following break-up :