From de6ece982679c05c2e469f7f4bda37065d23d2f9 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 6 Jan 2024 22:30:25 -0800 Subject: [PATCH 1/2] [llvm-exegesis] Make duplicate snippet repetitor produce whole snippets Currently, the duplicate snippet repetitor will truncate snippets that do not exactly divide the minimum number of instructions. This patch corrects that behavior by making the duplicate snippet repetitor duplicate the snippet in its entirety until the minimum number of instructions has been reached. --- .../llvm-exegesis/lib/SnippetRepetitor.cpp | 6 +++++- .../llvm-exegesis/X86/SnippetRepetitorTest.cpp | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp index cc5a045a8be5d..5861d56c61cf6 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp @@ -31,7 +31,11 @@ class DuplicateSnippetRepetitor : public SnippetRepetitor { if (!Instructions.empty()) { // Add the whole snippet at least once. Entry.addInstructions(Instructions); - for (unsigned I = Instructions.size(); I < MinInstructions; ++I) { + unsigned FullInstructionCount = MinInstructions; + if (FullInstructionCount % Instructions.size() != 0) + FullInstructionCount += + Instructions.size() - (MinInstructions % Instructions.size()); + for (unsigned I = Instructions.size(); I < FullInstructionCount; ++I) { Entry.addInstruction(Instructions[I % Instructions.size()]); } } diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp index d2382ec0cddc4..25e8836087c15 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp @@ -38,9 +38,11 @@ class X86SnippetRepetitorTest : public X86TestBase { MF = &createVoidVoidPtrMachineFunction("TestFn", Mod.get(), MMI.get()); } - void TestCommon(Benchmark::RepetitionModeE RepetitionMode) { + void TestCommon(Benchmark::RepetitionModeE RepetitionMode, + unsigned SnippetInstructions = 1) { const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State); - const std::vector Instructions = {MCInstBuilder(X86::NOOP)}; + const std::vector Instructions(SnippetInstructions, + MCInstBuilder(X86::NOOP)); FunctionFiller Sink(*MF, {X86::EAX}); const auto Fill = Repetitor->Repeat(Instructions, kMinInstructions, kLoopBodySize, false); @@ -74,6 +76,18 @@ TEST_F(X86SnippetRepetitorTest, Duplicate) { HasOpcode(X86::NOOP), HasOpcode(X86::RET64))); } +TEST_F(X86SnippetRepetitorTest, DuplicateSnippetInstructionCount) { + TestCommon(Benchmark::Duplicate, 2); + // Duplicating a snippet of two instructions with the minimum number of + // instructions set to three duplicates the snippet twice for a total of + // four instructions. + ASSERT_EQ(MF->getNumBlockIDs(), 1u); + EXPECT_THAT(MF->getBlockNumbered(0)->instrs(), + ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP), + HasOpcode(X86::NOOP), HasOpcode(X86::NOOP), + HasOpcode(X86::RET64))); +} + TEST_F(X86SnippetRepetitorTest, Loop) { TestCommon(Benchmark::Loop); // Duplicating creates an entry block, a loop body and a ret block. From 90b0e9079d59a579596c40f8e1756a07fda21054 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Fri, 19 Jan 2024 01:16:34 -0800 Subject: [PATCH 2/2] Address reviewer feedback --- llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp index 5861d56c61cf6..a853364b6e3e8 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp @@ -29,14 +29,10 @@ class DuplicateSnippetRepetitor : public SnippetRepetitor { CleanupMemory](FunctionFiller &Filler) { auto Entry = Filler.getEntry(); if (!Instructions.empty()) { - // Add the whole snippet at least once. - Entry.addInstructions(Instructions); - unsigned FullInstructionCount = MinInstructions; - if (FullInstructionCount % Instructions.size() != 0) - FullInstructionCount += - Instructions.size() - (MinInstructions % Instructions.size()); - for (unsigned I = Instructions.size(); I < FullInstructionCount; ++I) { - Entry.addInstruction(Instructions[I % Instructions.size()]); + const unsigned NumRepetitions = + divideCeil(MinInstructions, Instructions.size()); + for (unsigned I = 0; I < NumRepetitions; ++I) { + Entry.addInstructions(Instructions); } } Entry.addReturn(State.getExegesisTarget(), CleanupMemory);