Skip to content

Commit a258a55

Browse files
committed
LLVM and SPIRV-LLVM-Translator pulldown (WW18)
LLVM: llvm/llvm-project@483efc9 SPIRV-LLVM-Translator: KhronosGroup/SPIRV-LLVM-Translator@28fdb7a
2 parents e59fb89 + 49464bb commit a258a55

File tree

9,052 files changed

+284273
-176656
lines changed

Some content is hidden

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

9,052 files changed

+284273
-176656
lines changed

bolt/CMakeLists.txt

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,7 @@ if (BOLT_ENABLE_RUNTIME)
5959
COMPONENT bolt)
6060
endif()
6161

62-
# Get the current git revision for BOLT.
63-
find_program(git_executable NAMES git git.exe git.cmd)
64-
if (git_executable)
65-
execute_process(COMMAND ${git_executable} rev-parse HEAD
66-
WORKING_DIRECTORY ${LLVM_MAIN_SRC_DIR}
67-
TIMEOUT 5
68-
RESULT_VARIABLE git_result
69-
OUTPUT_VARIABLE git_output)
70-
if( git_result EQUAL 0 )
71-
string(STRIP "${git_output}" git_ref_id)
72-
set(BOLT_REVISION "${git_ref_id}")
73-
endif()
74-
endif()
75-
76-
# If we can't find a revision, set it to "<unknown>".
77-
if (NOT BOLT_REVISION)
78-
set(BOLT_REVISION "<unknown>")
79-
endif()
80-
81-
configure_file(
82-
${CMAKE_CURRENT_SOURCE_DIR}/include/bolt/Utils/BoltRevision.inc.in
83-
${CMAKE_CURRENT_BINARY_DIR}/include/bolt/Utils/BoltRevision.inc)
62+
find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld")
8463

