Skip to content

Commit 08c749d

Browse files
committed
Merge branch 'main' into pauth-lld & fix conflict after 2763353
2 parents 83eddae + ba6b2d2 commit 08c749d

File tree

1,882 files changed

+66446
-22216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,882 files changed

+66446
-22216
lines changed

.ci/monolithic-linux.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ set -o pipefail
1818

1919
MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
2020
BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build}"
21-
rm -rf ${BUILD_DIR}
21+
rm -rf "${BUILD_DIR}"
2222

2323
ccache --zero-stats
2424

@@ -37,8 +37,8 @@ projects="${1}"
3737
targets="${2}"
3838

3939
echo "--- cmake"
40-
pip install -q -r ${MONOREPO_ROOT}/mlir/python/requirements.txt
41-
cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \
40+
pip install -q -r "${MONOREPO_ROOT}"/mlir/python/requirements.txt
41+
cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \
4242
-D LLVM_ENABLE_PROJECTS="${projects}" \
4343
-G Ninja \
4444
-D CMAKE_BUILD_TYPE=Release \

.ci/monolithic-windows.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ set -o pipefail
1919
MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
2020
BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build}"
2121

22-
rm -rf ${BUILD_DIR}
22+
rm -rf "${BUILD_DIR}"
2323

2424
if [[ -n "${CLEAR_CACHE:-}" ]]; then
2525
echo "clearing sccache"
@@ -37,14 +37,14 @@ projects="${1}"
3737
targets="${2}"
3838

3939
echo "--- cmake"
40-
pip install -q -r ${MONOREPO_ROOT}/mlir/python/requirements.txt
40+
pip install -q -r "${MONOREPO_ROOT}"/mlir/python/requirements.txt
4141

4242
# The CMAKE_*_LINKER_FLAGS to disable the manifest come from research
4343
# on fixing a build reliability issue on the build server, please
4444
# see https://github.com/llvm/llvm-project/pull/82393 and
4545
# https://discourse.llvm.org/t/rfc-future-of-windows-pre-commit-ci/76840/40
4646
# for further information.
47-
cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \
47+
cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \
4848
-D LLVM_ENABLE_PROJECTS="${projects}" \
4949
-G Ninja \
5050
-D CMAKE_BUILD_TYPE=Release \

.github/workflows/pr-code-format.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ jobs:
7373
# to take advantage of the new --diff_from_common_commit option
7474
# explicitly in code-format-helper.py and not have to diff starting at
7575
# the merge base.
76+
# Create an empty comments file so the pr-write job doesn't fail.
7677
run: |
78+
echo "[]" > comments &&
7779
python ./code-format-tools/llvm/utils/git/code-format-helper.py \
7880
--write-comment-to-file \
7981
--token ${{ secrets.GITHUB_TOKEN }} \

.github/workflows/scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
persist-credentials: false
3737

3838
- name: "Run analysis"
39-
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
39+
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
4040
with:
4141
results_file: results.sarif
4242
results_format: sarif

bolt/docs/BAT.md

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,21 @@ and [BoltAddressTranslation.cpp](/bolt/lib/Profile/BoltAddressTranslation.cpp).
4242
### Layout
4343
The general layout is as follows:
4444
```
45-
Hot functions table header
46-
|------------------|
47-
| Function entry |
48-
| |--------------| |
49-
| | OutOff InOff | |
50-
| |--------------| |
51-
~~~~~~~~~~~~~~~~~~~~
45+
Hot functions table
46+
Cold functions table
5247
53-
Cold functions table header
48+
Functions table:
5449
|------------------|
5550
| Function entry |
56-
| |--------------| |
57-
| | OutOff InOff | |
58-
| |--------------| |
59-
~~~~~~~~~~~~~~~~~~~~
51+
| |
52+
| Address |
53+
| translation |
54+
| table |
55+
| |
56+
| Secondary entry |
57+
| points |
58+
|------------------|
59+
6060
```
6161

6262
### Functions table
@@ -74,19 +74,20 @@ internal offsets, and between hot and cold fragments, to better spread deltas
7474
and save space.
7575

