Skip to content

Commit

Permalink
Merge branch 'main' into pauth-gnuprop-readobj & fix conflict after 2…
Browse files Browse the repository at this point in the history
  • Loading branch information
kovdan01 committed Mar 29, 2024
2 parents 26c8586 + ba6b2d2 commit 69b2cb7
Show file tree
Hide file tree
Showing 1,882 changed files with 66,442 additions and 22,208 deletions.
6 changes: 3 additions & 3 deletions .ci/monolithic-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ set -o pipefail

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

ccache --zero-stats

Expand All @@ -37,8 +37,8 @@ projects="${1}"
targets="${2}"

echo "--- cmake"
pip install -q -r ${MONOREPO_ROOT}/mlir/python/requirements.txt
cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \
pip install -q -r "${MONOREPO_ROOT}"/mlir/python/requirements.txt
cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \
-D LLVM_ENABLE_PROJECTS="${projects}" \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
Expand Down
6 changes: 3 additions & 3 deletions .ci/monolithic-windows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set -o pipefail
MONOREPO_ROOT="${MONOREPO_ROOT:="$(git rev-parse --show-toplevel)"}"
BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build}"

rm -rf ${BUILD_DIR}
rm -rf "${BUILD_DIR}"

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

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

# The CMAKE_*_LINKER_FLAGS to disable the manifest come from research
# on fixing a build reliability issue on the build server, please
# see https://github.com/llvm/llvm-project/pull/82393 and
# https://discourse.llvm.org/t/rfc-future-of-windows-pre-commit-ci/76840/40
# for further information.
cmake -S ${MONOREPO_ROOT}/llvm -B ${BUILD_DIR} \
cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \
-D LLVM_ENABLE_PROJECTS="${projects}" \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pr-code-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ jobs:
# to take advantage of the new --diff_from_common_commit option
# explicitly in code-format-helper.py and not have to diff starting at
# the merge base.
# Create an empty comments file so the pr-write job doesn't fail.
run: |
echo "[]" > comments &&
python ./code-format-tools/llvm/utils/git/code-format-helper.py \
--write-comment-to-file \
--token ${{ secrets.GITHUB_TOKEN }} \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
with:
results_file: results.sarif
results_format: sarif
Expand Down
61 changes: 36 additions & 25 deletions bolt/docs/BAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@ and [BoltAddressTranslation.cpp](/bolt/lib/Profile/BoltAddressTranslation.cpp).
### Layout
The general layout is as follows:
```
Hot functions table header
|------------------|
| Function entry |
| |--------------| |
| | OutOff InOff | |
| |--------------| |
~~~~~~~~~~~~~~~~~~~~
Hot functions table
Cold functions table
Cold functions table header
Functions table:
|------------------|
| Function entry |
| |--------------| |
| | OutOff InOff | |
| |--------------| |
~~~~~~~~~~~~~~~~~~~~
| |
| Address |
| translation |
| table |
| |
| Secondary entry |
| points |
|------------------|
```

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