8564
include_directories(
8665
${CMAKE_CURRENT_SOURCE_DIR}/include

bolt/docs/Heatmaps.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ or if you want to monitor the existing process(es):
2020
$ perf record -e cycles:u -j any,u [-p PID|-a] -- sleep <interval>
2121
```
2222

23-
Note that at the moment running with LBR (`-j any,u` or `-b`) is
24-
a requirement.
23+
Running with LBR (`-j any,u` or `-b`) is recommended. Heatmaps can be generated
24+
from basic events by using the llvm-bolt-heatmap option `-nl` (no LBR) but
25+
such heatmaps do not have the coverage provided by LBR and may only be useful
26+
for finding event hotspots at larger code block granularities.
2527

2628
Once the run is complete, and `perf.data` is generated, run llvm-bolt-heatmap:
2729

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,22 @@ class BinaryContext {
774774
return Itr != GlobalSymbols.end() ? Itr->second : nullptr;
775775
}
776776

777+
/// Return registered PLT entry BinaryData with the given \p Name
778+
/// or nullptr if no global PLT symbol with that name exists.
779+
const BinaryData *getPLTBinaryDataByName(StringRef Name) const {
780+
if (const BinaryData *Data = getBinaryDataByName(Name.str() + "@PLT"))
781+
return Data;
782+
783+
// The symbol name might contain versioning information e.g
784+
// memcpy@@GLIBC_2.17. Remove it and try to locate binary data
785+
// without it.
786+
size_t At = Name.find("@");
787+
if (At != std::string::npos)
788+
return getBinaryDataByName(Name.str().substr(0, At) + "@PLT");
789+
790+
return nullptr;
791+
}
792+
777793
/// Return true if \p SymbolName was generated internally and was not present
778794
/// in the input binary.
779795
bool isInternalSymbolName(const StringRef Name) {
@@ -954,6 +970,15 @@ class BinaryContext {
954970
Sections.end()));
955971
}
956972

973+
/// Return base address for the shared object or PIE based on the segment
974+
/// mapping information. \p MMapAddress is an address where one of the
975+
/// segments was mapped. \p FileOffset is the offset in the file of the
976+
/// mapping. Note that \p FileOffset should be page-aligned and could be
977+
/// different from the file offset of the segment which could be unaligned.
978+
/// If no segment is found that matches \p FileOffset, return NoneType().
979+
Optional<uint64_t> getBaseAddressForMapping(uint64_t MMapAddress,
980+
uint64_t FileOffset) const;
981+
957982
/// Check if the address belongs to this binary's static allocation space.
958983
bool containsAddress(uint64_t Address) const {
959984
return Address >= FirstAllocAddress && Address < LayoutStartAddress;

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ class MCPlusBuilder {
353353
}
354354

355355
virtual bool isUnconditionalBranch(const MCInst &Inst) const {
356-
return Analysis->isUnconditionalBranch(Inst);
356+
return Analysis->isUnconditionalBranch(Inst) && !isTailCall(Inst);
357357
}
358358

359359
virtual bool isIndirectBranch(const MCInst &Inst) const {
@@ -511,11 +511,6 @@ class MCPlusBuilder {
511511
return 0;
512512
}
513513

514-
virtual bool isADD64rr(const MCInst &Inst) const {
515-
llvm_unreachable("not implemented");
516-
return false;
517-
}
518-
519514
virtual bool isSUB(const MCInst &Inst) const {
520515
llvm_unreachable("not implemented");
521516
return false;

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,15 @@ class DataAggregator : public DataReader {
168168
/// from the file name in BC.
169169
std::string BuildIDBinaryName;
170170

171-
/// Memory map info for a single file
171+
/// Memory map info for a single file as recorded in perf.data
172172
struct MMapInfo {
173-
uint64_t BaseAddress;
174-
uint64_t Size;
175-
uint64_t Offset;
176-
int32_t PID{-1};
177-
bool Forked{false};
178-
uint64_t Time{0ULL}; // time in micro seconds
173+
uint64_t BaseAddress{0}; /// Base address of the mapped binary.
174+
uint64_t MMapAddress{0}; /// Address of the executable segment.
175+
uint64_t Size{0}; /// Size of the mapping.
176+
uint64_t Offset{0}; /// File offset of the mapped segment.
177+
int32_t PID{-1}; /// Process ID.
178+
bool Forked{false}; /// Was the process forked?
179+
uint64_t Time{0ULL}; /// Time in micro seconds.
179180
};
180181

181182
/// Per-PID map info for the binary
@@ -420,12 +421,8 @@ class DataAggregator : public DataReader {
420421
/// correspond to the binary allocated address space, are adjusted to avoid
421422
/// conflicts.
422423
void adjustAddress(uint64_t &Address, const MMapInfo &MMI) const {
423-
if (Address >= MMI.BaseAddress && Address < MMI.BaseAddress + MMI.Size) {
424-
// NOTE: Assumptions about the binary segment load table (PH for ELF)
425-
// Segment file offset equals virtual address (which is true for .so)
426-
// There aren't multiple executable segments loaded because MMapInfo
427-
// doesn't support them.
428-
Address -= MMI.BaseAddress - MMI.Offset;
424+
if (Address >= MMI.MMapAddress && Address < MMI.MMapAddress + MMI.Size) {
425+
Address -= MMI.BaseAddress;
429426
} else if (Address < MMI.Size) {
430427
// Make sure the address is not treated as belonging to the binary.
431428
Address = (-1ULL);

bolt/include/bolt/Utils/BoltRevision.inc.in

Lines changed: 0 additions & 1 deletion
This file was deleted.

bolt/lib/Core/BinaryContext.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,22 @@ void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
16901690
}
16911691
}
16921692

1693+
Optional<uint64_t>
1694+
BinaryContext::getBaseAddressForMapping(uint64_t MMapAddress,
1695+
uint64_t FileOffset) const {
1696+
// Find a segment with a matching file offset.
1697+
for (auto &KV : SegmentMapInfo) {
1698+
const SegmentInfo &SegInfo = KV.second;
1699+
if (alignDown(SegInfo.FileOffset, SegInfo.Alignment) == FileOffset) {
1700+
// Use segment's aligned memory offset to calculate the base address.
1701+
const uint64_t MemOffset = alignDown(SegInfo.Address, SegInfo.Alignment);
1702+
return MMapAddress - MemOffset;
1703+
}
1704+
}
1705+
1706+
return NoneType();
1707+
}
1708+
16931709
ErrorOr<BinarySection &> BinaryContext::getSectionForAddress(uint64_t Address) {
16941710
auto SI = AddressToSection.upper_bound(Address);
16951711
if (SI != AddressToSection.begin()) {

bolt/lib/Core/DebugData.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,8 @@ void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) {
820820
auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool {
821821
llvm::SHA1 Hasher;
822822
Hasher.update(AbbrevData);
823-
StringRef Key = Hasher.final();
823+
std::array<uint8_t, 20> Hash = Hasher.final();
824+
StringRef Key((const char *)Hash.data(), Hash.size());
824825
auto Iter = AbbrevDataCache.find(Key);
825826
if (Iter != AbbrevDataCache.end()) {
826827
UnitsAbbrevData[&Unit] = Iter->second.get();

bolt/lib/Core/Relocation.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,17 @@ bool skipRelocationProcessX86(uint64_t Type, uint64_t Contents) {
168168
bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
169169
auto IsMov = [](uint64_t Contents) -> bool {
170170
// The bits 28-23 are 0b100101
171-
if ((Contents & 0x1f800000) == 0x12800000)
172-
return true;
173-
return false;
171+
return (Contents & 0x1f800000) == 0x12800000;
174172
};
175173

176174
auto IsB = [](uint64_t Contents) -> bool {
177175
// The bits 31-26 are 0b000101
178-
if ((Contents & 0xfc000000) == 0x14000000)
179-
return true;
180-
return false;
176+
return (Contents & 0xfc000000) == 0x14000000;
177+
};
178+
179+
auto IsAdr = [](uint64_t Contents) -> bool {
180+
// The bits 31-24 are 0b0xx10000
181+
return (Contents & 0x9f000000) == 0x10000000;
181182
};
182183

183184
auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; };
@@ -205,7 +206,7 @@ bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
205206
}
206207
}
207208

208-
// The ld might replace load/store instruction with jump and
209+
// The linker might replace load/store instruction with jump and
209210
// veneer due to errata 843419
210211
// https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d
211212
// Thus load/store relocations for these instructions must be ignored
@@ -223,6 +224,18 @@ bool skipRelocationProcessAArch64(uint64_t Type, uint64_t Contents) {
223224
}
224225
}
225226

227+
// The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP
228+
switch (Type) {
229+
default:
230+
break;
231+
case ELF::R_AARCH64_ADR_PREL_PG_HI21:
232+
case ELF::R_AARCH64_ADD_ABS_LO12_NC:
233+
case ELF::R_AARCH64_ADR_GOT_PAGE:
234+
case ELF::R_AARCH64_LD64_GOT_LO12_NC:
235+
if (IsAdr(Contents))
236+
return true;
237+
}
238+
226239
return false;
227240
}
228241

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ uint64_t ShortenInstructions::shortenInstructions(BinaryFunction &Function) {
10151015
continue;
10161016

10171017
if (opts::Verbosity > 2) {
1018+
BC.scopeLock();
10181019
outs() << "BOLT-INFO: shortening:\nBOLT-INFO: ";
10191020
BC.printInstruction(outs(), OriginalInst, 0, &Function);
10201021
outs() << "BOLT-INFO: to:";

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,37 +1296,55 @@ std::error_code DataAggregator::printLBRHeatMap() {
12961296
uint64_t NumTotalSamples = 0;
12971297

12981298
while (hasData()) {
1299-
ErrorOr<PerfBranchSample> SampleRes = parseBranchSample();
1300-
if (std::error_code EC = SampleRes.getError()) {
1301-
if (EC == errc::no_such_process)
1302-
continue;
1303-
return EC;
1304-
}
1305-
1306-
PerfBranchSample &Sample = SampleRes.get();
1299+
if (opts::BasicAggregation) {
1300+
ErrorOr<PerfBasicSample> SampleRes = parseBasicSample();
1301+
if (std::error_code EC = SampleRes.getError()) {
1302+
if (EC == errc::no_such_process)
1303+
continue;
1304+
return EC;
1305+
}
1306+
PerfBasicSample &Sample = SampleRes.get();
1307+
HM.registerAddress(Sample.PC);
1308+
NumTotalSamples++;
1309+
} else {
1310+
ErrorOr<PerfBranchSample> SampleRes = parseBranchSample();
1311+
if (std::error_code EC = SampleRes.getError()) {
1312+
if (EC == errc::no_such_process)
1313+
continue;
1314+
return EC;
1315+
}
13071316

1308-
// LBRs are stored in reverse execution order. NextLBR refers to the next
1309-
// executed branch record.
1310-
const LBREntry *NextLBR = nullptr;
1311-
for (const LBREntry &LBR : Sample.LBR) {
1312-
if (NextLBR) {
1313-
// Record fall-through trace.
1314-
const uint64_t TraceFrom = LBR.To;
1315-
const uint64_t TraceTo = NextLBR->From;
1316-
++FallthroughLBRs[Trace(TraceFrom, TraceTo)].InternCount;
1317+
PerfBranchSample &Sample = SampleRes.get();
1318+
1319+
// LBRs are stored in reverse execution order. NextLBR refers to the next
1320+
// executed branch record.
1321+
const LBREntry *NextLBR = nullptr;
1322+
for (const LBREntry &LBR : Sample.LBR) {
1323+
if (NextLBR) {
1324+
// Record fall-through trace.
1325+
const uint64_t TraceFrom = LBR.To;
1326+
const uint64_t TraceTo = NextLBR->From;
1327+
++FallthroughLBRs[Trace(TraceFrom, TraceTo)].InternCount;
1328+
}
1329+
NextLBR = &LBR;
13171330
}
1318-
NextLBR = &LBR;
1319-
}
1320-
if (!Sample.LBR.empty()) {
1321-
HM.registerAddress(Sample.LBR.front().To);
1322-
HM.registerAddress(Sample.LBR.back().From);
1331+
if (!Sample.LBR.empty()) {
1332+
HM.registerAddress(Sample.LBR.front().To);
1333+
HM.registerAddress(Sample.LBR.back().From);
1334+
}
1335+
NumTotalSamples += Sample.LBR.size();
13231336
}
1324-
NumTotalSamples += Sample.LBR.size();
13251337
}
13261338

13271339
if (!NumTotalSamples) {
1328-
errs() << "HEATMAP-ERROR: no LBR traces detected in profile. "
1329-
"Cannot build heatmap.\n";
1340+
if (!opts::BasicAggregation) {
1341+
errs() << "HEATMAP-ERROR: no LBR traces detected in profile. "
1342+
"Cannot build heatmap. Use -nl for building heatmap from "
1343+
"basic events.\n";
1344+
} else {
1345+
errs() << "HEATMAP-ERROR: no samples detected in profile. "
1346+
"Cannot build heatmap.";
1347+
}
13301348
exit(1);
13311349
}
13321350

@@ -1925,7 +1943,7 @@ DataAggregator::parseMMapEvent() {
19251943
}
19261944

19271945
const StringRef BaseAddressStr = Line.split('[').second.split('(').first;
1928-
if (BaseAddressStr.getAsInteger(0, ParsedInfo.BaseAddress)) {
1946+
if (BaseAddressStr.getAsInteger(0, ParsedInfo.MMapAddress)) {
19291947
reportError("expected base address");
19301948
Diag << "Found: " << BaseAddressStr << "in '" << Line << "'\n";
19311949
return make_error_code(llvm::errc::io_error);
@@ -1985,7 +2003,7 @@ std::error_code DataAggregator::parseMMapEvents() {
19852003
dbgs() << "FileName -> mmap info:\n";
19862004
for (const std::pair<const StringRef, MMapInfo> &Pair : GlobalMMapInfo)
19872005
dbgs() << " " << Pair.first << " : " << Pair.second.PID << " [0x"
1988-
<< Twine::utohexstr(Pair.second.BaseAddress) << ", "
2006+
<< Twine::utohexstr(Pair.second.MMapAddress) << ", "
19892007
<< Twine::utohexstr(Pair.second.Size) << " @ "
19902008
<< Twine::utohexstr(Pair.second.Offset) << "]\n";
19912009
});
@@ -1999,26 +2017,42 @@ std::error_code DataAggregator::parseMMapEvents() {
19992017

20002018
auto Range = GlobalMMapInfo.equal_range(NameToUse);
20012019
for (auto I = Range.first; I != Range.second; ++I) {
2002-
const MMapInfo &MMapInfo = I->second;
2003-
if (BC->HasFixedLoadAddress && MMapInfo.BaseAddress) {
2020+
MMapInfo &MMapInfo = I->second;
2021+
if (BC->HasFixedLoadAddress && MMapInfo.MMapAddress) {
20042022
// Check that the binary mapping matches one of the segments.
20052023
bool MatchFound = false;
20062024
for (auto &KV : BC->SegmentMapInfo) {
20072025
SegmentInfo &SegInfo = KV.second;
2008-
// The mapping is page-aligned and hence the BaseAddress could be
2026+
// The mapping is page-aligned and hence the MMapAddress could be
20092027
// different from the segment start address. We cannot know the page
20102028
// size of the mapping, but we know it should not exceed the segment
20112029
// alignment value. Hence we are performing an approximate check.
2012-
if (SegInfo.Address >= MMapInfo.BaseAddress &&
2013-
SegInfo.Address - MMapInfo.BaseAddress < SegInfo.Alignment) {
2030+
if (SegInfo.Address >= MMapInfo.MMapAddress &&
2031+
SegInfo.Address - MMapInfo.MMapAddress < SegInfo.Alignment) {
20142032
MatchFound = true;
20152033
break;
20162034
}
20172035
}
20182036
if (!MatchFound) {
20192037
errs() << "PERF2BOLT-WARNING: ignoring mapping of " << NameToUse
2020-
<< " at 0x" << Twine::utohexstr(MMapInfo.BaseAddress) << '\n';
2038+
<< " at 0x" << Twine::utohexstr(MMapInfo.MMapAddress) << '\n';
2039+
continue;
2040+
}
2041+
}
2042+
2043+
// Set base address for shared objects.
2044+
if (!BC->HasFixedLoadAddress) {
2045+
Optional<uint64_t> BaseAddress =
2046+
BC->getBaseAddressForMapping(MMapInfo.MMapAddress, MMapInfo.Offset);
2047+
if (!BaseAddress) {
2048+
errs() << "PERF2BOLT-WARNING: unable to find base address of the "
2049+
"binary when memory mapped at 0x"
2050+
<< Twine::utohexstr(MMapInfo.MMapAddress)
2051+
<< " using file offset 0x" << Twine::utohexstr(MMapInfo.Offset)
2052+
<< ". Ignoring profile data for this mapping\n";
20212053
continue;
2054+
} else {
2055+
MMapInfo.BaseAddress = *BaseAddress;
20222056
}
20232057
}
20242058

@@ -2092,7 +2126,7 @@ std::error_code DataAggregator::parseTaskEvents() {
20922126
LLVM_DEBUG({
20932127
for (std::pair<const uint64_t, MMapInfo> &MMI : BinaryMMapInfo)
20942128
outs() << " " << MMI.second.PID << (MMI.second.Forked ? " (forked)" : "")
2095-
<< ": (0x" << Twine::utohexstr(MMI.second.BaseAddress) << ": 0x"
2129+
<< ": (0x" << Twine::utohexstr(MMI.second.MMapAddress) << ": 0x"
20962130
<< Twine::utohexstr(MMI.second.Size) << ")\n";
20972131
});
20982132

0 commit comments

Comments
 (0)