7676
Hot indices are delta encoded, implicitly starting at zero.
77-
| Entry | Encoding | Description |
78-
| ------ | ------| ----------- |
79-
| `Address` | Continuous, Delta, ULEB128 | Function address in the output binary |
80-
| `HotIndex` | Delta, ULEB128 | Cold functions only: index of corresponding hot function in hot functions table |
81-
| `FuncHash` | 8b | Hot functions only: function hash for input function |
82-
| `NumBlocks` | ULEB128 | Hot functions only: number of basic blocks in the original function |
83-
| `NumEntries` | ULEB128 | Number of address translation entries for a function |
84-
| `EqualElems` | ULEB128 | Hot functions only: number of equal offsets in the beginning of a function |
85-
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | Hot functions only: if `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit |
86-
87-
Function header is followed by `EqualElems` offsets (hot functions only) and
88-
`NumEntries-EqualElems` (`NumEntries` for cold functions) pairs of offsets for
89-
current function.
77+
| Entry | Encoding | Description | Hot/Cold |
78+
| ------ | ------| ----------- | ------ |
79+
| `Address` | Continuous, Delta, ULEB128 | Function address in the output binary | Both |
80+
| `HotIndex` | Delta, ULEB128 | Index of corresponding hot function in hot functions table | Cold |
81+
| `FuncHash` | 8b | Function hash for input function | Hot |
82+
| `NumBlocks` | ULEB128 | Number of basic blocks in the original function | Hot |
83+
| `NumSecEntryPoints` | ULEB128 | Number of secondary entry points in the original function | Hot |
84+
| `NumEntries` | ULEB128 | Number of address translation entries for a function | Both |
85+
| `EqualElems` | ULEB128 | Number of equal offsets in the beginning of a function | Hot |
86+
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | If `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit | Hot |
87+
88+
Function header is followed by *Address Translation Table* with `NumEntries`
89+
total entries, and *Secondary Entry Points* table with `NumSecEntryPoints`
90+
entries (hot functions only).
9091

9192
### Address translation table
9293
Delta encoding means that only the difference with the previous corresponding
@@ -98,8 +99,18 @@ entry is encoded. Input offsets implicitly start at zero.
9899
| `BBHash` | Optional, 8b | Basic block hash in input binary | BB |
99100
| `BBIdx` | Optional, Delta, ULEB128 | Basic block index in input binary | BB |
100101

