-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Add initial support for SPE brstack format #129231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
a203f8b
[BOLT][AArch64] Introduce SPE mode in BasicAggregation
paschalis-mpeis efda3b3
clang-format fix
paschalis-mpeis 90b79b0
Addressing reviewers (1)
paschalis-mpeis 607a5df
Addressing reviewers (2)
paschalis-mpeis 4e33fb7
Add initial support for SPE brstack
kaadam 84b2634
Fix format issue
kaadam 84b35a3
Fix typo
kaadam 1c10eb2
Removing dependency of the SPE BasicAggregation
kaadam 42ac0b0
Address reviewers 2
kaadam 7de0865
Simplifies SpeBranchesWithBrstack testcase
kaadam 942700c
Added the suggested changes
kaadam 89bbc7e
Fixes typo
kaadam 7c0e538
clang format fix
kaadam 9ae52b9
Updated the test case.
kaadam 3dbf4b2
updated comments
kaadam 5196432
Address reviewers 3
kaadam cd58b83
Adjusting SpeBranchesWithBrstack testcase to #143289
kaadam 374c1b5
Address reviewers 4
kaadam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
## Check that Arm SPE mode is available on AArch64. | ||
|
||
REQUIRES: system-linux,perf,target=aarch64{{.*}} | ||
|
||
RUN: %clang %cflags %p/../../Inputs/asm_foo.s %p/../../Inputs/asm_main.c -o %t.exe | ||
|
||
RUN: perf record -e cycles -q -o %t.perf.data -- %t.exe 2> /dev/null | ||
|
||
RUN: (perf2bolt -p %t.perf.data -o %t.perf.boltdata --spe %t.exe 2> /dev/null; exit 0) | FileCheck %s --check-prefix=CHECK-SPE-LBR | ||
|
||
CHECK-SPE-LBR: PERF2BOLT: parse SPE branch events in LBR-format | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## Check that Arm SPE mode is unavailable on X86. | ||
|
||
REQUIRES: system-linux,x86_64-linux | ||
|
||
paschalis-mpeis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
RUN: %clang %cflags %p/../../Inputs/asm_foo.s %p/../../Inputs/asm_main.c -o %t.exe | ||
RUN: touch %t.empty.perf.data | ||
RUN: not perf2bolt -p %t.empty.perf.data -o %t.perf.boltdata --spe --pa %t.exe 2>&1 | FileCheck %s | ||
|
||
CHECK: perf2bolt: -spe is available only on AArch64. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,25 @@ | ||
set(LLVM_LINK_COMPONENTS | ||
DebugInfoDWARF | ||
Object | ||
${LLVM_TARGETS_TO_BUILD} | ||
) | ||
|
||
add_bolt_unittest(ProfileTests | ||
DataAggregator.cpp | ||
PerfSpeEvents.cpp | ||
|
||
DISABLE_LLVM_LINK_LLVM_DYLIB | ||
) | ||
|
||
target_link_libraries(ProfileTests | ||
PRIVATE | ||
LLVMBOLTCore | ||
LLVMBOLTProfile | ||
LLVMTargetParser | ||
LLVMTestingSupport | ||
) | ||
|
||
foreach (tgt ${BOLT_TARGETS_TO_BUILD}) | ||
string(TOUPPER "${tgt}" upper) | ||
target_compile_definitions(ProfileTests PRIVATE "${upper}_AVAILABLE") | ||
endforeach() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
//===- bolt/unittests/Profile/PerfSpeEvents.cpp ---------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifdef AARCH64_AVAILABLE | ||
|
||
#include "bolt/Core/BinaryContext.h" | ||
#include "bolt/Profile/DataAggregator.h" | ||
#include "llvm/BinaryFormat/ELF.h" | ||
#include "llvm/DebugInfo/DWARF/DWARFContext.h" | ||
#include "llvm/Support/CommandLine.h" | ||
#include "llvm/Support/TargetSelect.h" | ||
#include "gtest/gtest.h" | ||
|
||
using namespace llvm; | ||
using namespace llvm::bolt; | ||
using namespace llvm::object; | ||
using namespace llvm::ELF; | ||
|
||
namespace opts { | ||
extern cl::opt<std::string> ReadPerfEvents; | ||
extern cl::opt<bool> ArmSPE; | ||
} // namespace opts | ||
|
||
namespace llvm { | ||
namespace bolt { | ||
|
||
/// Perform checks on perf SPE branch events. | ||
struct PerfSpeEventsTestHelper : public testing::Test { | ||
void SetUp() override { | ||
initalizeLLVM(); | ||
prepareElf(); | ||
initializeBOLT(); | ||
} | ||
|
||
protected: | ||
using Trace = DataAggregator::Trace; | ||
using TakenBranchInfo = DataAggregator::TakenBranchInfo; | ||
|
||
void initalizeLLVM() { | ||
llvm::InitializeAllTargetInfos(); | ||
llvm::InitializeAllTargetMCs(); | ||
llvm::InitializeAllAsmParsers(); | ||
llvm::InitializeAllDisassemblers(); | ||
llvm::InitializeAllTargets(); | ||
llvm::InitializeAllAsmPrinters(); | ||
} | ||
|
||
void prepareElf() { | ||
memcpy(ElfBuf, "\177ELF", 4); | ||
ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf); | ||
EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; | ||
EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; | ||
EHdr->e_machine = llvm::ELF::EM_AARCH64; | ||
MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF"); | ||
ObjFile = cantFail(ObjectFile::createObjectFile(Source)); | ||
} | ||
|
||
void initializeBOLT() { | ||
Relocation::Arch = ObjFile->makeTriple().getArch(); | ||
BC = cantFail(BinaryContext::createBinaryContext( | ||
ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(), | ||
ObjFile->getFileName(), nullptr, /*IsPIC*/ false, | ||
DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); | ||
ASSERT_FALSE(!BC); | ||
} | ||
|
||
char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {}; | ||
std::unique_ptr<ObjectFile> ObjFile; | ||
std::unique_ptr<BinaryContext> BC; | ||
|
||
/// Helper function to export lists to show the mismatch. | ||
void reportBrStackEventMismatch( | ||
const std::vector<std::pair<Trace, TakenBranchInfo>> &Traces, | ||
const std::vector<std::pair<Trace, TakenBranchInfo>> &ExpectedSamples) { | ||
llvm::errs() << "Traces items: \n"; | ||
for (const auto &[Trace, BI] : Traces) | ||
llvm::errs() << "{" << Trace.Branch << ", " << Trace.From << "," | ||
<< Trace.To << ", " << BI.TakenCount << ", " | ||
<< BI.MispredCount << "}" << "\n"; | ||
|
||
llvm::errs() << "Expected items: \n"; | ||
for (const auto &[Trace, BI] : ExpectedSamples) | ||
llvm::errs() << "{" << Trace.Branch << ", " << Trace.From << ", " | ||
<< Trace.To << ", " << BI.TakenCount << ", " | ||
<< BI.MispredCount << "}" << "\n"; | ||
} | ||
|
||
/// Parse and check SPE brstack as LBR. | ||
void parseAndCheckBrstackEvents( | ||
uint64_t PID, | ||
const std::vector<std::pair<Trace, TakenBranchInfo>> &ExpectedSamples) { | ||
DataAggregator DA("<pseudo input>"); | ||
DA.ParsingBuf = opts::ReadPerfEvents; | ||
DA.BC = BC.get(); | ||
DataAggregator::MMapInfo MMap; | ||
DA.BinaryMMapInfo.insert(std::make_pair(PID, MMap)); | ||
|
||
DA.parseBranchEvents(); | ||
|
||
EXPECT_EQ(DA.Traces.size(), ExpectedSamples.size()); | ||
if (DA.Traces.size() != ExpectedSamples.size()) | ||
reportBrStackEventMismatch(DA.Traces, ExpectedSamples); | ||
|
||
const auto TracesBegin = DA.Traces.begin(); | ||
const auto TracesEnd = DA.Traces.end(); | ||
for (const auto &BI : ExpectedSamples) { | ||
auto it = find_if(TracesBegin, TracesEnd, | ||
[&BI](const auto &Tr) { return Tr.first == BI.first; }); | ||
|
||
EXPECT_NE(it, TracesEnd); | ||
EXPECT_EQ(it->second.MispredCount, BI.second.MispredCount); | ||
EXPECT_EQ(it->second.TakenCount, BI.second.TakenCount); | ||
} | ||
} | ||
}; | ||
|
||
} // namespace bolt | ||
} // namespace llvm | ||
|
||
TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstack) { | ||
// Check perf input with SPE branch events as brstack format. | ||
// Example collection command: | ||
// ``` | ||
// perf record -e 'arm_spe_0/branch_filter=1/u' -- BINARY | ||
// ``` | ||
// How Bolt extracts the branch events: | ||
// ``` | ||
// perf script -F pid,brstack --itrace=bl | ||
// ``` | ||
|
||
opts::ArmSPE = true; | ||
opts::ReadPerfEvents = " 1234 0xa001/0xa002/PN/-/-/10/COND/-\n" | ||
" 1234 0xb001/0xb002/P/-/-/4/RET/-\n" | ||
" 1234 0xc456/0xc789/P/-/-/13/-/-\n" | ||
" 1234 0xd123/0xd456/M/-/-/7/RET/-\n" | ||
" 1234 0xe001/0xe002/P/-/-/14/RET/-\n" | ||
" 1234 0xd123/0xd456/M/-/-/7/RET/-\n" | ||
" 1234 0xf001/0xf002/MN/-/-/8/COND/-\n" | ||
" 1234 0xc456/0xc789/M/-/-/13/-/-\n"; | ||
|
||
// ExpectedSamples contains the aggregated information about | ||
// a branch {{Branch From, To}, {TakenCount, MispredCount}}. | ||
// Consider this example trace: {{0xd123, 0xd456, Trace::BR_ONLY}, | ||
// {2,2}}. This entry has a TakenCount = 2, as we have two samples for | ||
// (0xd123, 0xd456) in our input. It also has MispredsCount = 2, | ||
// as 'M' misprediction flag appears in both cases. BR_ONLY means | ||
// the trace only contains branch data. | ||
std::vector<std::pair<Trace, TakenBranchInfo>> ExpectedSamples = { | ||
{{0xa001, 0xa002, Trace::BR_ONLY}, {1, 0}}, | ||
{{0xb001, 0xb002, Trace::BR_ONLY}, {1, 0}}, | ||
{{0xc456, 0xc789, Trace::BR_ONLY}, {2, 1}}, | ||
{{0xd123, 0xd456, Trace::BR_ONLY}, {2, 2}}, | ||
{{0xe001, 0xe002, Trace::BR_ONLY}, {1, 0}}, | ||
{{0xf001, 0xf002, Trace::BR_ONLY}, {1, 1}}}; | ||
|
||
parseAndCheckBrstackEvents(1234, ExpectedSamples); | ||
} | ||
|
||
#endif |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.