Skip to content

Commit ec7b9da

Browse files
authored
Merge branch 'llvm:main' into main
2 parents 0e43587 + a1c9b96 commit ec7b9da

File tree

570 files changed

+10519
-8847
lines changed

Some content is hidden

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

570 files changed

+10519
-8847
lines changed

bolt/docs/BAT.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,14 @@ equals output offset.
106106
`BRANCHENTRY` bit denotes whether a given offset pair is a control flow source
107107
(branch or call instruction). If not set, it signifies a control flow target
108108
(basic block offset).
109+
109110
`InputAddr` is omitted for equal offsets in input and output function. In this
110111
case, `BRANCHENTRY` bits are encoded separately in a `BranchEntries` bitvector.
111112

113+
Deleted basic blocks are emitted as having `OutputOffset` equal to the size of
114+
the function. They don't affect address translation and only participate in
115+
input basic block mapping.
116+
112117
### Secondary Entry Points table
113118
The table is emitted for hot fragments only. It contains `NumSecEntryPoints`
114119
offsets denoting secondary entry points, delta encoded, implicitly starting at zero.

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "bolt/Core/BinaryData.h"
1818
#include "bolt/Core/BinarySection.h"
1919
#include "bolt/Core/DebugData.h"
20+
#include "bolt/Core/DynoStats.h"
2021
#include "bolt/Core/JumpTable.h"
2122
#include "bolt/Core/MCPlusBuilder.h"
2223
#include "bolt/RuntimeLibs/RuntimeLibrary.h"
@@ -717,6 +718,9 @@ class BinaryContext {
717718
uint64_t NumStaleBlocksWithEqualIcount{0};
718719
} Stats;
719720

721+
// Original binary execution count stats.
722+
DynoStats InitialDynoStats;
723+
720724
// Address of the first allocated segment.
721725
uint64_t FirstAllocAddress{std::numeric_limits<uint64_t>::max()};
722726

bolt/include/bolt/Passes/BinaryPasses.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,31 @@ class BinaryFunctionPass {
5353
virtual Error runOnFunctions(BinaryContext &BC) = 0;
5454
};
5555

