[llvm] r342117 - [llvm-exegesis][NFC] Split BenchmarkRunner class
Clement Courbet via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 13 00:40:53 PDT 2018
Author: courbet
Date: Thu Sep 13 00:40:53 2018
New Revision: 342117
URL: http://llvm.org/viewvc/llvm-project?rev=342117&view=rev
Log:
[llvm-exegesis][NFC] Split BenchmarkRunner class
Summary:
The snippet-generation part goes to the SnippetGenerator class.
This will allow benchmarking arbitrary code (see PR38437).
Reviewers: gchatelet
Subscribers: mgorny, tschuett, llvm-commits
Differential Revision: https://reviews.llvm.org/D51979
Added:
llvm/trunk/tools/llvm-exegesis/lib/BenchmarkCode.h
llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.cpp
llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.h
Modified:
llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt
llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
llvm/trunk/tools/llvm-exegesis/lib/Latency.h
llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
llvm/trunk/tools/llvm-exegesis/lib/Target.h
llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
llvm/trunk/tools/llvm-exegesis/lib/Uops.h
llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp
llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
Added: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkCode.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkCode.h?rev=342117&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkCode.h (added)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkCode.h Thu Sep 13 00:40:53 2018
@@ -0,0 +1,38 @@
+//===-- BenchmarkCode.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKCODE_H
+#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKCODE_H
+
+#include "llvm/MC/MCInst.h"
+#include <string>
+#include <vector>
+
+namespace exegesis {
+
+// A collection of instructions that are to be assembled, executed and measured.
+struct BenchmarkCode {
+ // The sequence of instructions that are to be repeated.
+ std::vector<llvm::MCInst> Instructions;
+
+ // Before the code is executed some instructions are added to setup the
+ // registers initial values.
+ std::vector<unsigned> RegsToDef;
+
+ // We also need to provide the registers that are live on entry for the
+ // assembler to generate proper prologue/epilogue.
+ std::vector<unsigned> LiveIns;
+
+ // Informations about how this configuration was built.
+ std::string Info;
+};
+
+} // namespace exegesis
+
+#endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKCODE_H
Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp Thu Sep 13 00:40:53 2018
@@ -17,7 +17,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
@@ -28,37 +27,10 @@ BenchmarkFailure::BenchmarkFailure(const
BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
InstructionBenchmark::ModeE Mode)
- : State(State), RATC(State.getRegInfo(),
- getFunctionReservedRegs(State.getTargetMachine())),
- Mode(Mode), Scratch(llvm::make_unique<ScratchSpace>()) {}
+ : State(State), Mode(Mode), Scratch(llvm::make_unique<ScratchSpace>()) {}
BenchmarkRunner::~BenchmarkRunner() = default;
-llvm::Expected<std::vector<InstructionBenchmark>>
-BenchmarkRunner::run(unsigned Opcode, unsigned NumRepetitions) {
- const llvm::MCInstrDesc &InstrDesc = State.getInstrInfo().get(Opcode);
- // Ignore instructions that we cannot run.
- if (InstrDesc.isPseudo())
- return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
- if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
- return llvm::make_error<BenchmarkFailure>(
- "Unsupported opcode: isBranch/isIndirectBranch");
- if (InstrDesc.isCall() || InstrDesc.isReturn())
- return llvm::make_error<BenchmarkFailure>(
- "Unsupported opcode: isCall/isReturn");
-
- llvm::Expected<std::vector<BenchmarkCode>> ConfigurationOrError =
- generateConfigurations(Opcode);
-
- if (llvm::Error E = ConfigurationOrError.takeError())
- return std::move(E);
-
- std::vector<InstructionBenchmark> InstrBenchmarks;
- for (const BenchmarkCode &Conf : ConfigurationOrError.get())
- InstrBenchmarks.push_back(runConfiguration(Conf, NumRepetitions));
- return InstrBenchmarks;
-}
-
// Repeat the snippet until there are at least NumInstructions in the resulting
// code.
static std::vector<llvm::MCInst>
@@ -122,74 +94,6 @@ BenchmarkRunner::runConfiguration(const
return InstrBenchmark;
}
-llvm::Expected<std::vector<BenchmarkCode>>
-BenchmarkRunner::generateConfigurations(unsigned Opcode) const {
- if (auto E = generateCodeTemplate(Opcode)) {
- CodeTemplate &CT = E.get();
- std::vector<BenchmarkCode> Output;
- // TODO: Generate as many BenchmarkCode as needed.
- {
- BenchmarkCode BC;
- BC.Info = CT.Info;
- for (InstructionBuilder &IB : CT.Instructions) {
- IB.randomizeUnsetVariables(
- CT.ScratchSpacePointerInReg
- ? RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits()
- : RATC.emptyRegisters());
- BC.Instructions.push_back(IB.build());
- }
- if (CT.ScratchSpacePointerInReg)
- BC.LiveIns.push_back(CT.ScratchSpacePointerInReg);
- BC.RegsToDef = computeRegsToDef(CT.Instructions);
- Output.push_back(std::move(BC));
- }
- return Output;
- } else
- return E.takeError();
-}
-
-std::vector<unsigned> BenchmarkRunner::computeRegsToDef(
- const std::vector<InstructionBuilder> &Instructions) const {
- // Collect all register uses and create an assignment for each of them.
- // Ignore memory operands which are handled separately.
- // Loop invariant: DefinedRegs[i] is true iif it has been set at least once
- // before the current instruction.
- llvm::BitVector DefinedRegs = RATC.emptyRegisters();
- std::vector<unsigned> RegsToDef;
- for (const InstructionBuilder &IB : Instructions) {
- // Returns the register that this Operand sets or uses, or 0 if this is not
- // a register.
- const auto GetOpReg = [&IB](const Operand &Op) -> unsigned {
- if (Op.IsMem)
- return 0;
- if (Op.ImplicitReg)
- return *Op.ImplicitReg;
- if (Op.IsExplicit && IB.getValueFor(Op).isReg())
- return IB.getValueFor(Op).getReg();
- return 0;
- };
- // Collect used registers that have never been def'ed.
- for (const Operand &Op : IB.Instr.Operands) {
- if (!Op.IsDef) {
- const unsigned Reg = GetOpReg(Op);
- if (Reg > 0 && !DefinedRegs.test(Reg)) {
- RegsToDef.push_back(Reg);
- DefinedRegs.set(Reg);
- }
- }
- }
- // Mark defs as having been def'ed.
- for (const Operand &Op : IB.Instr.Operands) {
- if (Op.IsDef) {
- const unsigned Reg = GetOpReg(Op);
- if (Reg > 0)
- DefinedRegs.set(Reg);
- }
- }
- }
- return RegsToDef;
-}
-
llvm::Expected<std::string>
BenchmarkRunner::writeObjectFile(const BenchmarkCode &BC,
llvm::ArrayRef<llvm::MCInst> Code) const {
@@ -204,32 +108,4 @@ BenchmarkRunner::writeObjectFile(const B
return ResultPath.str();
}
-llvm::Expected<CodeTemplate> BenchmarkRunner::generateSelfAliasingCodeTemplate(
- const Instruction &Instr) const {
- const AliasingConfigurations SelfAliasing(Instr, Instr);
- if (SelfAliasing.empty()) {
- return llvm::make_error<BenchmarkFailure>("empty self aliasing");
- }
- CodeTemplate CT;
- InstructionBuilder IB(Instr);
- if (SelfAliasing.hasImplicitAliasing()) {
- CT.Info = "implicit Self cycles, picking random values.";
- } else {
- CT.Info = "explicit self cycles, selecting one aliasing Conf.";
- // This is a self aliasing instruction so defs and uses are from the same
- // instance, hence twice IB in the following call.
- setRandomAliasing(SelfAliasing, IB, IB);
- }
- CT.Instructions.push_back(std::move(IB));
- return std::move(CT);
-}
-
-llvm::Expected<CodeTemplate>
-BenchmarkRunner::generateUnconstrainedCodeTemplate(const Instruction &Instr,
- llvm::StringRef Msg) const {
- CodeTemplate CT;
- CT.Info = llvm::formatv("{0}, repeating an unconstrained assignment", Msg);
- CT.Instructions.emplace_back(Instr);
- return std::move(CT);
-}
} // namespace exegesis
Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h Thu Sep 13 00:40:53 2018
@@ -17,10 +17,10 @@
#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H
#include "Assembler.h"
+#include "BenchmarkCode.h"
#include "BenchmarkResult.h"
#include "LlvmState.h"
#include "MCInstrDescView.h"
-#include "RegisterAliasing.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Error.h"
#include <cstdlib>
@@ -36,23 +36,6 @@ public:
BenchmarkFailure(const llvm::Twine &S);
};
-// A collection of instructions that are to be assembled, executed and measured.
-struct BenchmarkCode {
- // The sequence of instructions that are to be repeated.
- std::vector<llvm::MCInst> Instructions;
-
- // Before the code is executed some instructions are added to setup the
- // registers initial values.
- std::vector<unsigned> RegsToDef;
-
- // We also need to provide the registers that are live on entry for the
- // assembler to generate proper prologue/epilogue.
- std::vector<unsigned> LiveIns;
-
- // Informations about how this configuration was built.
- std::string Info;
-};
-
// Common code for all benchmark modes.
class BenchmarkRunner {
public:
@@ -61,12 +44,8 @@ public:
virtual ~BenchmarkRunner();
- llvm::Expected<std::vector<InstructionBenchmark>>
- run(unsigned Opcode, unsigned NumRepetitions);
-
- // Given a snippet, computes which registers the setup code needs to define.
- std::vector<unsigned>
- computeRegsToDef(const std::vector<InstructionBuilder> &Snippet) const;
+ InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration,
+ unsigned NumRepetitions) const;
// Scratch space to run instructions that touch memory.
struct ScratchSpace {
@@ -87,33 +66,12 @@ public:
protected:
const LLVMState &State;
- const RegisterAliasingTrackerCache RATC;
-
- // Generates a single code template that has a self-dependency.
- llvm::Expected<CodeTemplate>
- generateSelfAliasingCodeTemplate(const Instruction &Instr) const;
- // Generates a single code template without assignment constraints.
- llvm::Expected<CodeTemplate>
- generateUnconstrainedCodeTemplate(const Instruction &Instr,
- llvm::StringRef Msg) const;
private:
- // API to be implemented by subclasses.
- virtual llvm::Expected<CodeTemplate>
- generateCodeTemplate(unsigned Opcode) const = 0;
-
virtual std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
const unsigned NumRepetitions) const = 0;
- // Internal helpers.
- InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration,
- unsigned NumRepetitions) const;
-
- // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
- llvm::Expected<std::vector<BenchmarkCode>>
- generateConfigurations(unsigned Opcode) const;
-
llvm::Expected<std::string>
writeObjectFile(const BenchmarkCode &Configuration,
llvm::ArrayRef<llvm::MCInst> Code) const;
Modified: llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt Thu Sep 13 00:40:53 2018
@@ -19,6 +19,7 @@ add_library(LLVMExegesis
MCInstrDescView.cpp
PerfHelper.cpp
RegisterAliasing.cpp
+ SnippetGenerator.cpp
Target.cpp
Uops.cpp
)
Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp Thu Sep 13 00:40:53 2018
@@ -29,9 +29,9 @@ static bool hasMemoryOperand(const llvm:
return OpInfo.OperandType == llvm::MCOI::OPERAND_MEMORY;
}
-LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
+LatencySnippetGenerator::~LatencySnippetGenerator() = default;
-llvm::Error LatencyBenchmarkRunner::isInfeasible(
+llvm::Error LatencySnippetGenerator::isInfeasible(
const llvm::MCInstrDesc &MCInstrDesc) const {
if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
return llvm::make_error<BenchmarkFailure>(
@@ -43,7 +43,7 @@ llvm::Error LatencyBenchmarkRunner::isIn
}
llvm::Expected<CodeTemplate>
-LatencyBenchmarkRunner::generateTwoInstructionPrototype(
+LatencySnippetGenerator::generateTwoInstructionPrototype(
const Instruction &Instr) const {
std::vector<unsigned> Opcodes;
Opcodes.resize(State.getInstrInfo().getNumOpcodes());
@@ -80,7 +80,7 @@ LatencyBenchmarkRunner::generateTwoInstr
}
llvm::Expected<CodeTemplate>
-LatencyBenchmarkRunner::generateCodeTemplate(unsigned Opcode) const {
+LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
const auto &InstrDesc = State.getInstrInfo().get(Opcode);
if (auto E = isInfeasible(InstrDesc))
return std::move(E);
@@ -105,6 +105,8 @@ const char *LatencyBenchmarkRunner::getC
return CounterName;
}
+LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
+
std::vector<BenchmarkMeasure>
LatencyBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
ScratchSpace &Scratch,
Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.h?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.h Thu Sep 13 00:40:53 2018
@@ -17,14 +17,14 @@
#include "BenchmarkRunner.h"
#include "MCInstrDescView.h"
+#include "SnippetGenerator.h"
namespace exegesis {
-class LatencyBenchmarkRunner : public BenchmarkRunner {
+class LatencySnippetGenerator : public SnippetGenerator {
public:
- LatencyBenchmarkRunner(const LLVMState &State)
- : BenchmarkRunner(State, InstructionBenchmark::Latency) {}
- ~LatencyBenchmarkRunner() override;
+ LatencySnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
+ ~LatencySnippetGenerator() override;
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override;
@@ -34,14 +34,21 @@ private:
llvm::Expected<CodeTemplate>
generateTwoInstructionPrototype(const Instruction &Instr) const;
+};
+class LatencyBenchmarkRunner : public BenchmarkRunner {
+public:
+ LatencyBenchmarkRunner(const LLVMState &State)
+ : BenchmarkRunner(State, InstructionBenchmark::Latency) {}
+ ~LatencyBenchmarkRunner() override;
+
+private:
std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
const unsigned NumRepetitions) const override;
virtual const char *getCounterName() const;
};
-
} // namespace exegesis
#endif // LLVM_TOOLS_LLVM_EXEGESIS_LATENCY_H
Added: llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.cpp?rev=342117&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.cpp (added)
+++ llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.cpp Thu Sep 13 00:40:53 2018
@@ -0,0 +1,130 @@
+//===-- SnippetGenerator.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <array>
+#include <string>
+
+#include "Assembler.h"
+#include "MCInstrDescView.h"
+#include "SnippetGenerator.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Program.h"
+
+namespace exegesis {
+
+SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S)
+ : llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
+
+SnippetGenerator::SnippetGenerator(const LLVMState &State)
+ : State(State), RATC(State.getRegInfo(),
+ getFunctionReservedRegs(State.getTargetMachine())) {}
+
+SnippetGenerator::~SnippetGenerator() = default;
+
+llvm::Expected<std::vector<BenchmarkCode>>
+SnippetGenerator::generateConfigurations(unsigned Opcode) const {
+ if (auto E = generateCodeTemplate(Opcode)) {
+ CodeTemplate &CT = E.get();
+ std::vector<BenchmarkCode> Output;
+ // TODO: Generate as many BenchmarkCode as needed.
+ {
+ BenchmarkCode BC;
+ BC.Info = CT.Info;
+ for (InstructionBuilder &IB : CT.Instructions) {
+ IB.randomizeUnsetVariables(
+ CT.ScratchSpacePointerInReg
+ ? RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits()
+ : RATC.emptyRegisters());
+ BC.Instructions.push_back(IB.build());
+ }
+ if (CT.ScratchSpacePointerInReg)
+ BC.LiveIns.push_back(CT.ScratchSpacePointerInReg);
+ BC.RegsToDef = computeRegsToDef(CT.Instructions);
+ Output.push_back(std::move(BC));
+ }
+ return Output;
+ } else
+ return E.takeError();
+}
+
+std::vector<unsigned> SnippetGenerator::computeRegsToDef(
+ const std::vector<InstructionBuilder> &Instructions) const {
+ // Collect all register uses and create an assignment for each of them.
+ // Ignore memory operands which are handled separately.
+ // Loop invariant: DefinedRegs[i] is true iif it has been set at least once
+ // before the current instruction.
+ llvm::BitVector DefinedRegs = RATC.emptyRegisters();
+ std::vector<unsigned> RegsToDef;
+ for (const InstructionBuilder &IB : Instructions) {
+ // Returns the register that this Operand sets or uses, or 0 if this is not
+ // a register.
+ const auto GetOpReg = [&IB](const Operand &Op) -> unsigned {
+ if (Op.IsMem)
+ return 0;
+ if (Op.ImplicitReg)
+ return *Op.ImplicitReg;
+ if (Op.IsExplicit && IB.getValueFor(Op).isReg())
+ return IB.getValueFor(Op).getReg();
+ return 0;
+ };
+ // Collect used registers that have never been def'ed.
+ for (const Operand &Op : IB.Instr.Operands) {
+ if (!Op.IsDef) {
+ const unsigned Reg = GetOpReg(Op);
+ if (Reg > 0 && !DefinedRegs.test(Reg)) {
+ RegsToDef.push_back(Reg);
+ DefinedRegs.set(Reg);
+ }
+ }
+ }
+ // Mark defs as having been def'ed.
+ for (const Operand &Op : IB.Instr.Operands) {
+ if (Op.IsDef) {
+ const unsigned Reg = GetOpReg(Op);
+ if (Reg > 0)
+ DefinedRegs.set(Reg);
+ }
+ }
+ }
+ return RegsToDef;
+}
+
+llvm::Expected<CodeTemplate> SnippetGenerator::generateSelfAliasingCodeTemplate(
+ const Instruction &Instr) const {
+ const AliasingConfigurations SelfAliasing(Instr, Instr);
+ if (SelfAliasing.empty()) {
+ return llvm::make_error<SnippetGeneratorFailure>("empty self aliasing");
+ }
+ CodeTemplate CT;
+ InstructionBuilder IB(Instr);
+ if (SelfAliasing.hasImplicitAliasing()) {
+ CT.Info = "implicit Self cycles, picking random values.";
+ } else {
+ CT.Info = "explicit self cycles, selecting one aliasing Conf.";
+ // This is a self aliasing instruction so defs and uses are from the same
+ // instance, hence twice IB in the following call.
+ setRandomAliasing(SelfAliasing, IB, IB);
+ }
+ CT.Instructions.push_back(std::move(IB));
+ return std::move(CT);
+}
+
+llvm::Expected<CodeTemplate>
+SnippetGenerator::generateUnconstrainedCodeTemplate(const Instruction &Instr,
+ llvm::StringRef Msg) const {
+ CodeTemplate CT;
+ CT.Info = llvm::formatv("{0}, repeating an unconstrained assignment", Msg);
+ CT.Instructions.emplace_back(Instr);
+ return std::move(CT);
+}
+} // namespace exegesis
Added: llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.h?rev=342117&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.h (added)
+++ llvm/trunk/tools/llvm-exegesis/lib/SnippetGenerator.h Thu Sep 13 00:40:53 2018
@@ -0,0 +1,74 @@
+//===-- SnippetGenerator.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines the abstract SnippetGenerator class for generating code that allows
+/// measuring a certain property of instructions (e.g. latency).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H
+#define LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H
+
+#include "Assembler.h"
+#include "BenchmarkCode.h"
+#include "LlvmState.h"
+#include "MCInstrDescView.h"
+#include "RegisterAliasing.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/Error.h"
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+namespace exegesis {
+
+// A class representing failures that happened during Benchmark, they are used
+// to report informations to the user.
+class SnippetGeneratorFailure : public llvm::StringError {
+public:
+ SnippetGeneratorFailure(const llvm::Twine &S);
+};
+
+// Common code for all benchmark modes.
+class SnippetGenerator {
+public:
+ explicit SnippetGenerator(const LLVMState &State);
+
+ virtual ~SnippetGenerator();
+
+ // Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
+ llvm::Expected<std::vector<BenchmarkCode>>
+ generateConfigurations(unsigned Opcode) const;
+
+ // Given a snippet, computes which registers the setup code needs to define.
+ std::vector<unsigned>
+ computeRegsToDef(const std::vector<InstructionBuilder> &Snippet) const;
+
+protected:
+ const LLVMState &State;
+ const RegisterAliasingTrackerCache RATC;
+
+ // Generates a single code template that has a self-dependency.
+ llvm::Expected<CodeTemplate>
+ generateSelfAliasingCodeTemplate(const Instruction &Instr) const;
+ // Generates a single code template without assignment constraints.
+ llvm::Expected<CodeTemplate>
+ generateUnconstrainedCodeTemplate(const Instruction &Instr,
+ llvm::StringRef Msg) const;
+
+private:
+ // API to be implemented by subclasses.
+ virtual llvm::Expected<CodeTemplate>
+ generateCodeTemplate(unsigned Opcode) const = 0;
+};
+
+} // namespace exegesis
+
+#endif // LLVM_TOOLS_LLVM_EXEGESIS_SNIPPETGENERATOR_H
Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.cpp Thu Sep 13 00:40:53 2018
@@ -36,6 +36,20 @@ void ExegesisTarget::registerTarget(Exeg
FirstTarget = Target;
}
+std::unique_ptr<SnippetGenerator>
+ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode,
+ const LLVMState &State) const {
+ switch (Mode) {
+ case InstructionBenchmark::Unknown:
+ return nullptr;
+ case InstructionBenchmark::Latency:
+ return createLatencySnippetGenerator(State);
+ case InstructionBenchmark::Uops:
+ return createUopsSnippetGenerator(State);
+ }
+ return nullptr;
+}
+
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
const LLVMState &State) const {
@@ -50,6 +64,16 @@ ExegesisTarget::createBenchmarkRunner(In
return nullptr;
}
+std::unique_ptr<SnippetGenerator>
+ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const {
+ return llvm::make_unique<LatencySnippetGenerator>(State);
+}
+
+std::unique_ptr<SnippetGenerator>
+ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const {
+ return llvm::make_unique<UopsSnippetGenerator>(State);
+}
+
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const {
return llvm::make_unique<LatencyBenchmarkRunner>(State);
Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.h?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.h Thu Sep 13 00:40:53 2018
@@ -20,6 +20,7 @@
#include "BenchmarkResult.h"
#include "BenchmarkRunner.h"
#include "LlvmState.h"
+#include "SnippetGenerator.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/CallingConv.h"
@@ -61,6 +62,10 @@ public:
// matter as long as it's large enough.
virtual unsigned getMaxMemoryAccessSize() const { return 0; }
+ // Creates a snippet generator for the given mode.
+ std::unique_ptr<SnippetGenerator>
+ createSnippetGenerator(InstructionBenchmark::ModeE Mode,
+ const LLVMState &State) const;
// Creates a benchmark runner for the given mode.
std::unique_ptr<BenchmarkRunner>
createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
@@ -79,8 +84,12 @@ public:
private:
virtual bool matchesArch(llvm::Triple::ArchType Arch) const = 0;
- // Targets can implement their own Latency/Uops benchmarks runners by
+ // Targets can implement their own snippet generators/benchmarks runners by
// implementing these.
+ std::unique_ptr<SnippetGenerator> virtual createLatencySnippetGenerator(
+ const LLVMState &State) const;
+ std::unique_ptr<SnippetGenerator> virtual createUopsSnippetGenerator(
+ const LLVMState &State) const;
std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
const LLVMState &State) const;
std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp Thu Sep 13 00:40:53 2018
@@ -86,7 +86,7 @@ static bool hasUnknownOperand(const llvm
}
llvm::Error
-UopsBenchmarkRunner::isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const {
+UopsSnippetGenerator::isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const {
if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
return llvm::make_error<BenchmarkFailure>(
"Infeasible : has unknown operands");
@@ -123,8 +123,9 @@ static void remove(llvm::BitVector &a, c
}
UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
+UopsSnippetGenerator::~UopsSnippetGenerator() = default;
-void UopsBenchmarkRunner::instantiateMemoryOperands(
+void UopsSnippetGenerator::instantiateMemoryOperands(
const unsigned ScratchSpacePointerInReg,
std::vector<InstructionBuilder> &Instructions) const {
if (ScratchSpacePointerInReg == 0)
@@ -144,11 +145,12 @@ void UopsBenchmarkRunner::instantiateMem
++I;
Instructions.push_back(std::move(IB));
}
- assert(I * MemStep < ScratchSpace::kSize && "not enough scratch space");
+ assert(I * MemStep < BenchmarkRunner::ScratchSpace::kSize &&
+ "not enough scratch space");
}
llvm::Expected<CodeTemplate>
-UopsBenchmarkRunner::generateCodeTemplate(unsigned Opcode) const {
+UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
const auto &InstrDesc = State.getInstrInfo().get(Opcode);
if (auto E = isInfeasible(InstrDesc))
return std::move(E);
@@ -285,6 +287,6 @@ UopsBenchmarkRunner::runMeasurements(con
return Result;
}
-constexpr const size_t UopsBenchmarkRunner::kMinNumDifferentAddresses;
+constexpr const size_t UopsSnippetGenerator::kMinNumDifferentAddresses;
} // namespace exegesis
Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.h?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.h Thu Sep 13 00:40:53 2018
@@ -16,14 +16,14 @@
#define LLVM_TOOLS_LLVM_EXEGESIS_UOPS_H
#include "BenchmarkRunner.h"
+#include "SnippetGenerator.h"
namespace exegesis {
-class UopsBenchmarkRunner : public BenchmarkRunner {
+class UopsSnippetGenerator : public SnippetGenerator {
public:
- UopsBenchmarkRunner(const LLVMState &State)
- : BenchmarkRunner(State, InstructionBenchmark::Uops) {}
- ~UopsBenchmarkRunner() override;
+ UopsSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
+ ~UopsSnippetGenerator() override;
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override;
@@ -33,10 +33,6 @@ public:
private:
llvm::Error isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const;
- std::vector<BenchmarkMeasure>
- runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
- const unsigned NumRepetitions) const override;
-
// Instantiates memory operands within a snippet.
// To make computations as parallel as possible, we generate independant
// memory locations for instructions that load and store. If there are less
@@ -65,6 +61,20 @@ private:
std::vector<InstructionBuilder> &Snippet) const;
};
+class UopsBenchmarkRunner : public BenchmarkRunner {
+public:
+ UopsBenchmarkRunner(const LLVMState &State)
+ : BenchmarkRunner(State, InstructionBenchmark::Uops) {}
+ ~UopsBenchmarkRunner() override;
+
+ static constexpr const size_t kMinNumDifferentAddresses = 6;
+
+private:
+ std::vector<BenchmarkMeasure>
+ runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
+ const unsigned NumRepetitions) const override;
+};
+
} // namespace exegesis
#endif // LLVM_TOOLS_LLVM_EXEGESIS_UOPS_H
Modified: llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp Thu Sep 13 00:40:53 2018
@@ -22,7 +22,7 @@ namespace exegesis {
namespace {
// Common code for X86 Uops and Latency runners.
-template <typename Impl> class X86BenchmarkRunner : public Impl {
+template <typename Impl> class X86SnippetGenerator : public Impl {
using Impl::Impl;
llvm::Expected<CodeTemplate>
@@ -71,21 +71,23 @@ template <typename Impl> class X86Benchm
}
};
-class X86LatencyImpl : public LatencyBenchmarkRunner {
+class X86LatencyImpl : public LatencySnippetGenerator {
protected:
- using Base = LatencyBenchmarkRunner;
+ using Base = LatencySnippetGenerator;
using Base::Base;
llvm::Expected<CodeTemplate> handleCompareFP(const Instruction &Instr) const {
- return llvm::make_error<BenchmarkFailure>("Unsupported x87 CompareFP");
+ return llvm::make_error<SnippetGeneratorFailure>(
+ "Unsupported x87 CompareFP");
}
llvm::Expected<CodeTemplate> handleCondMovFP(const Instruction &Instr) const {
- return llvm::make_error<BenchmarkFailure>("Unsupported x87 CondMovFP");
+ return llvm::make_error<SnippetGeneratorFailure>(
+ "Unsupported x87 CondMovFP");
}
};
-class X86UopsImpl : public UopsBenchmarkRunner {
+class X86UopsImpl : public UopsSnippetGenerator {
protected:
- using Base = UopsBenchmarkRunner;
+ using Base = UopsSnippetGenerator;
using Base::Base;
// We can compute uops for any FP instruction that does not grow or shrink the
// stack (either do not touch the stack or push as much as they pop).
@@ -193,14 +195,14 @@ class ExegesisX86Target : public Exegesi
return {};
}
- std::unique_ptr<BenchmarkRunner>
- createLatencyBenchmarkRunner(const LLVMState &State) const override {
- return llvm::make_unique<X86BenchmarkRunner<X86LatencyImpl>>(State);
+ std::unique_ptr<SnippetGenerator>
+ createLatencySnippetGenerator(const LLVMState &State) const override {
+ return llvm::make_unique<X86SnippetGenerator<X86LatencyImpl>>(State);
}
- std::unique_ptr<BenchmarkRunner>
- createUopsBenchmarkRunner(const LLVMState &State) const override {
- return llvm::make_unique<X86BenchmarkRunner<X86UopsImpl>>(State);
+ std::unique_ptr<SnippetGenerator>
+ createUopsSnippetGenerator(const LLVMState &State) const override {
+ return llvm::make_unique<X86SnippetGenerator<X86UopsImpl>>(State);
}
bool matchesArch(llvm::Triple::ArchType Arch) const override {
Modified: llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp Thu Sep 13 00:40:53 2018
@@ -119,6 +119,30 @@ getBenchmarkResultContext(const LLVMStat
return Ctx;
}
+// Generates code snippets for opcode `Opcode`.
+llvm::Expected<std::vector<BenchmarkCode>>
+generateSnippets(const LLVMState &State, unsigned Opcode,
+ unsigned NumRepetitions) {
+ const std::unique_ptr<SnippetGenerator> Generator =
+ State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State);
+ if (!Generator) {
+ llvm::report_fatal_error("cannot create snippet generator");
+ }
+
+ const llvm::MCInstrDesc &InstrDesc = State.getInstrInfo().get(Opcode);
+ // Ignore instructions that we cannot run.
+ if (InstrDesc.isPseudo())
+ return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
+ if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
+ return llvm::make_error<BenchmarkFailure>(
+ "Unsupported opcode: isBranch/isIndirectBranch");
+ if (InstrDesc.isCall() || InstrDesc.isReturn())
+ return llvm::make_error<BenchmarkFailure>(
+ "Unsupported opcode: isCall/isReturn");
+
+ return Generator->generateConfigurations(Opcode);
+}
+
void benchmarkMain() {
if (exegesis::pfm::pfmInitialize())
llvm::report_fatal_error("cannot initialize libpfm");
@@ -140,6 +164,10 @@ void benchmarkMain() {
return;
}
+ // FIXME: Allow arbitrary code.
+ const std::vector<BenchmarkCode> Configurations =
+ ExitOnErr(generateSnippets(State, Opcode, NumRepetitions));
+
const std::unique_ptr<BenchmarkRunner> Runner =
State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
if (!Runner) {
@@ -154,11 +182,12 @@ void benchmarkMain() {
BenchmarkFile = "-";
const BenchmarkResultContext Context = getBenchmarkResultContext(State);
- std::vector<InstructionBenchmark> Results =
- ExitOnErr(Runner->run(Opcode, NumRepetitions));
- for (InstructionBenchmark &Result : Results)
- ExitOnErr(Result.writeYaml(Context, BenchmarkFile));
+ for (const BenchmarkCode &Conf : Configurations) {
+ InstructionBenchmark Result =
+ Runner->runConfiguration(Conf, NumRepetitions);
+ ExitOnErr(Result.writeYaml(Context, BenchmarkFile));
+ }
exegesis::pfm::pfmTerminate();
}
Modified: llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp?rev=342117&r1=342116&r2=342117&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp Thu Sep 13 00:40:53 2018
@@ -52,26 +52,27 @@ protected:
const llvm::MCRegisterInfo &MCRegisterInfo;
};
-template <typename BenchmarkRunner>
+template <typename SnippetGeneratorT>
class SnippetGeneratorTest : public X86SnippetGeneratorTest {
protected:
- SnippetGeneratorTest() : Runner(State) {}
+ SnippetGeneratorTest() : Generator(State) {}
CodeTemplate checkAndGetCodeTemplate(unsigned Opcode) {
randomGenerator().seed(0); // Initialize seed.
- auto CodeTemplateOrError = Runner.generateCodeTemplate(Opcode);
+ auto CodeTemplateOrError = Generator.generateCodeTemplate(Opcode);
EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
return std::move(CodeTemplateOrError.get());
}
- BenchmarkRunner Runner;
+ SnippetGeneratorT Generator;
};
-using LatencyBenchmarkRunnerTest = SnippetGeneratorTest<LatencyBenchmarkRunner>;
+using LatencySnippetGeneratorTest =
+ SnippetGeneratorTest<LatencySnippetGenerator>;
-using UopsBenchmarkRunnerTest = SnippetGeneratorTest<UopsBenchmarkRunner>;
+using UopsSnippetGeneratorTest = SnippetGeneratorTest<UopsSnippetGenerator>;
-TEST_F(LatencyBenchmarkRunnerTest, ImplicitSelfDependency) {
+TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependency) {
// ADC16i16 self alias because of implicit use and def.
// explicit use 0 : imm
@@ -93,7 +94,7 @@ TEST_F(LatencyBenchmarkRunnerTest, Impli
EXPECT_THAT(IB.VariableValues[0], IsInvalid()) << "Immediate is not set";
}
-TEST_F(LatencyBenchmarkRunnerTest, ExplicitSelfDependency) {
+TEST_F(LatencySnippetGeneratorTest, ExplicitSelfDependency) {
// ADD16ri self alias because Op0 and Op1 are tied together.
// explicit def 0 : reg RegClass=GR16
@@ -112,7 +113,7 @@ TEST_F(LatencyBenchmarkRunnerTest, Expli
EXPECT_THAT(IB.VariableValues[1], IsInvalid()) << "Operand 2 is not set";
}
-TEST_F(LatencyBenchmarkRunnerTest, DependencyThroughOtherOpcode) {
+TEST_F(LatencySnippetGeneratorTest, DependencyThroughOtherOpcode) {
// CMP64rr
// explicit use 0 : reg RegClass=GR64
// explicit use 1 : reg RegClass=GR64
@@ -131,7 +132,7 @@ TEST_F(LatencyBenchmarkRunnerTest, Depen
// TODO: check that the two instructions alias each other.
}
-TEST_F(LatencyBenchmarkRunnerTest, LAHF) {
+TEST_F(LatencySnippetGeneratorTest, LAHF) {
const unsigned Opcode = llvm::X86::LAHF;
const CodeTemplate CT = checkAndGetCodeTemplate(Opcode);
EXPECT_THAT(CT.Info, HasSubstr("cycle through"));
@@ -141,7 +142,7 @@ TEST_F(LatencyBenchmarkRunnerTest, LAHF)
ASSERT_THAT(IB.VariableValues, SizeIs(0));
}
-TEST_F(UopsBenchmarkRunnerTest, ParallelInstruction) {
+TEST_F(UopsSnippetGeneratorTest, ParallelInstruction) {
// BNDCL32rr is parallel no matter what.
// explicit use 0 : reg RegClass=BNDR
@@ -158,7 +159,7 @@ TEST_F(UopsBenchmarkRunnerTest, Parallel
EXPECT_THAT(IB.VariableValues[1], IsInvalid());
}
-TEST_F(UopsBenchmarkRunnerTest, SerialInstruction) {
+TEST_F(UopsSnippetGeneratorTest, SerialInstruction) {
// CDQ is serial no matter what.
// implicit def : EAX
@@ -173,7 +174,7 @@ TEST_F(UopsBenchmarkRunnerTest, SerialIn
ASSERT_THAT(IB.VariableValues, SizeIs(0));
}
-TEST_F(UopsBenchmarkRunnerTest, StaticRenaming) {
+TEST_F(UopsSnippetGeneratorTest, StaticRenaming) {
// CMOVA32rr has tied variables, we enumarate the possible values to execute
// as many in parallel as possible.
@@ -195,7 +196,7 @@ TEST_F(UopsBenchmarkRunnerTest, StaticRe
<< "Each instruction writes to a different register";
}
-TEST_F(UopsBenchmarkRunnerTest, NoTiedVariables) {
+TEST_F(UopsSnippetGeneratorTest, NoTiedVariables) {
// CMOV_GR32 has no tied variables, we make sure def and use are different
// from each other.
@@ -218,13 +219,13 @@ TEST_F(UopsBenchmarkRunnerTest, NoTiedVa
EXPECT_THAT(IB.VariableValues[3], IsInvalid());
}
-TEST_F(UopsBenchmarkRunnerTest, MemoryUse) {
+TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
// Mov32rm reads from memory.
const unsigned Opcode = llvm::X86::MOV32rm;
const CodeTemplate CT = checkAndGetCodeTemplate(Opcode);
EXPECT_THAT(CT.Info, HasSubstr("no tied variables"));
ASSERT_THAT(CT.Instructions,
- SizeIs(UopsBenchmarkRunner::kMinNumDifferentAddresses));
+ SizeIs(UopsSnippetGenerator::kMinNumDifferentAddresses));
const InstructionBuilder &IB = CT.Instructions[0];
EXPECT_THAT(IB.getOpcode(), Opcode);
ASSERT_THAT(IB.VariableValues, SizeIs(6));
@@ -234,18 +235,17 @@ TEST_F(UopsBenchmarkRunnerTest, MemoryUs
EXPECT_EQ(IB.VariableValues[5].getReg(), 0u);
}
-TEST_F(UopsBenchmarkRunnerTest, MemoryUse_Movsb) {
+TEST_F(UopsSnippetGeneratorTest, MemoryUse_Movsb) {
// MOVSB writes to scratch memory register.
const unsigned Opcode = llvm::X86::MOVSB;
- auto Error = Runner.generateCodeTemplate(Opcode).takeError();
+ auto Error = Generator.generateCodeTemplate(Opcode).takeError();
EXPECT_TRUE((bool)Error);
llvm::consumeError(std::move(Error));
}
-class FakeBenchmarkRunner : public BenchmarkRunner {
+class FakeSnippetGenerator : public SnippetGenerator {
public:
- FakeBenchmarkRunner(const LLVMState &State)
- : BenchmarkRunner(State, InstructionBenchmark::Unknown) {}
+ FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
Instruction createInstruction(unsigned Opcode) {
return Instruction(State.getInstrInfo().get(Opcode), RATC);
@@ -257,15 +257,9 @@ private:
return llvm::make_error<llvm::StringError>("not implemented",
llvm::inconvertibleErrorCode());
}
-
- std::vector<BenchmarkMeasure>
- runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
- const unsigned NumRepetitions) const override {
- return {};
- }
};
-using FakeSnippetGeneratorTest = SnippetGeneratorTest<FakeBenchmarkRunner>;
+using FakeSnippetGeneratorTest = SnippetGeneratorTest<FakeSnippetGenerator>;
TEST_F(FakeSnippetGeneratorTest, ComputeRegsToDefAdd16ri) {
// ADD16ri:
@@ -273,12 +267,12 @@ TEST_F(FakeSnippetGeneratorTest, Compute
// explicit use 1 : reg RegClass=GR16 | TIED_TO:0
// explicit use 2 : imm
// implicit def : EFLAGS
- InstructionBuilder IB(Runner.createInstruction(llvm::X86::ADD16ri));
+ InstructionBuilder IB(Generator.createInstruction(llvm::X86::ADD16ri));
IB.getValueFor(IB.Instr.Variables[0]) =
llvm::MCOperand::createReg(llvm::X86::AX);
std::vector<InstructionBuilder> Snippet;
Snippet.push_back(std::move(IB));
- const auto RegsToDef = Runner.computeRegsToDef(Snippet);
+ const auto RegsToDef = Generator.computeRegsToDef(Snippet);
EXPECT_THAT(RegsToDef, UnorderedElementsAre(llvm::X86::AX));
}
@@ -289,14 +283,14 @@ TEST_F(FakeSnippetGeneratorTest, Compute
// -> only rbx needs defining.
std::vector<InstructionBuilder> Snippet;
{
- InstructionBuilder Mov(Runner.createInstruction(llvm::X86::MOV64ri));
+ InstructionBuilder Mov(Generator.createInstruction(llvm::X86::MOV64ri));
Mov.getValueFor(Mov.Instr.Variables[0]) =
llvm::MCOperand::createReg(llvm::X86::RAX);
Mov.getValueFor(Mov.Instr.Variables[1]) = llvm::MCOperand::createImm(42);
Snippet.push_back(std::move(Mov));
}
{
- InstructionBuilder Add(Runner.createInstruction(llvm::X86::ADD64rr));
+ InstructionBuilder Add(Generator.createInstruction(llvm::X86::ADD64rr));
Add.getValueFor(Add.Instr.Variables[0]) =
llvm::MCOperand::createReg(llvm::X86::RAX);
Add.getValueFor(Add.Instr.Variables[1]) =
@@ -304,7 +298,7 @@ TEST_F(FakeSnippetGeneratorTest, Compute
Snippet.push_back(std::move(Add));
}
- const auto RegsToDef = Runner.computeRegsToDef(Snippet);
+ const auto RegsToDef = Generator.computeRegsToDef(Snippet);
EXPECT_THAT(RegsToDef, UnorderedElementsAre(llvm::X86::RBX));
}
More information about the llvm-commits
mailing list