102+
For hot fragments, the table omits the first `EqualElems` input offsets
103+
where the input offset equals output offset.
104+
101105
`BRANCHENTRY` bit denotes whether a given offset pair is a control flow source
102106
(branch or call instruction). If not set, it signifies a control flow target
103107
(basic block offset).
104108
`InputAddr` is omitted for equal offsets in input and output function. In this
105109
case, `BRANCHENTRY` bits are encoded separately in a `BranchEntries` bitvector.
110+
111+
### Secondary Entry Points table
112+
The table is emitted for hot fragments only. It contains `NumSecEntryPoints`
113+
offsets denoting secondary entry points, delta encoded, implicitly starting at zero.
114+
| Entry | Encoding | Description |
115+
| ----- | -------- | ----------- |
116+
| `SecEntryPoint` | Delta, ULEB128 | Secondary entry point offset |

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ class BoltAddressTranslation {
118118
/// True if a given \p Address is a function with translation table entry.
119119
bool isBATFunction(uint64_t Address) const { return Maps.count(Address); }
120120

121+
/// Returns branch offsets grouped by containing basic block in a given
122+
/// function.
123+
std::unordered_map<uint32_t, std::vector<uint32_t>>
124+
getBFBranches(uint64_t FuncOutputAddress) const;
125+
121126
private:
122127
/// Helper to update \p Map by inserting one or more BAT entries reflecting
123128
/// \p BB for function located at \p FuncAddress. At least one entry will be
@@ -150,6 +155,9 @@ class BoltAddressTranslation {
150155
/// Map a function to its basic blocks count
151156
std::unordered_map<uint64_t, size_t> NumBasicBlocksMap;
152157

158+
/// Map a function to its secondary entry points vector
159+
std::unordered_map<uint64_t, std::vector<uint32_t>> SecondaryEntryPointsMap;
160+
153161
/// Links outlined cold bocks to their original function
154162
std::map<uint64_t, uint64_t> ColdPartSource;
155163

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ class DataAggregator : public DataReader {
467467
std::error_code writeBATYAML(BinaryContext &BC,
468468
StringRef OutputFilename) const;
469469

470+
/// Fixup profile collected on BOLTed binary, namely handle split functions.
471+
void fixupBATProfile(BinaryContext &BC);
472+
470473
/// Filter out binaries based on PID
471474
void filterBinaryMMapInfo();
472475

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3547,7 +3547,7 @@ MCSymbol *BinaryFunction::getSymbolForEntryID(uint64_t EntryID) {
35473547
if (!isMultiEntry())
35483548
return nullptr;
35493549

3550-
uint64_t NumEntries = 0;
3550+
uint64_t NumEntries = 1;
35513551
if (hasCFG()) {
35523552
for (BinaryBasicBlock *BB : BasicBlocks) {
35533553
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(*BB);
@@ -3580,7 +3580,7 @@ uint64_t BinaryFunction::getEntryIDForSymbol(const MCSymbol *Symbol) const {
35803580
return 0;
35813581

35823582
// Check all secondary entries available as either basic blocks or lables.
3583-
uint64_t NumEntries = 0;
3583+
uint64_t NumEntries = 1;
35843584
for (const BinaryBasicBlock *BB : BasicBlocks) {
35853585
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(*BB);
35863586
if (!EntrySymbol)
@@ -3589,7 +3589,7 @@ uint64_t BinaryFunction::getEntryIDForSymbol(const MCSymbol *Symbol) const {
35893589
return NumEntries;
35903590
++NumEntries;
35913591
}
3592-
NumEntries = 0;
3592+
NumEntries = 1;
35933593
for (const std::pair<const uint32_t, MCSymbol *> &KV : Labels) {
35943594
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(KV.second);
35953595
if (!EntrySymbol)

bolt/lib/Profile/BoltAddressTranslation.cpp

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,21 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
8888
if (Function.isIgnored() || (!BC.HasRelocations && !Function.isSimple()))
8989
continue;
9090

91-
// TBD: handle BAT functions w/multiple entry points.
92-
if (Function.isMultiEntry())
93-
continue;
91+
uint32_t NumSecondaryEntryPoints = 0;
92+
Function.forEachEntryPoint([&](uint64_t Offset, const MCSymbol *) {
93+
if (!Offset)
94+
return true;
95+
++NumSecondaryEntryPoints;
96+
SecondaryEntryPointsMap[OutputAddress].push_back(Offset);
97+
return true;
98+
});
9499

95100
LLVM_DEBUG(dbgs() << "Function name: " << Function.getPrintName() << "\n");
96101
LLVM_DEBUG(dbgs() << " Address reference: 0x"
97102
<< Twine::utohexstr(Function.getOutputAddress()) << "\n");
98103
LLVM_DEBUG(dbgs() << formatv(" Hash: {0:x}\n", getBFHash(OutputAddress)));
104+
LLVM_DEBUG(dbgs() << " Secondary Entry Points: " << NumSecondaryEntryPoints
105+
<< '\n');
99106

100107
MapTy Map;
101108
for (const BinaryBasicBlock *const BB :
@@ -185,6 +192,10 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
185192
<< Twine::utohexstr(Address) << ".\n");
186193
encodeULEB128(Address - PrevAddress, OS);
187194
PrevAddress = Address;
195+
const uint32_t NumSecondaryEntryPoints =
196+
SecondaryEntryPointsMap.count(Address)
197+
? SecondaryEntryPointsMap[Address].size()
198+
: 0;
188199
if (Cold) {
189200
size_t HotIndex =
190201
std::distance(ColdPartSource.begin(), ColdPartSource.find(Address));
@@ -199,6 +210,10 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
199210
size_t NumBasicBlocks = getBBHashMap(HotInputAddress).getNumBasicBlocks();
200211
LLVM_DEBUG(dbgs() << "Basic blocks: " << NumBasicBlocks << '\n');
201212
encodeULEB128(NumBasicBlocks, OS);
213+
// Secondary entry points
214+
encodeULEB128(NumSecondaryEntryPoints, OS);
215+
LLVM_DEBUG(dbgs() << "Secondary Entry Points: " << NumSecondaryEntryPoints
216+
<< '\n');
202217
}
203218
encodeULEB128(NumEntries, OS);
204219
// For hot fragments only: encode the number of equal offsets
@@ -244,6 +259,17 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
244259
InOffset >> 1, BBHash, BBIndex));
245260
}
246261
}
262+
uint32_t PrevOffset = 0;
263+
if (!Cold && NumSecondaryEntryPoints) {
264+
LLVM_DEBUG(dbgs() << "Secondary entry points: ");
265+
// Secondary entry point offsets, delta-encoded
266+
for (uint32_t Offset : SecondaryEntryPointsMap[Address]) {
267+
encodeULEB128(Offset - PrevOffset, OS);
268+
LLVM_DEBUG(dbgs() << formatv("{0:x} ", Offset));
269+
PrevOffset = Offset;
270+
}
271+
LLVM_DEBUG(dbgs() << '\n');
272+
}
247273
}
248274
}
249275

@@ -287,6 +313,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
287313
const uint64_t Address = PrevAddress + DE.getULEB128(&Offset, &Err);
288314
uint64_t HotAddress = Cold ? 0 : Address;
289315
PrevAddress = Address;
316+
uint32_t SecondaryEntryPoints = 0;
290317
if (Cold) {
291318
HotIndex += DE.getULEB128(&Offset, &Err);
292319
HotAddress = HotFuncs[HotIndex];
@@ -303,6 +330,12 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
303330
LLVM_DEBUG(dbgs() << formatv("{0:x}: #bbs {1}, {2} bytes\n", Address,
304331
NumBasicBlocks,
305332
getULEB128Size(NumBasicBlocks)));
333+
// Secondary entry points
334+
SecondaryEntryPoints = DE.getULEB128(&Offset, &Err);
335+
LLVM_DEBUG(
336+
dbgs() << formatv("{0:x}: secondary entry points {1}, {2} bytes\n",
337+
Address, SecondaryEntryPoints,
338+
getULEB128Size(SecondaryEntryPoints)));
306339
}
307340
const uint32_t NumEntries = DE.getULEB128(&Offset, &Err);
308341
// Equal offsets, hot fragments only.
@@ -370,6 +403,19 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
370403
});
371404
}
372405
Maps.insert(std::pair<uint64_t, MapTy>(Address, Map));
406+
if (!Cold && SecondaryEntryPoints) {
407+
uint32_t EntryPointOffset = 0;
408+
LLVM_DEBUG(dbgs() << "Secondary entry points: ");
409+
for (uint32_t EntryPointId = 0; EntryPointId != SecondaryEntryPoints;
410+
++EntryPointId) {
411+
uint32_t OffsetDelta = DE.getULEB128(&Offset, &Err);
412+
EntryPointOffset += OffsetDelta;
413+
SecondaryEntryPointsMap[Address].push_back(EntryPointOffset);
414+
LLVM_DEBUG(dbgs() << formatv("{0:x}/{1}b ", EntryPointOffset,
415+
getULEB128Size(OffsetDelta)));
416+
}
417+
LLVM_DEBUG(dbgs() << '\n');
418+
}
373419
}
374420
}
375421

