Skip to content

Commit 6dea75a

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: I64c9b919a4c1fc4109f282cbe042291e05909702
2 parents aaed821 + f5d7e75 commit 6dea75a

File tree

88 files changed

+924
-366
lines changed

Some content is hidden

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

88 files changed

+924
-366
lines changed

bolt/include/bolt/Profile/BoltAddressTranslation.h

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <unordered_map>
2020

2121
namespace llvm {
22+
class MCSymbol;
2223
class raw_ostream;
2324

2425
namespace object {
@@ -123,6 +124,13 @@ class BoltAddressTranslation {
123124
std::unordered_map<uint32_t, std::vector<uint32_t>>
124125
getBFBranches(uint64_t FuncOutputAddress) const;
125126

127+
/// For a given \p Symbol in the output binary and known \p InputOffset
128+
/// return a corresponding pair of parent BinaryFunction and secondary entry
129+
/// point in it.
130+
std::pair<const BinaryFunction *, unsigned>
131+
translateSymbol(const BinaryContext &BC, const MCSymbol &Symbol,
132+
uint32_t InputOffset) const;
133+
126134
private:
127135
/// Helper to update \p Map by inserting one or more BAT entries reflecting
128136
/// \p BB for function located at \p FuncAddress. At least one entry will be
@@ -158,6 +166,10 @@ class BoltAddressTranslation {
158166
/// Map a function to its secondary entry points vector
159167
std::unordered_map<uint64_t, std::vector<uint32_t>> SecondaryEntryPointsMap;
160168

169+
/// Return a secondary entry point ID for a function located at \p Address and
170+
/// \p Offset within that function.
171+
unsigned getSecondaryEntryPointId(uint64_t Address, uint32_t Offset) const;
172+
161173
/// Links outlined cold bocks to their original function
162174
std::map<uint64_t, uint64_t> ColdPartSource;
163175

bolt/include/bolt/Profile/YAMLProfileWriter.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
namespace llvm {
1717
namespace bolt {
18+
class BoltAddressTranslation;
1819
class RewriteInstance;
1920

2021
class YAMLProfileWriter {
@@ -31,8 +32,16 @@ class YAMLProfileWriter {
3132
/// Save execution profile for that instance.
3233
std::error_code writeProfile(const RewriteInstance &RI);
3334

34-
static yaml::bolt::BinaryFunctionProfile convert(const BinaryFunction &BF,
35-
bool UseDFS);
35+
static yaml::bolt::BinaryFunctionProfile
36+
convert(const BinaryFunction &BF, bool UseDFS,
37+
const BoltAddressTranslation *BAT = nullptr);
38+
39+
/// Set CallSiteInfo destination fields from \p Symbol and return a target
40+
/// BinaryFunction for that symbol.
41+
static const BinaryFunction *
42+
setCSIDestination(const BinaryContext &BC, yaml::bolt::CallSiteInfo &CSI,
43+
const MCSymbol *Symbol, const BoltAddressTranslation *BAT,
44+
uint32_t Offset = 0);
3645
};
3746

3847
} // namespace bolt

bolt/lib/Profile/BoltAddressTranslation.cpp

+54-5
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
100100
LLVM_DEBUG(dbgs() << "Function name: " << Function.getPrintName() << "\n");
101101
LLVM_DEBUG(dbgs() << " Address reference: 0x"
102102
<< Twine::utohexstr(Function.getOutputAddress()) << "\n");
103-
LLVM_DEBUG(dbgs() << formatv(" Hash: {0:x}\n", getBFHash(OutputAddress)));
103+
LLVM_DEBUG(dbgs() << formatv(" Hash: {0:x}\n", getBFHash(InputAddress)));
104104
LLVM_DEBUG(dbgs() << " Secondary Entry Points: " << NumSecondaryEntryPoints
105105
<< '\n');
106106

@@ -197,8 +197,9 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
197197
? SecondaryEntryPointsMap[Address].size()
198198
: 0;
199199
if (Cold) {
200-
size_t HotIndex =
201-
std::distance(ColdPartSource.begin(), ColdPartSource.find(Address));
200+
auto HotEntryIt = Maps.find(ColdPartSource[Address]);
201+
assert(HotEntryIt != Maps.end());
202+
size_t HotIndex = std::distance(Maps.begin(), HotEntryIt);
202203
encodeULEB128(HotIndex - PrevIndex, OS);
203204
PrevIndex = HotIndex;
204205
} else {
@@ -207,7 +208,7 @@ void BoltAddressTranslation::writeMaps(std::map<uint64_t, MapTy> &Maps,
207208
LLVM_DEBUG(dbgs() << "Hash: " << formatv("{0:x}\n", BFHash));
208209
OS.write(reinterpret_cast<char *>(&BFHash), 8);
209210
// Number of basic blocks
210-
size_t NumBasicBlocks = getBBHashMap(HotInputAddress).getNumBasicBlocks();
211+
size_t NumBasicBlocks = NumBasicBlocksMap[HotInputAddress];
211212
LLVM_DEBUG(dbgs() << "Basic blocks: " << NumBasicBlocks << '\n');
212213
encodeULEB128(NumBasicBlocks, OS);
213214
// Secondary entry points
@@ -425,8 +426,9 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
425426
for (const auto &MapEntry : Maps) {
426427
const uint64_t Address = MapEntry.first;
427428
const uint64_t HotAddress = fetchParentAddress(Address);
429+
const bool IsHotFunction = HotAddress == 0;
428430
OS << "Function Address: 0x" << Twine::utohexstr(Address);
429-
if (HotAddress == 0)
431+
if (IsHotFunction)
430432
OS << formatv(", hash: {0:x}", getBFHash(Address));
431433
OS << "\n";
432434
OS << "BB mappings:\n";
@@ -443,6 +445,8 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
443445
OS << formatv(" hash: {0:x}", BBHashMap.getBBHash(Val));
444446
OS << "\n";
445447
}
448+
if (IsHotFunction)
449+
OS << "NumBlocks: " << NumBasicBlocksMap[Address] << '\n';
446450
if (SecondaryEntryPointsMap.count(Address)) {
447451
const std::vector<uint32_t> &SecondaryEntryPoints =
448452
SecondaryEntryPointsMap[Address];
@@ -574,6 +578,7 @@ void BoltAddressTranslation::saveMetadata(BinaryContext &BC) {
574578
// Set BF/BB metadata
575579
for (const BinaryBasicBlock &BB : BF)
576580
BBHashMap.addEntry(BB.getInputOffset(), BB.getIndex(), BB.getHash());
581+
NumBasicBlocksMap.emplace(BF.getAddress(), BF.size());
577582
}
578583
}
579584

@@ -597,5 +602,49 @@ BoltAddressTranslation::getBFBranches(uint64_t OutputAddress) const {
597602
return Branches;
598603
}
599604

605+
unsigned
606+
BoltAddressTranslation::getSecondaryEntryPointId(uint64_t Address,
607+
uint32_t Offset) const {
608+
auto FunctionIt = SecondaryEntryPointsMap.find(Address);
609+
if (FunctionIt == SecondaryEntryPointsMap.end())
610+
return 0;
611+
const std::vector<uint32_t> &Offsets = FunctionIt->second;
612+
auto OffsetIt = std::find(Offsets.begin(), Offsets.end(), Offset);
613+
if (OffsetIt == Offsets.end())
614+
return 0;
615+
// Adding one here because main entry point is not stored in BAT, and
616+
// enumeration for secondary entry points starts with 1.
617+
return OffsetIt - Offsets.begin() + 1;
618+
}
619+
620+
std::pair<const BinaryFunction *, unsigned>
621+
BoltAddressTranslation::translateSymbol(const BinaryContext &BC,
622+
const MCSymbol &Symbol,
623+
uint32_t Offset) const {
624+
// The symbol could be a secondary entry in a cold fragment.
625+
uint64_t SymbolValue = cantFail(errorOrToExpected(BC.getSymbolValue(Symbol)));
626+
627+
const BinaryFunction *Callee = BC.getFunctionForSymbol(&Symbol);
628+
assert(Callee);
629+
630+
// Containing function, not necessarily the same as symbol value.
631+
const uint64_t CalleeAddress = Callee->getAddress();
632+
const uint32_t OutputOffset = SymbolValue - CalleeAddress;
633+
634+
const uint64_t ParentAddress = fetchParentAddress(CalleeAddress);
635+
const uint64_t HotAddress = ParentAddress ? ParentAddress : CalleeAddress;
636+
637+
const BinaryFunction *ParentBF = BC.getBinaryFunctionAtAddress(HotAddress);
638+
639+
const uint32_t InputOffset =
640+
translate(CalleeAddress, OutputOffset, /*IsBranchSrc*/ false) + Offset;
641+
642+
unsigned SecondaryEntryId{0};
643+
if (InputOffset)
644+
SecondaryEntryId = getSecondaryEntryPointId(HotAddress, InputOffset);
645+
646+
return std::pair(ParentBF, SecondaryEntryId);
647+
}
648+
600649
} // namespace bolt
601650
} // namespace llvm

bolt/lib/Profile/DataAggregator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
23332333
if (BAT->isBATFunction(Function.getAddress()))
23342334
continue;
23352335
BP.Functions.emplace_back(
2336-
YAMLProfileWriter::convert(Function, /*UseDFS=*/false));
2336+
YAMLProfileWriter::convert(Function, /*UseDFS=*/false, BAT));
23372337
}
23382338

23392339
for (const auto &KV : NamesToBranches) {

bolt/lib/Profile/YAMLProfileWriter.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "bolt/Profile/YAMLProfileWriter.h"
1010
#include "bolt/Core/BinaryBasicBlock.h"
1111
#include "bolt/Core/BinaryFunction.h"
12+
#include "bolt/Profile/BoltAddressTranslation.h"
1213
#include "bolt/Profile/ProfileReaderBase.h"
1314
#include "bolt/Rewrite/RewriteInstance.h"
1415
#include "llvm/Support/CommandLine.h"
@@ -25,17 +26,19 @@ extern llvm::cl::opt<bool> ProfileUseDFS;
2526
namespace llvm {
2627
namespace bolt {
2728

28-
/// Set CallSiteInfo destination fields from \p Symbol and return a target
29-
/// BinaryFunction for that symbol.
30-
static const BinaryFunction *setCSIDestination(const BinaryContext &BC,
31-
yaml::bolt::CallSiteInfo &CSI,
32-
const MCSymbol *Symbol) {
29+
const BinaryFunction *YAMLProfileWriter::setCSIDestination(
30+
const BinaryContext &BC, yaml::bolt::CallSiteInfo &CSI,
31+
const MCSymbol *Symbol, const BoltAddressTranslation *BAT,
32+
uint32_t Offset) {
3333
CSI.DestId = 0; // designated for unknown functions
3434
CSI.EntryDiscriminator = 0;
35+
3536
if (Symbol) {
3637
uint64_t EntryID = 0;
37-
if (const BinaryFunction *const Callee =
38+
if (const BinaryFunction *Callee =
3839
BC.getFunctionForSymbol(Symbol, &EntryID)) {
40+
if (BAT && BAT->isBATFunction(Callee->getAddress()))
41+
std::tie(Callee, EntryID) = BAT->translateSymbol(BC, *Symbol, Offset);
3942
CSI.DestId = Callee->getFunctionNumber();
4043
CSI.EntryDiscriminator = EntryID;
4144
return Callee;
@@ -45,7 +48,8 @@ static const BinaryFunction *setCSIDestination(const BinaryContext &BC,
4548
}
4649

4750
yaml::bolt::BinaryFunctionProfile
48-
YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS) {
51+
YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
52+
const BoltAddressTranslation *BAT) {
4953
yaml::bolt::BinaryFunctionProfile YamlBF;
5054
const BinaryContext &BC = BF.getBinaryContext();
5155

@@ -98,7 +102,8 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS) {
98102
continue;
99103
for (const IndirectCallProfile &CSP : ICSP.get()) {
100104
StringRef TargetName = "";
101-
const BinaryFunction *Callee = setCSIDestination(BC, CSI, CSP.Symbol);
105+
const BinaryFunction *Callee =
106+
setCSIDestination(BC, CSI, CSP.Symbol, BAT);
102107
if (Callee)
103108
TargetName = Callee->getOneName();
104109
CSI.Count = CSP.Count;
@@ -109,7 +114,7 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS) {
109114
StringRef TargetName = "";
110115
const MCSymbol *CalleeSymbol = BC.MIB->getTargetSymbol(Instr);
111116
const BinaryFunction *const Callee =
112-
setCSIDestination(BC, CSI, CalleeSymbol);
117+
setCSIDestination(BC, CSI, CalleeSymbol, BAT);
113118
if (Callee)
114119
TargetName = Callee->getOneName();
115120

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,14 @@ YAML-BAT-CHECK-NEXT: - bid: 0
3636
YAML-BAT-CHECK-NEXT: insns: 26
3737
YAML-BAT-CHECK-NEXT: hash: 0xA900AE79CFD40000
3838
YAML-BAT-CHECK-NEXT: succ: [ { bid: 3, cnt: 0 }, { bid: 1, cnt: 0 } ]
39+
# Calls from no-BAT to BAT function
40+
YAML-BAT-CHECK: - bid: 28
41+
YAML-BAT-CHECK-NEXT: insns: 13
42+
YAML-BAT-CHECK-NEXT: hash: 0xB2F04C1F25F00400
43+
YAML-BAT-CHECK-NEXT: calls: [ { off: 0x21, fid: [[#SOLVECUBIC:]], cnt: 25 }, { off: 0x2D, fid: [[#]], cnt: 9 } ]
3944
# Function covered by BAT with calls
4045
YAML-BAT-CHECK: - name: SolveCubic
41-
YAML-BAT-CHECK-NEXT: fid: [[#]]
46+
YAML-BAT-CHECK-NEXT: fid: [[#SOLVECUBIC]]
4247
YAML-BAT-CHECK-NEXT: hash: 0x6AF7E61EA3966722
4348
YAML-BAT-CHECK-NEXT: exec: 25
4449
YAML-BAT-CHECK-NEXT: nblocks: 15

bolt/test/X86/yaml-secondary-entry-discriminator.s

+16-3
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@
1111
# RUN: FileCheck %s -input-file %t.yaml
1212
# CHECK: - name: main
1313
# CHECK-NEXT: fid: 2
14-
# CHECK-NEXT: hash: 0xADF270D550151185
14+
# CHECK-NEXT: hash: {{.*}}
1515
# CHECK-NEXT: exec: 0
1616
# CHECK-NEXT: nblocks: 4
1717
# CHECK-NEXT: blocks:
1818
# CHECK: - bid: 1
1919
# CHECK-NEXT: insns: 1
20-
# CHECK-NEXT: hash: 0x36A303CBA4360014
20+
# CHECK-NEXT: hash: {{.*}}
2121
# CHECK-NEXT: calls: [ { off: 0x0, fid: 1, disc: 1, cnt: 1 } ]
2222
# CHECK: - bid: 2
2323
# CHECK-NEXT: insns: 5
24-
# CHECK-NEXT: hash: 0x8B2F5747CD0019
24+
# CHECK-NEXT: hash: {{.*}}
2525
# CHECK-NEXT: calls: [ { off: 0x0, fid: 1, disc: 1, cnt: 1, mis: 1 } ]
2626

2727
# Make sure that the profile is attached correctly
@@ -33,15 +33,28 @@
3333
# CHECK-CFG: callq *%rax # Offset: [[#]] # CallProfile: 1 (1 misses) :
3434
# CHECK-CFG-NEXT: { secondary_entry: 1 (1 misses) }
3535

36+
# YAML BAT test of calling BAT secondary entry from non-BAT function
37+
# Now force-split func and skip main (making it call secondary entries)
38+
# RUN: llvm-bolt %t.exe -o %t.bat --data %t.fdata --funcs=func \
39+
# RUN: --split-functions --split-strategy=all --split-all-cold --enable-bat
40+
3641
.globl func
3742
.type func, @function
3843
func:
3944
# FDATA: 0 [unknown] 0 1 func 0 1 0
4045
.cfi_startproc
4146
pushq %rbp
4247
movq %rsp, %rbp
48+
# Placeholder code to make splitting profitable
49+
.rept 5
50+
testq %rax, %rax
51+
.endr
4352
.globl secondary_entry
4453
secondary_entry:
54+
# Placeholder code to make splitting profitable
55+
.rept 5
56+
testq %rax, %rax
57+
.endr
4558
popq %rbp
4659
retq
4760
nopl (%rax)

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

+4
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ void DuplicateIncludeCallbacks::InclusionDirective(
7979
bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
8080
StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
8181
bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
82+
// Skip includes behind macros
83+
if (FilenameRange.getBegin().isMacroID() ||
84+
FilenameRange.getEnd().isMacroID())
85+
return;
8286
if (llvm::is_contained(Files.back(), FileName)) {
8387
// We want to delete the entire line, so make sure that [Start,End] covers
8488
// everything.

clang-tools-extra/docs/ReleaseNotes.rst

+4
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ Changes in existing checks
255255
analyzed, se the check now handles the common patterns
256256
`const auto e = (*vector_ptr)[i]` and `const auto e = vector_ptr->at(i);`.
257257

258+
- Improved :doc:`readability-duplicate-include
259+
<clang-tidy/checks/readability/duplicate-include>` check by excluding include
260+
directives that form the filename using macro.
261+
258262
- Improved :doc:`readability-identifier-naming
259263
<clang-tidy/checks/readability/identifier-naming>` check in `GetConfigPerFile`
260264
mode by resolving symbolic links to header files. Fixed handling of Hungarian

clang-tools-extra/test/clang-tidy/checkers/readability/duplicate-include.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,18 @@ int r;
7070
// CHECK-FIXES: {{^int q;$}}
7171
// CHECK-FIXES-NEXT: {{^#include <sys/types.h>$}}
7272
// CHECK-FIXES-NEXT: {{^int r;$}}
73+
74+
namespace Issue_87303 {
75+
#define RESET_INCLUDE_CACHE
76+
// Expect no warnings
77+
78+
#define MACRO_FILENAME "duplicate-include.h"
79+
#include MACRO_FILENAME
80+
#include "duplicate-include.h"
81+
82+
#define MACRO_FILENAME_2 <duplicate-include2.h>
83+
#include <duplicate-include2.h>
84+
#include MACRO_FILENAME_2
85+
86+
#undef RESET_INCLUDE_CACHE
87+
} // Issue_87303

clang/include/clang/Basic/DiagnosticSemaKinds.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def ext_vla_folded_to_constant : ExtWarn<
165165
"variable length array folded to constant array as an extension">,
166166
InGroup<GNUFoldingConstant>;
167167
def err_vla_unsupported : Error<
168-
"variable length arrays are not supported for %select{the current target|'%1'}0">;
168+
"variable length arrays are not supported %select{for the current target|in '%1'}0">;
169169
def err_vla_in_coroutine_unsupported : Error<
170170
"variable length arrays in a coroutine are not supported">;
171171
def note_vla_unsupported : Note<

clang/lib/Format/FormatTokenLexer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ bool FormatTokenLexer::tryMergeNullishCoalescingEqual() {
404404
return false;
405405
auto &NullishCoalescing = *(Tokens.end() - 2);
406406
auto &Equal = *(Tokens.end() - 1);
407-
if (NullishCoalescing->getType() != TT_NullCoalescingOperator ||
407+
if (NullishCoalescing->isNot(TT_NullCoalescingOperator) ||
408408
Equal->isNot(tok::equal)) {
409409
return false;
410410
}

0 commit comments

Comments
 (0)