56+
/// A pass to set initial program-wide dynostats.
57+
class DynoStatsSetPass : public BinaryFunctionPass {
58+
public:
59+
DynoStatsSetPass() : BinaryFunctionPass(false) {}
60+
61+
const char *getName() const override {
62+
return "set dyno-stats before optimizations";
63+
}
64+
65+
bool shouldPrint(const BinaryFunction &BF) const override { return false; }
66+
67+
Error runOnFunctions(BinaryContext &BC) override {
68+
BC.InitialDynoStats = getDynoStats(BC.getBinaryFunctions(), BC.isAArch64());
69+
return Error::success();
70+
}
71+
};
72+
5673
/// A pass to print program-wide dynostats.
5774
class DynoStatsPrintPass : public BinaryFunctionPass {
5875
protected:
59-
DynoStats PrevDynoStats;
6076
std::string Title;
6177

6278
public:
63-
DynoStatsPrintPass(const DynoStats &PrevDynoStats, const char *Title)
64-
: BinaryFunctionPass(false), PrevDynoStats(PrevDynoStats), Title(Title) {}
79+
DynoStatsPrintPass(const char *Title)
80+
: BinaryFunctionPass(false), Title(Title) {}
6581

6682
const char *getName() const override {
6783
return "print dyno-stats after optimizations";
@@ -70,6 +86,7 @@ class DynoStatsPrintPass : public BinaryFunctionPass {
7086
bool shouldPrint(const BinaryFunction &BF) const override { return false; }
7187

7288
Error runOnFunctions(BinaryContext &BC) override {
89+
const DynoStats PrevDynoStats = BC.InitialDynoStats;
7390
const DynoStats NewDynoStats =
7491
getDynoStats(BC.getBinaryFunctions(), BC.isAArch64());
7592
const bool Changed = (NewDynoStats != PrevDynoStats);

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class BinaryFunction;
7070
class BoltAddressTranslation {
7171
public:
7272
// In-memory representation of the address translation table
73-
using MapTy = std::map<uint32_t, uint32_t>;
73+
using MapTy = std::multimap<uint32_t, uint32_t>;
7474

7575
// List of taken fall-throughs
7676
using FallthroughListTy = SmallVector<std::pair<uint64_t, uint64_t>, 16>;
@@ -218,6 +218,7 @@ class BoltAddressTranslation {
218218
auto begin() const { return Map.begin(); }
219219
auto end() const { return Map.end(); }
220220
auto upper_bound(uint32_t Offset) const { return Map.upper_bound(Offset); }
221+
auto size() const { return Map.size(); }
221222
};
222223

223224
/// Map function output address to its hash and basic blocks hash map.

bolt/lib/Core/BinaryContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
142142
AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), STI(std::move(STI)),
143143
InstPrinter(std::move(InstPrinter)), MIA(std::move(MIA)),
144144
MIB(std::move(MIB)), MRI(std::move(MRI)), DisAsm(std::move(DisAsm)),
145-
Logger(Logger) {
145+
Logger(Logger), InitialDynoStats(isAArch64()) {
146146
Relocation::Arch = this->TheTriple->getArch();
147147
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
148148
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;

bolt/lib/Profile/BoltAddressTranslation.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void BoltAddressTranslation::writeEntriesForBB(
5454
// and this deleted block will both share the same output address (the same
5555
// key), and we need to map back. We choose here to privilege the successor by
5656
// allowing it to overwrite the previously inserted key in the map.
57-
Map[BBOutputOffset] = BBInputOffset << 1;
57+
Map.emplace(BBOutputOffset, BBInputOffset << 1);
5858

5959
const auto &IOAddressMap =
6060
BB.getFunction()->getBinaryContext().getIOAddressMap();
@@ -71,8 +71,7 @@ void BoltAddressTranslation::writeEntriesForBB(
7171

7272
LLVM_DEBUG(dbgs() << " Key: " << Twine::utohexstr(OutputOffset) << " Val: "
7373
<< Twine::utohexstr(InputOffset) << " (branch)\n");
74-
Map.insert(std::pair<uint32_t, uint32_t>(OutputOffset,
75-
(InputOffset << 1) | BRANCHENTRY));
74+
Map.emplace(OutputOffset, (InputOffset << 1) | BRANCHENTRY);
7675
}
7776
}
7877

@@ -107,6 +106,19 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
107106
for (const BinaryBasicBlock *const BB :
108107
Function.getLayout().getMainFragment())
109108
writeEntriesForBB(Map, *BB, InputAddress, OutputAddress);
109+
// Add entries for deleted blocks. They are still required for correct BB
110+
// mapping of branches modified by SCTC. By convention, they would have the
111+
// end of the function as output address.
112+
const BBHashMapTy &BBHashMap = getBBHashMap(InputAddress);
113+
if (BBHashMap.size() != Function.size()) {
114+
const uint64_t EndOffset = Function.getOutputSize();
115+
std::unordered_set<uint32_t> MappedInputOffsets;
116+
for (const BinaryBasicBlock &BB : Function)
117+
MappedInputOffsets.emplace(BB.getInputOffset());
118+
for (const auto &[InputOffset, _] : BBHashMap)
119+
if (!llvm::is_contained(MappedInputOffsets, InputOffset))
120+
Map.emplace(EndOffset, InputOffset << 1);
121+
}
110122
Maps.emplace(Function.getOutputAddress(), std::move(Map));
111123
ReverseMap.emplace(OutputAddress, InputAddress);
112124

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,11 +2349,11 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
23492349
BAT->getBBHashMap(FuncAddress);
23502350
YamlBF.Blocks.resize(YamlBF.NumBasicBlocks);
23512351

2352-
for (auto &&[Idx, YamlBB] : llvm::enumerate(YamlBF.Blocks))
2353-
YamlBB.Index = Idx;
2354-
2355-
for (auto BI = BlockMap.begin(), BE = BlockMap.end(); BI != BE; ++BI)
2356-
YamlBF.Blocks[BI->second.Index].Hash = BI->second.Hash;
2352+
for (auto &&[Entry, YamlBB] : llvm::zip(BlockMap, YamlBF.Blocks)) {
2353+
const auto &Block = Entry.second;
2354+
YamlBB.Hash = Block.Hash;
2355+
YamlBB.Index = Block.Index;
2356+
}
23572357

23582358
// Lookup containing basic block offset and index
23592359
auto getBlock = [&BlockMap](uint32_t Offset) {

bolt/lib/Rewrite/BinaryPassManager.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
343343
Manager.registerPass(
344344
std::make_unique<EstimateEdgeCounts>(PrintEstimateEdgeCounts));
345345

346-
const DynoStats InitialDynoStats =
347-
getDynoStats(BC.getBinaryFunctions(), BC.isAArch64());
346+
Manager.registerPass(std::make_unique<DynoStatsSetPass>());
348347

349348
Manager.registerPass(std::make_unique<AsmDumpPass>(),
350349
opts::AsmDump.getNumOccurrences());
@@ -456,10 +455,9 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) {
456455
Manager.registerPass(std::make_unique<SplitFunctions>(PrintSplit));
457456

458457
// Print final dyno stats right while CFG and instruction analysis are intact.
459-
Manager.registerPass(
460-
std::make_unique<DynoStatsPrintPass>(
461-
InitialDynoStats, "after all optimizations before SCTC and FOP"),
462-
opts::PrintDynoStats || opts::DynoStatsAll);
458+
Manager.registerPass(std::make_unique<DynoStatsPrintPass>(
459+
"after all optimizations before SCTC and FOP"),
460+
opts::PrintDynoStats || opts::DynoStatsAll);
463461

464462
// Add the StokeInfo pass, which extract functions for stoke optimization and
465463
// get the liveness information for them

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3206,12 +3206,14 @@ void RewriteInstance::preprocessProfileData() {
32063206
if (Error E = ProfileReader->preprocessProfile(*BC.get()))
32073207
report_error("cannot pre-process profile", std::move(E));
32083208

3209-
if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName()) {
3209+
if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName() &&
3210+
!opts::AllowStripped) {
32103211
BC->errs()
32113212
<< "BOLT-ERROR: input binary does not have local file symbols "
32123213
"but profile data includes function names with embedded file "
32133214
"names. It appears that the input binary was stripped while a "
3214-
"profiled binary was not\n";
3215+
"profiled binary was not. If you know what you are doing and "
3216+
"wish to proceed, use -allow-stripped option.\n";
32153217
exit(1);
32163218
}
32173219
}

bolt/test/X86/bb-with-two-tail-calls.s

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
99
# RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --lite=0 --dyno-stats \
1010
# RUN: --print-sctc --print-only=_start -enable-bat 2>&1 | FileCheck %s
11+
# RUN: llvm-objdump --syms %t.out > %t.log
12+
# RUN: llvm-bat-dump %t.out --dump-all >> %t.log
13+
# RUN: FileCheck %s --input-file %t.log --check-prefix=CHECK-BAT
14+
1115
# CHECK-NOT: Assertion `BranchInfo.size() == 2 && "could only be called for blocks with 2 successors"' failed.
1216
# Two tail calls in the same basic block after SCTC:
1317
# CHECK: {{.*}}: ja {{.*}} # TAILCALL # Offset: 7 # CTCTakenCount: 4
1418
# CHECK-NEXT: {{.*}}: jmp {{.*}} # TAILCALL # Offset: 13
1519

20+
# Confirm that a deleted basic block is emitted at function end offset (0xe)
21+
# CHECK-BAT: [[#%x,ADDR:]] g .text [[#%x,SIZE:]] _start
22+
# CHECK-BAT: Function Address: 0x[[#%x,ADDR]]
23+
# CHECK-BAT: 0x[[#%x,SIZE]]
24+
# CHECK-BAT: NumBlocks: 5
25+
1626
.globl _start
1727
_start:
1828
je x

bolt/test/X86/bolt-address-translation-yaml.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ RUN: | FileCheck --check-prefix CHECK-BOLT-YAML %s
4141

4242
WRITE-BAT-CHECK: BOLT-INFO: Wrote 5 BAT maps
4343
WRITE-BAT-CHECK: BOLT-INFO: Wrote 4 function and 22 basic block hashes
44-
WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 384
44+
WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 404
4545

4646
READ-BAT-CHECK-NOT: BOLT-ERROR: unable to save profile in YAML format for input file processed by BOLT
4747
READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries

bolt/test/X86/bolt-address-translation.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
# CHECK: BOLT: 3 out of 7 functions were overwritten.
3838
# CHECK: BOLT-INFO: Wrote 6 BAT maps
3939
# CHECK: BOLT-INFO: Wrote 3 function and 58 basic block hashes
40-
# CHECK: BOLT-INFO: BAT section size (bytes): 928
40+
# CHECK: BOLT-INFO: BAT section size (bytes): 940
4141
#
4242
# usqrt mappings (hot part). We match against any key (left side containing
4343
# the bolted binary offsets) because BOLT may change where it puts instructions

clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
5050

5151
case CK_PointerToBoolean:
5252
case CK_MemberPointerToBoolean: // Fall-through on purpose.
53-
return Context.getLangOpts().CPlusPlus11 ? "nullptr" : "0";
53+
return (Context.getLangOpts().CPlusPlus11 || Context.getLangOpts().C23)
54+
? "nullptr"
55+
: "0";
5456

5557
default:
5658
llvm_unreachable("Unexpected cast kind");
@@ -165,6 +167,12 @@ bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
165167
void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
166168
const ImplicitCastExpr *Cast,
167169
ASTContext &Context, StringRef OtherType) {
170+
if (!Context.getLangOpts().CPlusPlus) {
171+
Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(),
172+
(Twine("(") + OtherType + ")").str());
173+
return;
174+
}
175+
168176
const Expr *SubExpr = Cast->getSubExpr();
169177
const bool NeedParens = !isa<ParenExpr>(SubExpr->IgnoreImplicit());
170178
const bool NeedSpace = needsSpacePrefix(Cast->getBeginLoc(), Context);
@@ -267,6 +275,10 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
267275
auto BoolXor =
268276
binaryOperator(hasOperatorName("^"), hasLHS(ImplicitCastFromBool),
269277
hasRHS(ImplicitCastFromBool));
278+
auto ComparisonInCall = allOf(
279+
hasParent(callExpr()),
280+
hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!="))));
281+
270282
Finder->addMatcher(
271283
traverse(TK_AsIs,
272284
implicitCastExpr(
@@ -281,6 +293,8 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
281293
stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))),
282294
// Exclude cases common to implicit cast to and from bool.
283295
unless(ExceptionCases), unless(has(BoolXor)),
296+
// Exclude C23 cases common to implicit cast to bool.
297+
unless(ComparisonInCall),
284298
// Retrieve also parent statement, to check if we need
285299
// additional parens in replacement.
286300
optionally(hasParent(stmt().bind("parentStmt"))),

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,9 @@ Changes in existing checks
381381
- Improved :doc:`readability-implicit-bool-conversion
382382
<clang-tidy/checks/readability/implicit-bool-conversion>` check to provide
383383
valid fix suggestions for ``static_cast`` without a preceding space and
384-
fixed problem with duplicate parentheses in double implicit casts.
384+
fixed problem with duplicate parentheses in double implicit casts. Corrected
385+
the fix suggestions for C23 and later by using C-style casts instead of
386+
``static_cast``.
385387

386388
- Improved :doc:`readability-redundant-inline-specifier
387389
<clang-tidy/checks/readability/redundant-inline-specifier>` check to properly

clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ The rules for generating fix-it hints are:
9696
- ``if (!pointer)`` is changed to ``if (pointer == nullptr)``,
9797

9898
- in case of conversions from bool to other built-in types, an explicit
99-
``static_cast`` is proposed to make it clear that a conversion is taking
100-
place:
99+
``static_cast`` (or a C-style cast since C23) is proposed to make it clear
100+
that a conversion is taking place:
101101

102102
- ``int integer = boolean;`` is changed to
103103
``int integer = static_cast<int>(boolean);``,

0 commit comments

Comments
 (0)