Skip to content

Commit 482c56d

Browse files
committed
Merge branch 'main' into users/vikramRH/enable_opt
2 parents 2392e73 + 0d9d5f7 commit 482c56d

File tree

4,384 files changed

+66850
-23182
lines changed

Some content is hidden

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

4,384 files changed

+66850
-23182
lines changed

.github/new-prs-labeler.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,29 @@ backend:AArch64:
775775
- clang/include/clang/Sema/SemaARM.h
776776
- clang/lib/Sema/SemaARM.cpp
777777

778+
backend:Hexagon:
779+
- clang/include/clang/Basic/BuiltinsHexagon*.def
780+
- clang/include/clang/Sema/SemaHexagon.h
781+
- clang/lib/Basic/Targets/Hexagon.*
782+
- clang/lib/CodeGen/Targets/Hexagon.cpp
783+
- clang/lib/Driver/ToolChains/Hexagon.*
784+
- clang/lib/Sema/SemaHexagon.cpp
785+
- lld/ELF/Arch/Hexagon.cpp
786+
- lldb/source/Plugins/ABI/Hexagon/**
787+
- lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/**
788+
- llvm/include/llvm/BinaryFormat/ELFRelocs/Hexagon.def
789+
- llvm/include/llvm/IR/IntrinsicsHexagon*
790+
- llvm/include/llvm/Support/Hexagon*
791+
- llvm/lib/Support/Hexagon*
792+
- llvm/lib/Target/Hexagon/**
793+
- llvm/test/CodeGen/Hexagon/**
794+
- llvm/test/CodeGen/*/Hexagon/**
795+
- llvm/test/DebugInfo/*/Hexagon/**
796+
- llvm/test/Transforms/*/Hexagon
797+
- llvm/test/MC/Disassembler/Hexagon/**
798+
- llvm/test/MC/Hexagon/**
799+
- llvm/test/tools/llvm-objdump/ELF/Hexagon/**
800+
778801
backend:loongarch:
779802
- llvm/include/llvm/IR/IntrinsicsLoongArch.td
780803
- llvm/test/MC/LoongArch/**

bolt/include/bolt/Core/DebugData.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,17 +226,16 @@ class DebugRangesSectionWriter {
226226
/// Needs to be invoked before each \p CU is processed.
227227
void virtual initSection(DWARFUnit &CU){};
228228

229+
/// Initializes Ranges section with empty list.
230+
void initSection();
231+
229232
protected:
230233
std::unique_ptr<DebugBufferVector> RangesBuffer;
231234

232235
std::unique_ptr<raw_svector_ostream> RangesStream;
233236

234237
std::mutex WriterMutex;
235238

236-
/// Current offset in the section (updated as new entries are written).
237-
/// Starts with 16 since the first 16 bytes are reserved for an empty range.
238-
uint32_t SectionOffset{0};
239-
240239
/// Offset of an empty address ranges list.
241240
static constexpr uint64_t EmptyRangesOffset{0};
242241

bolt/include/bolt/Core/HashUtilities.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "bolt/Core/BinaryBasicBlock.h"
1818
#include "bolt/Core/BinaryContext.h"
19+
#include "bolt/Profile/ProfileYAMLMapping.h"
1920

2021
namespace llvm {
2122
namespace bolt {
@@ -35,6 +36,13 @@ std::string hashBlock(BinaryContext &BC, const BinaryBasicBlock &BB,
3536

3637
std::string hashBlockLoose(BinaryContext &BC, const BinaryBasicBlock &BB);
3738

39+
std::string hashBlockCalls(BinaryContext &BC, const BinaryBasicBlock &BB);
40+
41+
std::string
42+
hashBlockCalls(const DenseMap<uint32_t, yaml::bolt::BinaryFunctionProfile *>
43+
&IdToYamlFunction,
44+
const yaml::bolt::BinaryBasicBlockProfile &YamlBB);
45+
3846
} // namespace bolt
3947
} // namespace llvm
4048

bolt/include/bolt/Profile/YAMLProfileReader.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class YAMLProfileReader : public ProfileReaderBase {
4040
/// Check if the file contains YAML.
4141
static bool isYAML(StringRef Filename);
4242

43+
using ProfileLookupMap =
44+
DenseMap<uint32_t, yaml::bolt::BinaryFunctionProfile *>;
45+
4346
private:
4447
/// Adjustments for basic samples profiles (without LBR).
4548
bool NormalizeByInsnCount{false};
@@ -56,6 +59,10 @@ class YAMLProfileReader : public ProfileReaderBase {
5659
/// is attributed.
5760
FunctionSet ProfiledFunctions;
5861

62+
/// Maps profiled function id to function, for function matching with calls as
63+
/// anchors.
64+
ProfileLookupMap IdToYamLBF;
65+
5966
/// For LTO symbol resolution.
6067
/// Map a common LTO prefix to a list of YAML profiles matching the prefix.
6168
StringMap<std::vector<yaml::bolt::BinaryFunctionProfile *>> LTOCommonNameMap;

bolt/include/bolt/Utils/NameResolver.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ class NameResolver {
6161
std::tie(LHS, RHS) = UniqueName.split(Sep);
6262
return (LHS + Suffix + Twine(Sep) + RHS).str();
6363
}
64+
65+
// Drops the suffix that describes the function's number of names.
66+
static StringRef dropNumNames(StringRef Name) {
67+
const size_t Pos = Name.find("(*");
68+
return Pos != StringRef::npos ? Name.substr(0, Pos) : Name;
69+
}
6470
};
6571

6672
} // namespace bolt

bolt/lib/Core/DebugData.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,14 @@ DebugRangesSectionWriter::DebugRangesSectionWriter() {
137137
RangesBuffer = std::make_unique<DebugBufferVector>();
138138
RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
139139

140-
// Add an empty range as the first entry;
141-
SectionOffset +=
142-
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
143140
Kind = RangesWriterKind::DebugRangesWriter;
144141
}
145142

143+
void DebugRangesSectionWriter::initSection() {
144+
// Adds an empty range to the buffer.
145+
writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
146+
}
147+
146148
uint64_t DebugRangesSectionWriter::addRanges(
147149
DebugAddressRangesVector &&Ranges,
148150
std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
@@ -166,21 +168,20 @@ uint64_t DebugRangesSectionWriter::addRanges(DebugAddressRangesVector &Ranges) {
166168
// Reading the SectionOffset and updating it should be atomic to guarantee
167169
// unique and correct offsets in patches.
168170
std::lock_guard<std::mutex> Lock(WriterMutex);
169-
const uint32_t EntryOffset = SectionOffset;
170-
SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
171+
const uint32_t EntryOffset = RangesBuffer->size();
172+
writeAddressRanges(*RangesStream.get(), Ranges);
171173

172174
return EntryOffset;
173175
}
174176

175177
uint64_t DebugRangesSectionWriter::getSectionOffset() {
176178
std::lock_guard<std::mutex> Lock(WriterMutex);
177-
return SectionOffset;
179+
return RangesBuffer->size();
178180
}
179181

180182
void DebugRangesSectionWriter::appendToRangeBuffer(
181183
const DebugBufferVector &CUBuffer) {
182184
*RangesStream << CUBuffer;
183-
SectionOffset = RangesBuffer->size();
184185
}
185186

186187
DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
@@ -327,7 +328,6 @@ void DebugRangeListsSectionWriter::finalizeSection() {
327328
*RangesStream << *Header;
328329
*RangesStream << *CUArrayBuffer;
329330
*RangesStream << *CUBodyBuffer;
330-
SectionOffset = RangesBuffer->size();
331331
}
332332

333333
void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {

bolt/lib/Core/HashUtilities.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "bolt/Core/HashUtilities.h"
1414
#include "bolt/Core/BinaryContext.h"
15+
#include "bolt/Utils/NameResolver.h"
1516
#include "llvm/MC/MCInstPrinter.h"
1617

1718
namespace llvm {
@@ -155,5 +156,50 @@ std::string hashBlockLoose(BinaryContext &BC, const BinaryBasicBlock &BB) {
155156
return HashString;
156157
}
157158

159+
/// An even looser hash level relative to $ hashBlockLoose to use with stale
160+
/// profile matching, composed of the names of a block's called functions in
161+
/// lexicographic order.
162+
std::string hashBlockCalls(BinaryContext &BC, const BinaryBasicBlock &BB) {
163+
// The hash is computed by creating a string of all lexicographically ordered
164+
// called function names.
165+
std::vector<std::string> FunctionNames;
166+
for (const MCInst &Instr : BB) {
167+
// Skip non-call instructions.
168+
if (!BC.MIB->isCall(Instr))
169+
continue;
170+
const MCSymbol *CallSymbol = BC.MIB->getTargetSymbol(Instr);
171+
if (!CallSymbol)
172+
continue;
173+
FunctionNames.push_back(std::string(CallSymbol->getName()));
174+
}
175+
std::sort(FunctionNames.begin(), FunctionNames.end());
176+
std::string HashString;
177+
for (const std::string &FunctionName : FunctionNames)
178+
HashString.append(FunctionName);
179+
180+
return HashString;
181+
}
182+
183+
/// The same as the $hashBlockCalls function, but for profiled functions.
184+
std::string
185+
hashBlockCalls(const DenseMap<uint32_t, yaml::bolt::BinaryFunctionProfile *>
186+
&IdToYamlFunction,
187+
const yaml::bolt::BinaryBasicBlockProfile &YamlBB) {
188+
std::vector<std::string> FunctionNames;
189+
for (const yaml::bolt::CallSiteInfo &CallSiteInfo : YamlBB.CallSites) {
190+
auto It = IdToYamlFunction.find(CallSiteInfo.DestId);
191+
if (It == IdToYamlFunction.end())
192+
continue;
193+
StringRef Name = NameResolver::dropNumNames(It->second->Name);
194+
FunctionNames.push_back(std::string(Name));
195+
}
196+
std::sort(FunctionNames.begin(), FunctionNames.end());
197+
std::string HashString;
198+
for (const std::string &FunctionName : FunctionNames)
199+
HashString.append(FunctionName);
200+
201+
return HashString;
202+
}
203+
158204
} // namespace bolt
159205
} // namespace llvm

bolt/lib/Profile/StaleProfileMatching.cpp

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,43 @@ class StaleMatcher {
193193
public:
194194
/// Initialize stale matcher.
195195
void init(const std::vector<FlowBlock *> &Blocks,
196-
const std::vector<BlendedBlockHash> &Hashes) {
196+
const std::vector<BlendedBlockHash> &Hashes,
197+
const std::vector<uint64_t> &CallHashes) {
197198
assert(Blocks.size() == Hashes.size() &&
199+
Hashes.size() == CallHashes.size() &&
198200
"incorrect matcher initialization");
199201
for (size_t I = 0; I < Blocks.size(); I++) {
200202
FlowBlock *Block = Blocks[I];
201203
uint16_t OpHash = Hashes[I].OpcodeHash;
202204
OpHashToBlocks[OpHash].push_back(std::make_pair(Hashes[I], Block));
205+
if (CallHashes[I])
206+
CallHashToBlocks[CallHashes[I]].push_back(
207+
std::make_pair(Hashes[I], Block));
203208
}
204209
}
205210

206211
/// Find the most similar block for a given hash.
207-
const FlowBlock *matchBlock(BlendedBlockHash BlendedHash) const {
212+
const FlowBlock *matchBlock(BlendedBlockHash BlendedHash,
213+
uint64_t CallHash) const {
214+
const FlowBlock *BestBlock = matchWithOpcodes(BlendedHash);
215+
return BestBlock ? BestBlock : matchWithCalls(BlendedHash, CallHash);
216+
}
217+
218+
/// Returns true if the two basic blocks (in the binary and in the profile)
219+
/// corresponding to the given hashes are matched to each other with a high
220+
/// confidence.
221+
static bool isHighConfidenceMatch(BlendedBlockHash Hash1,
222+
BlendedBlockHash Hash2) {
223+
return Hash1.InstrHash == Hash2.InstrHash;
224+
}
225+
226+
private:
227+
using HashBlockPairType = std::pair<BlendedBlockHash, FlowBlock *>;
228+
std::unordered_map<uint16_t, std::vector<HashBlockPairType>> OpHashToBlocks;
229+
std::unordered_map<uint64_t, std::vector<HashBlockPairType>> CallHashToBlocks;
230+
231+
// Uses OpcodeHash to find the most similar block for a given hash.
232+
const FlowBlock *matchWithOpcodes(BlendedBlockHash BlendedHash) const {
208233
auto BlockIt = OpHashToBlocks.find(BlendedHash.OpcodeHash);
209234
if (BlockIt == OpHashToBlocks.end())
210235
return nullptr;
@@ -220,17 +245,27 @@ class StaleMatcher {
220245
return BestBlock;
221246
}
222247

223-
/// Returns true if the two basic blocks (in the binary and in the profile)
224-
/// corresponding to the given hashes are matched to each other with a high
225-
/// confidence.
226-
static bool isHighConfidenceMatch(BlendedBlockHash Hash1,
227-
BlendedBlockHash Hash2) {
228-
return Hash1.InstrHash == Hash2.InstrHash;
248+
// Uses CallHash to find the most similar block for a given hash.
249+
const FlowBlock *matchWithCalls(BlendedBlockHash BlendedHash,
250+
uint64_t CallHash) const {
251+
if (!CallHash)
252+
return nullptr;
253+
auto BlockIt = CallHashToBlocks.find(CallHash);
254+
if (BlockIt == CallHashToBlocks.end())
255+
return nullptr;
256+
FlowBlock *BestBlock = nullptr;
257+
uint64_t BestDist = std::numeric_limits<uint64_t>::max();
258+
for (const auto &[Hash, Block] : BlockIt->second) {
259+
uint64_t Dist = Hash.OpcodeHash > BlendedHash.OpcodeHash
260+
? Hash.OpcodeHash - BlendedHash.OpcodeHash
261+
: BlendedHash.OpcodeHash - Hash.OpcodeHash;
262+
if (BestBlock == nullptr || Dist < BestDist) {
263+
BestDist = Dist;
264+
BestBlock = Block;
265+
}
266+
}
267+
return BestBlock;
229268
}
230-
231-
private:
232-
using HashBlockPairType = std::pair<BlendedBlockHash, FlowBlock *>;
233-
std::unordered_map<uint16_t, std::vector<HashBlockPairType>> OpHashToBlocks;
234269
};
235270

236271
void BinaryFunction::computeBlockHashes(HashFunction HashFunction) const {
@@ -412,33 +447,62 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
412447
/// of the basic blocks in the binary, the count is "matched" to the block.
413448
/// Similarly, if both the source and the target of a count in the profile are
414449
/// matched to a jump in the binary, the count is recorded in CFG.
415-
size_t matchWeightsByHashes(
416-
BinaryContext &BC, const BinaryFunction::BasicBlockOrderType &BlockOrder,
417-
const yaml::bolt::BinaryFunctionProfile &YamlBF, FlowFunction &Func) {
450+
size_t
451+
matchWeightsByHashes(BinaryContext &BC,
452+
const BinaryFunction::BasicBlockOrderType &BlockOrder,
453+
const yaml::bolt::BinaryFunctionProfile &YamlBF,
454+
FlowFunction &Func, HashFunction HashFunction,
455+
YAMLProfileReader::ProfileLookupMap &IdToYamlBF) {
456+
418457
assert(Func.Blocks.size() == BlockOrder.size() + 2);
419458

459+
std::vector<uint64_t> CallHashes;
420460
std::vector<FlowBlock *> Blocks;
421461
std::vector<BlendedBlockHash> BlendedHashes;
422462
for (uint64_t I = 0; I < BlockOrder.size(); I++) {
423463
const BinaryBasicBlock *BB = BlockOrder[I];
424464
assert(BB->getHash() != 0 && "empty hash of BinaryBasicBlock");
465+
466+
std::string CallHashStr = hashBlockCalls(BC, *BB);
467+
if (CallHashStr.empty()) {
468+
CallHashes.push_back(0);
469+
} else {
470+
if (HashFunction == HashFunction::StdHash)
471+
CallHashes.push_back(std::hash<std::string>{}(CallHashStr));
472+
else if (HashFunction == HashFunction::XXH3)
473+
CallHashes.push_back(llvm::xxh3_64bits(CallHashStr));
474+
else
475+
llvm_unreachable("Unhandled HashFunction");
476+
}
477+
425478
Blocks.push_back(&Func.Blocks[I + 1]);
426479
BlendedBlockHash BlendedHash(BB->getHash());
427480
BlendedHashes.push_back(BlendedHash);
428481
LLVM_DEBUG(dbgs() << "BB with index " << I << " has hash = "
429482
<< Twine::utohexstr(BB->getHash()) << "\n");
430483
}
431484
StaleMatcher Matcher;
432-
Matcher.init(Blocks, BlendedHashes);
485+
Matcher.init(Blocks, BlendedHashes, CallHashes);
433486

434487
// Index in yaml profile => corresponding (matched) block
435488
DenseMap<uint64_t, const FlowBlock *> MatchedBlocks;
436489
// Match blocks from the profile to the blocks in CFG
437490
for (const yaml::bolt::BinaryBasicBlockProfile &YamlBB : YamlBF.Blocks) {
438491
assert(YamlBB.Hash != 0 && "empty hash of BinaryBasicBlockProfile");
439492
BlendedBlockHash YamlHash(YamlBB.Hash);
440-
const FlowBlock *MatchedBlock = Matcher.matchBlock(YamlHash);
441-
// Always match the entry block.
493+
494+
const FlowBlock *MatchedBlock = nullptr;
495+
std::string CallHashStr = hashBlockCalls(IdToYamlBF, YamlBB);
496+
uint64_t CallHash = 0;
497+
if (!CallHashStr.empty()) {
498+
if (HashFunction == HashFunction::StdHash)
499+
CallHash = std::hash<std::string>{}(CallHashStr);
500+
else if (HashFunction == HashFunction::XXH3)
501+
CallHash = llvm::xxh3_64bits(CallHashStr);
502+
else
503+
llvm_unreachable("Unhandled HashFunction");
504+
}
505+
MatchedBlock = Matcher.matchBlock(YamlHash, CallHash);
442506
if (MatchedBlock == nullptr && YamlBB.Index == 0)
443507
MatchedBlock = Blocks[0];
444508
if (MatchedBlock != nullptr) {
@@ -763,7 +827,8 @@ bool YAMLProfileReader::inferStaleProfile(
763827

764828
// Match as many block/jump counts from the stale profile as possible
765829
size_t MatchedBlocks =
766-
matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func);
830+
matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func,
831+
YamlBP.Header.HashFunction, IdToYamLBF);
767832

768833
// Adjust the flow function by marking unreachable blocks Unlikely so that
769834
// they don't get any counts assigned.

bolt/lib/Profile/YAMLProfileReader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,10 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
611611
NormalizeByInsnCount = usesEvent("cycles") || usesEvent("instructions");
612612
NormalizeByCalls = usesEvent("branches");
613613

614+
// Map profiled function ids to names.
615+
for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions)
616+
IdToYamLBF[YamlBF.Id] = &YamlBF;
617+
614618
uint64_t NumUnused = 0;
615619
for (yaml::bolt::BinaryFunctionProfile &YamlBF : YamlBP.Functions) {
616620
if (YamlBF.Id >= YamlProfileToFunction.size()) {

0 commit comments

Comments
 (0)