Hot indices are delta encoded, implicitly starting at zero.
| Entry | Encoding | Description |
| ------ | ------| ----------- |
| `Address` | Continuous, Delta, ULEB128 | Function address in the output binary |
| `HotIndex` | Delta, ULEB128 | Cold functions only: index of corresponding hot function in hot functions table |
| `FuncHash` | 8b | Hot functions only: function hash for input function |
| `NumBlocks` | ULEB128 | Hot functions only: number of basic blocks in the original function |
| `NumEntries` | ULEB128 | Number of address translation entries for a function |
| `EqualElems` | ULEB128 | Hot functions only: number of equal offsets in the beginning of a function |
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | Hot functions only: if `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit |

Function header is followed by `EqualElems` offsets (hot functions only) and
`NumEntries-EqualElems` (`NumEntries` for cold functions) pairs of offsets for
current function.
| Entry | Encoding | Description | Hot/Cold |
| ------ | ------| ----------- | ------ |
| `Address` | Continuous, Delta, ULEB128 | Function address in the output binary | Both |
| `HotIndex` | Delta, ULEB128 | Index of corresponding hot function in hot functions table | Cold |
| `FuncHash` | 8b | Function hash for input function | Hot |
| `NumBlocks` | ULEB128 | Number of basic blocks in the original function | Hot |
| `NumSecEntryPoints` | ULEB128 | Number of secondary entry points in the original function | Hot |
| `NumEntries` | ULEB128 | Number of address translation entries for a function | Both |
| `EqualElems` | ULEB128 | Number of equal offsets in the beginning of a function | Hot |
| `BranchEntries` | Bitmask, `alignTo(EqualElems, 8)` bits | If `EqualElems` is non-zero, bitmask denoting entries with `BRANCHENTRY` bit | Hot |

Function header is followed by *Address Translation Table* with `NumEntries`
total entries, and *Secondary Entry Points* table with `NumSecEntryPoints`
entries (hot functions only).

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

For hot fragments, the table omits the first `EqualElems` input offsets
where the input offset equals output offset.

`BRANCHENTRY` bit denotes whether a given offset pair is a control flow source
(branch or call instruction). If not set, it signifies a control flow target
(basic block offset).
`InputAddr` is omitted for equal offsets in input and output function. In this
case, `BRANCHENTRY` bits are encoded separately in a `BranchEntries` bitvector.

### Secondary Entry Points table
The table is emitted for hot fragments only. It contains `NumSecEntryPoints`
offsets denoting secondary entry points, delta encoded, implicitly starting at zero.
| Entry | Encoding | Description |
| ----- | -------- | ----------- |
| `SecEntryPoint` | Delta, ULEB128 | Secondary entry point offset |
8 changes: 8 additions & 0 deletions bolt/include/bolt/Profile/BoltAddressTranslation.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ class BoltAddressTranslation {
/// True if a given \p Address is a function with translation table entry.
bool isBATFunction(uint64_t Address) const { return Maps.count(Address); }

/// Returns branch offsets grouped by containing basic block in a given
/// function.
std::unordered_map<uint32_t, std::vector<uint32_t>>
getBFBranches(uint64_t FuncOutputAddress) const;

private:
/// Helper to update \p Map by inserting one or more BAT entries reflecting
/// \p BB for function located at \p FuncAddress. At least one entry will be
Expand Down Expand Up @@ -150,6 +155,9 @@ class BoltAddressTranslation {
/// Map a function to its basic blocks count
std::unordered_map<uint64_t, size_t> NumBasicBlocksMap;

/// Map a function to its secondary entry points vector
std::unordered_map<uint64_t, std::vector<uint32_t>> SecondaryEntryPointsMap;

/// Links outlined cold bocks to their original function
std::map<uint64_t, uint64_t> ColdPartSource;

Expand Down
3 changes: 3 additions & 0 deletions bolt/include/bolt/Profile/DataAggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ class DataAggregator : public DataReader {
std::error_code writeBATYAML(BinaryContext &BC,
StringRef OutputFilename) const;

/// Fixup profile collected on BOLTed binary, namely handle split functions.
void fixupBATProfile(BinaryContext &BC);

/// Filter out binaries based on PID
void filterBinaryMMapInfo();

Expand Down
6 changes: 3 additions & 3 deletions bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3547,7 +3547,7 @@ MCSymbol *BinaryFunction::getSymbolForEntryID(uint64_t EntryID) {
if (!isMultiEntry())
return nullptr;

uint64_t NumEntries = 0;
uint64_t NumEntries = 1;
if (hasCFG()) {
for (BinaryBasicBlock *BB : BasicBlocks) {
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(*BB);
Expand Down Expand Up @@ -3580,7 +3580,7 @@ uint64_t BinaryFunction::getEntryIDForSymbol(const MCSymbol *Symbol) const {
return 0;

// Check all secondary entries available as either basic blocks or lables.
uint64_t NumEntries = 0;
uint64_t NumEntries = 1;
for (const BinaryBasicBlock *BB : BasicBlocks) {
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(*BB);
if (!EntrySymbol)
Expand All @@ -3589,7 +3589,7 @@ uint64_t BinaryFunction::getEntryIDForSymbol(const MCSymbol *Symbol) const {
return NumEntries;
++NumEntries;
}
NumEntries = 0;
NumEntries = 1;
for (const std::pair<const uint32_t, MCSymbol *> &KV : Labels) {
MCSymbol *EntrySymbol = getSecondaryEntryPointSymbol(KV.second);
if (!EntrySymbol)
Expand Down
79 changes: 76 additions & 3 deletions bolt/lib/Profile/BoltAddressTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,21 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
if (Function.isIgnored() || (!BC.HasRelocations && !Function.isSimple()))
continue;

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

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

MapTy Map;
for (const BinaryBasicBlock *const BB :
Expand Down Expand Up @@ -185,6 +192,10 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
<< Twine::utohexstr(Address) << ".\n");
encodeULEB128(Address - PrevAddress, OS);
PrevAddress = Address;
const uint32_t NumSecondaryEntryPoints =
SecondaryEntryPointsMap.count(Address)
? SecondaryEntryPointsMap[Address].size()
: 0;
if (Cold) {
size_t HotIndex =
std::distance(ColdPartSource.begin(), ColdPartSource.find(Address));
Expand All @@ -199,6 +210,10 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
size_t NumBasicBlocks = getBBHashMap(HotInputAddress).getNumBasicBlocks();
LLVM_DEBUG(dbgs() << "Basic blocks: " << NumBasicBlocks << '\n');
encodeULEB128(NumBasicBlocks, OS);
// Secondary entry points
encodeULEB128(NumSecondaryEntryPoints, OS);
LLVM_DEBUG(dbgs() << "Secondary Entry Points: " << NumSecondaryEntryPoints
<< '\n');
}
encodeULEB128(NumEntries, OS);
// For hot fragments only: encode the number of equal offsets
Expand Down Expand Up @@ -244,6 +259,17 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
InOffset >> 1, BBHash, BBIndex));
}
}
uint32_t PrevOffset = 0;
if (!Cold && NumSecondaryEntryPoints) {
LLVM_DEBUG(dbgs() << "Secondary entry points: ");
// Secondary entry point offsets, delta-encoded
for (uint32_t Offset : SecondaryEntryPointsMap[Address]) {
encodeULEB128(Offset - PrevOffset, OS);
LLVM_DEBUG(dbgs() << formatv("{0:x} ", Offset));
PrevOffset = Offset;
}
LLVM_DEBUG(dbgs() << '\n');
}
}
}

Expand Down Expand Up @@ -287,6 +313,7 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
const uint64_t Address = PrevAddress + DE.getULEB128(&Offset, &Err);
uint64_t HotAddress = Cold ? 0 : Address;
PrevAddress = Address;
uint32_t SecondaryEntryPoints = 0;
if (Cold) {
HotIndex += DE.getULEB128(&Offset, &Err);
HotAddress = HotFuncs[HotIndex];
Expand All @@ -303,6 +330,12 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
LLVM_DEBUG(dbgs() << formatv("{0:x}: #bbs {1}, {2} bytes\n", Address,
NumBasicBlocks,
getULEB128Size(NumBasicBlocks)));
// Secondary entry points
SecondaryEntryPoints = DE.getULEB128(&Offset, &Err);
LLVM_DEBUG(
dbgs() << formatv("{0:x}: secondary entry points {1}, {2} bytes\n",
Address, SecondaryEntryPoints,
getULEB128Size(SecondaryEntryPoints)));
}
const uint32_t NumEntries = DE.getULEB128(&Offset, &Err);
// Equal offsets, hot fragments only.
Expand Down Expand Up @@ -370,6 +403,19 @@ void BoltAddressTranslation::parseMaps(std::vector<uint64_t> &HotFuncs,
});
}
Maps.insert(std::pair<uint64_t, MapTy>(Address, Map));
if (!Cold && SecondaryEntryPoints) {
uint32_t EntryPointOffset = 0;
LLVM_DEBUG(dbgs() << "Secondary entry points: ");
for (uint32_t EntryPointId = 0; EntryPointId != SecondaryEntryPoints;
++EntryPointId) {
uint32_t OffsetDelta = DE.getULEB128(&Offset, &Err);
EntryPointOffset += OffsetDelta;
SecondaryEntryPointsMap[Address].push_back(EntryPointOffset);
LLVM_DEBUG(dbgs() << formatv("{0:x}/{1}b ", EntryPointOffset,
getULEB128Size(OffsetDelta)));
}
LLVM_DEBUG(dbgs() << '\n');
}
}
}

Expand Down Expand Up @@ -397,6 +443,13 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
OS << formatv(" hash: {0:x}", BBHashMap.getBBHash(Val));
OS << "\n";
}
if (SecondaryEntryPointsMap.count(Address)) {
const std::vector<uint32_t> &SecondaryEntryPoints =
SecondaryEntryPointsMap[Address];
OS << SecondaryEntryPoints.size() << " secondary entry points:\n";
for (uint32_t EntryPointOffset : SecondaryEntryPoints)
OS << formatv("{0:x}\n", EntryPointOffset);
}
OS << "\n";
}
const size_t NumColdParts = ColdPartSource.size();
Expand Down Expand Up @@ -524,5 +577,25 @@ void BoltAddressTranslation::saveMetadata(BinaryContext &BC) {
}
}

std::unordered_map<uint32_t, std::vector<uint32_t>>
BoltAddressTranslation::getBFBranches(uint64_t OutputAddress) const {
std::unordered_map<uint32_t, std::vector<uint32_t>> Branches;
auto FuncIt = Maps.find(OutputAddress);
assert(FuncIt != Maps.end());
std::vector<uint32_t> InputOffsets;
for (const auto &KV : FuncIt->second)
InputOffsets.emplace_back(KV.second);
// Sort with LSB BRANCHENTRY bit.
llvm::sort(InputOffsets);
uint32_t BBOffset{0};
for (uint32_t InOffset : InputOffsets) {
if (InOffset & BRANCHENTRY)
Branches[BBOffset].push_back(InOffset >> 1);
else
BBOffset = InOffset >> 1;
}
return Branches;
}

} // namespace bolt
} // namespace llvm
Loading

0 comments on commit 69b2cb7

Please sign in to comment.