@@ -397,6 +443,13 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
397443
OS << formatv(" hash: {0:x}", BBHashMap.getBBHash(Val));
398444
OS << "\n";
399445
}
446+
if (SecondaryEntryPointsMap.count(Address)) {
447+
const std::vector<uint32_t> &SecondaryEntryPoints =
448+
SecondaryEntryPointsMap[Address];
449+
OS << SecondaryEntryPoints.size() << " secondary entry points:\n";
450+
for (uint32_t EntryPointOffset : SecondaryEntryPoints)
451+
OS << formatv("{0:x}\n", EntryPointOffset);
452+
}
400453
OS << "\n";
401454
}
402455
const size_t NumColdParts = ColdPartSource.size();
@@ -524,5 +577,25 @@ void BoltAddressTranslation::saveMetadata(BinaryContext &BC) {
524577
}
525578
}
526579

580+
std::unordered_map<uint32_t, std::vector<uint32_t>>
581+
BoltAddressTranslation::getBFBranches(uint64_t OutputAddress) const {
582+
std::unordered_map<uint32_t, std::vector<uint32_t>> Branches;
583+
auto FuncIt = Maps.find(OutputAddress);
584+
assert(FuncIt != Maps.end());
585+
std::vector<uint32_t> InputOffsets;
586+
for (const auto &KV : FuncIt->second)
587+
InputOffsets.emplace_back(KV.second);
588+
// Sort with LSB BRANCHENTRY bit.
589+
llvm::sort(InputOffsets);
590+
uint32_t BBOffset{0};
591+
for (uint32_t InOffset : InputOffsets) {
592+
if (InOffset & BRANCHENTRY)
593+
Branches[BBOffset].push_back(InOffset >> 1);
594+
else
595+
BBOffset = InOffset >> 1;
596+
}
597+
return Branches;
598+
}
599+
527600
} // namespace bolt
528601
} // namespace llvm

0 commit comments

Comments
 (0)