aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-exegesis
diff options
context:
space:
mode:
authorGuillaume Chatelet <gchatelet@google.com>2018-08-03 09:29:38 +0000
committerGuillaume Chatelet <gchatelet@google.com>2018-08-03 09:29:38 +0000
commit80d3cc7363b473caef0700747787970daf2003f7 (patch)
tree23636df19497db6ab0ee6ae910e468e9f9700583 /tools/llvm-exegesis
parent33493244220b8f1bc9b52bfa4bf02d54ccebdd72 (diff)
[llvm-exegesis] Renaming classes and functions.
Summary: Functional No Op. Reviewers: gchatelet Subscribers: tschuett, courbet, llvm-commits Differential Revision: https://reviews.llvm.org/D50231 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338836 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-exegesis')
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkRunner.cpp122
-rw-r--r--tools/llvm-exegesis/lib/BenchmarkRunner.h51
-rw-r--r--tools/llvm-exegesis/lib/Latency.cpp25
-rw-r--r--tools/llvm-exegesis/lib/Latency.h8
-rw-r--r--tools/llvm-exegesis/lib/MCInstrDescView.cpp4
-rw-r--r--tools/llvm-exegesis/lib/MCInstrDescView.h50
-rw-r--r--tools/llvm-exegesis/lib/Uops.cpp67
-rw-r--r--tools/llvm-exegesis/lib/Uops.h4
-rw-r--r--tools/llvm-exegesis/lib/X86/Target.cpp24
9 files changed, 174 insertions, 181 deletions
diff --git a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index f740489dd76..42fad2ff48f 100644
--- a/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -47,55 +47,54 @@ BenchmarkRunner::run(unsigned Opcode, unsigned NumRepetitions) {
return llvm::make_error<BenchmarkFailure>(
"Unsupported opcode: isCall/isReturn");
- llvm::Expected<std::vector<BenchmarkConfiguration>> ConfigurationOrError =
+ llvm::Expected<std::vector<BenchmarkCode>> ConfigurationOrError =
generateConfigurations(Opcode);
if (llvm::Error E = ConfigurationOrError.takeError())
return std::move(E);
std::vector<InstructionBenchmark> InstrBenchmarks;
- for (const BenchmarkConfiguration &Conf : ConfigurationOrError.get())
- InstrBenchmarks.push_back(runOne(Conf, Opcode, NumRepetitions));
+ for (const BenchmarkCode &Conf : ConfigurationOrError.get())
+ InstrBenchmarks.push_back(runConfiguration(Conf, Opcode, NumRepetitions));
return InstrBenchmarks;
}
+// Repeat the snippet until there are at least NumInstructions in the resulting
+// code.
+static std::vector<llvm::MCInst>
+GenerateInstructions(const BenchmarkCode &BC, const int MinInstructions) {
+ std::vector<llvm::MCInst> Code = BC.Instructions;
+ for (int I = 0; I < MinInstructions; ++I)
+ Code.push_back(BC.Instructions[I % BC.Instructions.size()]);
+ return Code;
+}
+
InstructionBenchmark
-BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
- unsigned Opcode, unsigned NumRepetitions) const {
+BenchmarkRunner::runConfiguration(const BenchmarkCode &BC, unsigned Opcode,
+ unsigned NumRepetitions) const {
InstructionBenchmark InstrBenchmark;
InstrBenchmark.Mode = Mode;
InstrBenchmark.CpuName = State.getTargetMachine().getTargetCPU();
InstrBenchmark.LLVMTriple =
State.getTargetMachine().getTargetTriple().normalize();
InstrBenchmark.NumRepetitions = NumRepetitions;
- InstrBenchmark.Info = Configuration.Info;
+ InstrBenchmark.Info = BC.Info;
- const std::vector<llvm::MCInst> &Snippet = Configuration.Snippet;
- if (Snippet.empty()) {
+ const std::vector<llvm::MCInst> &Instructions = BC.Instructions;
+ if (Instructions.empty()) {
InstrBenchmark.Error = "Empty snippet";
return InstrBenchmark;
}
- InstrBenchmark.Key.Instructions = Snippet;
-
- // Repeat the snippet until there are at least NumInstructions in the
- // resulting code. The snippet is always repeated at least once.
- const auto GenerateInstructions = [&Configuration](
- const int MinInstructions) {
- std::vector<llvm::MCInst> Code = Configuration.Snippet;
- for (int I = 0; I < MinInstructions; ++I)
- Code.push_back(Configuration.Snippet[I % Configuration.Snippet.size()]);
- return Code;
- };
+ InstrBenchmark.Key.Instructions = Instructions;
// Assemble at least kMinInstructionsForSnippet instructions by repeating the
// snippet for debug/analysis. This is so that the user clearly understands
// that the inside instructions are repeated.
constexpr const int kMinInstructionsForSnippet = 16;
{
- auto ObjectFilePath =
- writeObjectFile(Configuration.SnippetSetup,
- GenerateInstructions(kMinInstructionsForSnippet));
+ auto ObjectFilePath = writeObjectFile(
+ BC, GenerateInstructions(BC, kMinInstructionsForSnippet));
if (llvm::Error E = ObjectFilePath.takeError()) {
InstrBenchmark.Error = llvm::toString(std::move(E));
return InstrBenchmark;
@@ -108,9 +107,8 @@ BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
// Assemble NumRepetitions instructions repetitions of the snippet for
// measurements.
- auto ObjectFilePath =
- writeObjectFile(Configuration.SnippetSetup,
- GenerateInstructions(InstrBenchmark.NumRepetitions));
+ auto ObjectFilePath = writeObjectFile(
+ BC, GenerateInstructions(BC, InstrBenchmark.NumRepetitions));
if (llvm::Error E = ObjectFilePath.takeError()) {
InstrBenchmark.Error = llvm::toString(std::move(E));
return InstrBenchmark;
@@ -124,37 +122,41 @@ BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
return InstrBenchmark;
}
-llvm::Expected<std::vector<BenchmarkConfiguration>>
+llvm::Expected<std::vector<BenchmarkCode>>
BenchmarkRunner::generateConfigurations(unsigned Opcode) const {
- if (auto E = generatePrototype(Opcode)) {
- SnippetPrototype &Prototype = E.get();
- // TODO: Generate as many configurations as needed here.
- BenchmarkConfiguration Configuration;
- Configuration.Info = Prototype.Explanation;
- for (InstructionBuilder &IB : Prototype.Snippet) {
- IB.randomizeUnsetVariables(
- Prototype.ScratchSpaceReg
- ? RATC.getRegister(Prototype.ScratchSpaceReg).aliasedBits()
- : RATC.emptyRegisters());
- Configuration.Snippet.push_back(IB.build());
+ 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));
}
- if (Prototype.ScratchSpaceReg)
- Configuration.SnippetSetup.LiveIns.push_back(Prototype.ScratchSpaceReg);
- Configuration.SnippetSetup.RegsToDef = computeRegsToDef(Prototype.Snippet);
- return std::vector<BenchmarkConfiguration>{Configuration};
+ return Output;
} else
return E.takeError();
}
std::vector<unsigned> BenchmarkRunner::computeRegsToDef(
- const std::vector<InstructionBuilder> &Snippet) const {
+ 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 : Snippet) {
+ 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 {
@@ -189,7 +191,7 @@ std::vector<unsigned> BenchmarkRunner::computeRegsToDef(
}
llvm::Expected<std::string>
-BenchmarkRunner::writeObjectFile(const BenchmarkConfiguration::Setup &Setup,
+BenchmarkRunner::writeObjectFile(const BenchmarkCode &BC,
llvm::ArrayRef<llvm::MCInst> Code) const {
int ResultFD = 0;
llvm::SmallString<256> ResultPath;
@@ -198,38 +200,36 @@ BenchmarkRunner::writeObjectFile(const BenchmarkConfiguration::Setup &Setup,
return std::move(E);
llvm::raw_fd_ostream OFS(ResultFD, true /*ShouldClose*/);
assembleToStream(State.getExegesisTarget(), State.createTargetMachine(),
- Setup.LiveIns, Setup.RegsToDef, Code, OFS);
+ BC.LiveIns, BC.RegsToDef, Code, OFS);
return ResultPath.str();
}
-llvm::Expected<SnippetPrototype>
-BenchmarkRunner::generateSelfAliasingPrototype(const Instruction &Instr) const {
+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");
}
- SnippetPrototype Prototype;
+ CodeTemplate CT;
InstructionBuilder IB(Instr);
if (SelfAliasing.hasImplicitAliasing()) {
- Prototype.Explanation = "implicit Self cycles, picking random values.";
+ CT.Info = "implicit Self cycles, picking random values.";
} else {
- Prototype.Explanation =
- "explicit self cycles, selecting one aliasing Conf.";
+ 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);
}
- Prototype.Snippet.push_back(std::move(IB));
- return std::move(Prototype);
+ CT.Instructions.push_back(std::move(IB));
+ return std::move(CT);
}
-llvm::Expected<SnippetPrototype>
-BenchmarkRunner::generateUnconstrainedPrototype(const Instruction &Instr,
- llvm::StringRef Msg) const {
- SnippetPrototype Prototype;
- Prototype.Explanation =
- llvm::formatv("{0}, repeating an unconstrained assignment", Msg);
- Prototype.Snippet.emplace_back(Instr);
- return std::move(Prototype);
+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
diff --git a/tools/llvm-exegesis/lib/BenchmarkRunner.h b/tools/llvm-exegesis/lib/BenchmarkRunner.h
index af3968f8944..fcf89f838b4 100644
--- a/tools/llvm-exegesis/lib/BenchmarkRunner.h
+++ b/tools/llvm-exegesis/lib/BenchmarkRunner.h
@@ -37,18 +37,17 @@ public:
};
// A collection of instructions that are to be assembled, executed and measured.
-struct BenchmarkConfiguration {
- // This code is run before the Snippet is iterated. Since it is part of the
- // measurement it should be as short as possible. It is usually used to setup
- // the content of the Registers.
- struct Setup {
- std::vector<unsigned> LiveIns; // The registers that are live on entry.
- std::vector<unsigned> RegsToDef;
- };
- Setup SnippetSetup;
-
+struct BenchmarkCode {
// The sequence of instructions that are to be repeated.
- std::vector<llvm::MCInst> Snippet;
+ 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;
@@ -90,34 +89,34 @@ protected:
const LLVMState &State;
const RegisterAliasingTrackerCache RATC;
- // Generates a single instruction prototype that has a self-dependency.
- llvm::Expected<SnippetPrototype>
- generateSelfAliasingPrototype(const Instruction &Instr) const;
- // Generates a single instruction prototype without assignment constraints.
- llvm::Expected<SnippetPrototype>
- generateUnconstrainedPrototype(const Instruction &Instr,
- llvm::StringRef Msg) const;
+ // 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<SnippetPrototype>
- generatePrototype(unsigned Opcode) const = 0;
+ 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 runOne(const BenchmarkConfiguration &Configuration,
- unsigned Opcode, unsigned NumRepetitions) const;
+ InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration,
+ unsigned Opcode,
+ unsigned NumRepetitions) const;
- // Calls generatePrototype and expands the SnippetPrototype into one or more
- // BenchmarkConfiguration.
- llvm::Expected<std::vector<BenchmarkConfiguration>>
+ // 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 BenchmarkConfiguration::Setup &Setup,
+ writeObjectFile(const BenchmarkCode &Configuration,
llvm::ArrayRef<llvm::MCInst> Code) const;
const InstructionBenchmark::ModeE Mode;
diff --git a/tools/llvm-exegesis/lib/Latency.cpp b/tools/llvm-exegesis/lib/Latency.cpp
index 12bc8cd32b0..b8452ac35a8 100644
--- a/tools/llvm-exegesis/lib/Latency.cpp
+++ b/tools/llvm-exegesis/lib/Latency.cpp
@@ -42,7 +42,7 @@ llvm::Error LatencyBenchmarkRunner::isInfeasible(
return llvm::Error::success();
}
-llvm::Expected<SnippetPrototype>
+llvm::Expected<CodeTemplate>
LatencyBenchmarkRunner::generateTwoInstructionPrototype(
const Instruction &Instr) const {
std::vector<unsigned> Opcodes;
@@ -68,28 +68,27 @@ LatencyBenchmarkRunner::generateTwoInstructionPrototype(
setRandomAliasing(Forward, ThisIB, OtherIB);
if (!Back.hasImplicitAliasing())
setRandomAliasing(Back, OtherIB, ThisIB);
- SnippetPrototype Prototype;
- Prototype.Explanation =
- llvm::formatv("creating cycle through {0}.",
- State.getInstrInfo().getName(OtherOpcode));
- Prototype.Snippet.push_back(std::move(ThisIB));
- Prototype.Snippet.push_back(std::move(OtherIB));
- return std::move(Prototype);
+ CodeTemplate CT;
+ CT.Info = llvm::formatv("creating cycle through {0}.",
+ State.getInstrInfo().getName(OtherOpcode));
+ CT.Instructions.push_back(std::move(ThisIB));
+ CT.Instructions.push_back(std::move(OtherIB));
+ return std::move(CT);
}
return llvm::make_error<BenchmarkFailure>(
"Infeasible : Didn't find any scheme to make the instruction serial");
}
-llvm::Expected<SnippetPrototype>
-LatencyBenchmarkRunner::generatePrototype(unsigned Opcode) const {
+llvm::Expected<CodeTemplate>
+LatencyBenchmarkRunner::generateCodeTemplate(unsigned Opcode) const {
const auto &InstrDesc = State.getInstrInfo().get(Opcode);
if (auto E = isInfeasible(InstrDesc))
return std::move(E);
const Instruction Instr(InstrDesc, RATC);
- if (auto SelfAliasingPrototype = generateSelfAliasingPrototype(Instr))
- return SelfAliasingPrototype;
+ if (auto CT = generateSelfAliasingCodeTemplate(Instr))
+ return CT;
else
- llvm::consumeError(SelfAliasingPrototype.takeError());
+ llvm::consumeError(CT.takeError());
// No self aliasing, trying to create a dependency through another opcode.
return generateTwoInstructionPrototype(Instr);
}
diff --git a/tools/llvm-exegesis/lib/Latency.h b/tools/llvm-exegesis/lib/Latency.h
index fdaeb786fa5..f8c524afce4 100644
--- a/tools/llvm-exegesis/lib/Latency.h
+++ b/tools/llvm-exegesis/lib/Latency.h
@@ -26,14 +26,14 @@ public:
: BenchmarkRunner(State, InstructionBenchmark::Latency) {}
~LatencyBenchmarkRunner() override;
- llvm::Expected<SnippetPrototype>
- generatePrototype(unsigned Opcode) const override;
+ llvm::Expected<CodeTemplate>
+ generateCodeTemplate(unsigned Opcode) const override;
private:
llvm::Error isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const;
- llvm::Expected<SnippetPrototype> generateTwoInstructionPrototype(
- const Instruction &Instr) const;
+ llvm::Expected<CodeTemplate>
+ generateTwoInstructionPrototype(const Instruction &Instr) const;
std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF, ScratchSpace &Scratch,
diff --git a/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/tools/llvm-exegesis/lib/MCInstrDescView.cpp
index 39cb921d360..fc78bb121ae 100644
--- a/tools/llvm-exegesis/lib/MCInstrDescView.cpp
+++ b/tools/llvm-exegesis/lib/MCInstrDescView.cpp
@@ -159,9 +159,9 @@ llvm::MCInst InstructionBuilder::build() const {
return Result;
}
-SnippetPrototype::SnippetPrototype(SnippetPrototype &&) = default;
+CodeTemplate::CodeTemplate(CodeTemplate &&) = default;
-SnippetPrototype &SnippetPrototype::operator=(SnippetPrototype &&) = default;
+CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default;
bool RegisterOperandAssignment::
operator==(const RegisterOperandAssignment &Other) const {
diff --git a/tools/llvm-exegesis/lib/MCInstrDescView.h b/tools/llvm-exegesis/lib/MCInstrDescView.h
index 823c9e6b0fe..51f44cae45f 100644
--- a/tools/llvm-exegesis/lib/MCInstrDescView.h
+++ b/tools/llvm-exegesis/lib/MCInstrDescView.h
@@ -86,10 +86,10 @@ struct Instruction {
struct InstructionBuilder {
InstructionBuilder(const Instruction &Instr);
- InstructionBuilder(const InstructionBuilder &);
- InstructionBuilder &operator=(const InstructionBuilder &);
- InstructionBuilder(InstructionBuilder &&);
- InstructionBuilder &operator=(InstructionBuilder &&);
+ InstructionBuilder(const InstructionBuilder &); // default
+ InstructionBuilder &operator=(const InstructionBuilder &); // default
+ InstructionBuilder(InstructionBuilder &&); // default
+ InstructionBuilder &operator=(InstructionBuilder &&); // default
unsigned getOpcode() const;
llvm::MCOperand &getValueFor(const Variable &Var);
@@ -102,34 +102,34 @@ struct InstructionBuilder {
// Do not use any of the registers in `ForbiddenRegs`.
void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs);
- // Returns the instance as an llvm::MCInst. The InstructionBuilder must be
- // fully allocated (no invalid variables).
+ // Builds an llvm::MCInst from this InstructionBuilder setting its operands to
+ // the corresponding variable values.
+ // Precondition: All VariableValues must be set.
llvm::MCInst build() const;
Instruction Instr;
llvm::SmallVector<llvm::MCOperand, 4> VariableValues;
};
-// A prototype is a set of InstructionInstances with an explanation of how
-// it's been built. The prototype can then be randomized to exercice several
-// immediate values. It is also used to gather the used registers and define
-// their initial values.
-struct SnippetPrototype {
- SnippetPrototype() = default;
-
- // No copy.
- SnippetPrototype(const SnippetPrototype &) = delete;
- SnippetPrototype &operator=(const SnippetPrototype &) = delete;
-
- // Moving is OK.
- SnippetPrototype(SnippetPrototype &&);
- SnippetPrototype &operator=(SnippetPrototype &&);
-
- std::string Explanation;
- // If the prototype uses the provided scratch memory, the register in which
+// A CodeTemplate is a set of InstructionBuilders that may not be fully
+// specified (i.e. some variables are not yet set).
+// This allows the BenchmarkRunner to instantiate it many times with specific
+// values to study their impact on instruction's performance.
+struct CodeTemplate {
+ CodeTemplate() = default;
+
+ CodeTemplate(CodeTemplate &&); // default
+ CodeTemplate &operator=(CodeTemplate &&); // default
+ CodeTemplate(const CodeTemplate &) = delete;
+ CodeTemplate &operator=(const CodeTemplate &) = delete;
+
+ // Some information about how this template has been created.
+ std::string Info;
+ // The list of the instructions for this template.
+ std::vector<InstructionBuilder> Instructions;
+ // If the template uses the provided scratch memory, the register in which
// the pointer to this memory is passed in to the function.
- unsigned ScratchSpaceReg = 0;
- std::vector<InstructionBuilder> Snippet;
+ unsigned ScratchSpacePointerInReg = 0;
};
// Represents the assignment of a Register to an Operand.
diff --git a/tools/llvm-exegesis/lib/Uops.cpp b/tools/llvm-exegesis/lib/Uops.cpp
index 3089a98ac48..d7346de85a0 100644
--- a/tools/llvm-exegesis/lib/Uops.cpp
+++ b/tools/llvm-exegesis/lib/Uops.cpp
@@ -125,47 +125,47 @@ static void remove(llvm::BitVector &a, const llvm::BitVector &b) {
UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
void UopsBenchmarkRunner::instantiateMemoryOperands(
- const unsigned ScratchSpaceReg,
- std::vector<InstructionBuilder> &Snippet) const {
- if (ScratchSpaceReg == 0)
+ const unsigned ScratchSpacePointerInReg,
+ std::vector<InstructionBuilder> &Instructions) const {
+ if (ScratchSpacePointerInReg == 0)
return; // no memory operands.
const auto &ET = State.getExegesisTarget();
const unsigned MemStep = ET.getMaxMemoryAccessSize();
- const size_t OriginalSnippetSize = Snippet.size();
+ const size_t OriginalInstructionsSize = Instructions.size();
size_t I = 0;
- for (InstructionBuilder &IB : Snippet) {
- ET.fillMemoryOperands(IB, ScratchSpaceReg, I * MemStep);
+ for (InstructionBuilder &IB : Instructions) {
+ ET.fillMemoryOperands(IB, ScratchSpacePointerInReg, I * MemStep);
++I;
}
- while (Snippet.size() < kMinNumDifferentAddresses) {
- InstructionBuilder IB = Snippet[I % OriginalSnippetSize];
- ET.fillMemoryOperands(IB, ScratchSpaceReg, I * MemStep);
+ while (Instructions.size() < kMinNumDifferentAddresses) {
+ InstructionBuilder IB = Instructions[I % OriginalInstructionsSize];
+ ET.fillMemoryOperands(IB, ScratchSpacePointerInReg, I * MemStep);
++I;
- Snippet.push_back(std::move(IB));
+ Instructions.push_back(std::move(IB));
}
assert(I * MemStep < ScratchSpace::kSize && "not enough scratch space");
}
-llvm::Expected<SnippetPrototype>
-UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
+llvm::Expected<CodeTemplate>
+UopsBenchmarkRunner::generateCodeTemplate(unsigned Opcode) const {
const auto &InstrDesc = State.getInstrInfo().get(Opcode);
if (auto E = isInfeasible(InstrDesc))
return std::move(E);
const Instruction Instr(InstrDesc, RATC);
const auto &ET = State.getExegesisTarget();
- SnippetPrototype Prototype;
+ CodeTemplate CT;
const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
if (Instr.hasMemoryOperands()) {
- Prototype.ScratchSpaceReg =
+ CT.ScratchSpacePointerInReg =
ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
- if (Prototype.ScratchSpaceReg == 0)
+ if (CT.ScratchSpacePointerInReg == 0)
return llvm::make_error<BenchmarkFailure>(
"Infeasible : target does not support memory instructions");
ScratchSpaceAliasedRegs =
- &RATC.getRegister(Prototype.ScratchSpaceReg).aliasedBits();
- // If the instruction implicitly writes to ScratchSpaceReg , abort.
+ &RATC.getRegister(CT.ScratchSpacePointerInReg).aliasedBits();
+ // If the instruction implicitly writes to ScratchSpacePointerInReg , abort.
// FIXME: We could make a copy of the scratch register.
for (const auto &Op : Instr.Operands) {
if (Op.IsDef && Op.ImplicitReg &&
@@ -178,16 +178,16 @@ UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
const AliasingConfigurations SelfAliasing(Instr, Instr);
InstructionBuilder IB(Instr);
if (SelfAliasing.empty()) {
- Prototype.Explanation = "instruction is parallel, repeating a random one.";
- Prototype.Snippet.push_back(std::move(IB));
- instantiateMemoryOperands(Prototype.ScratchSpaceReg, Prototype.Snippet);
- return std::move(Prototype);
+ CT.Info = "instruction is parallel, repeating a random one.";
+ CT.Instructions.push_back(std::move(IB));
+ instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
+ return std::move(CT);
}
if (SelfAliasing.hasImplicitAliasing()) {
- Prototype.Explanation = "instruction is serial, repeating a random one.";
- Prototype.Snippet.push_back(std::move(IB));
- instantiateMemoryOperands(Prototype.ScratchSpaceReg, Prototype.Snippet);
- return std::move(Prototype);
+ CT.Info = "instruction is serial, repeating a random one.";
+ CT.Instructions.push_back(std::move(IB));
+ instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
+ return std::move(CT);
}
const auto TiedVariables = getTiedVariables(Instr);
if (!TiedVariables.empty()) {
@@ -200,17 +200,16 @@ UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
assert(!Var->TiedOperands.empty());
const Operand &Op = Instr.Operands[Var->TiedOperands.front()];
assert(Op.Tracker);
- Prototype.Explanation =
- "instruction has tied variables using static renaming.";
+ CT.Info = "instruction has tied variables using static renaming.";
for (const llvm::MCPhysReg Reg : Op.Tracker->sourceBits().set_bits()) {
if (ScratchSpaceAliasedRegs && ScratchSpaceAliasedRegs->test(Reg))
continue; // Do not use the scratch memory address register.
InstructionBuilder TmpIB = IB;
TmpIB.getValueFor(*Var) = llvm::MCOperand::createReg(Reg);
- Prototype.Snippet.push_back(std::move(TmpIB));
+ CT.Instructions.push_back(std::move(TmpIB));
}
- instantiateMemoryOperands(Prototype.ScratchSpaceReg, Prototype.Snippet);
- return std::move(Prototype);
+ instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
+ return std::move(CT);
}
// No tied variables, we pick random values for defs.
llvm::BitVector Defs(State.getRegInfo().getNumRegs());
@@ -242,11 +241,11 @@ UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
IB.getValueFor(Op) = llvm::MCOperand::createReg(RandomReg);
}
}
- Prototype.Explanation =
+ CT.Info =
"instruction has no tied variables picking Uses different from defs";
- Prototype.Snippet.push_back(std::move(IB));
- instantiateMemoryOperands(Prototype.ScratchSpaceReg, Prototype.Snippet);
- return std::move(Prototype);
+ CT.Instructions.push_back(std::move(IB));
+ instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions);
+ return std::move(CT);
}
std::vector<BenchmarkMeasure>
diff --git a/tools/llvm-exegesis/lib/Uops.h b/tools/llvm-exegesis/lib/Uops.h
index 58c1d347d81..0236cd99182 100644
--- a/tools/llvm-exegesis/lib/Uops.h
+++ b/tools/llvm-exegesis/lib/Uops.h
@@ -25,8 +25,8 @@ public:
: BenchmarkRunner(State, InstructionBenchmark::Uops) {}
~UopsBenchmarkRunner() override;
- llvm::Expected<SnippetPrototype>
- generatePrototype(unsigned Opcode) const override;
+ llvm::Expected<CodeTemplate>
+ generateCodeTemplate(unsigned Opcode) const override;
static constexpr const size_t kMinNumDifferentAddresses = 6;
diff --git a/tools/llvm-exegesis/lib/X86/Target.cpp b/tools/llvm-exegesis/lib/X86/Target.cpp
index f958c8d99e7..511aa55919f 100644
--- a/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -25,8 +25,8 @@ namespace {
template <typename Impl> class X86BenchmarkRunner : public Impl {
using Impl::Impl;
- llvm::Expected<SnippetPrototype>
- generatePrototype(unsigned Opcode) const override {
+ llvm::Expected<CodeTemplate>
+ generateCodeTemplate(unsigned Opcode) const override {
// Test whether we can generate a snippet for this instruction.
const auto &InstrInfo = this->State.getInstrInfo();
const auto OpcodeName = InstrInfo.getName(Opcode);
@@ -54,7 +54,7 @@ template <typename Impl> class X86BenchmarkRunner : public Impl {
// - `ST(0) = ST(0) + ST(i)` (TwoArgFP)
// They are intrinsically serial and do not modify the state of the stack.
// We generate the same code for latency and uops.
- return this->generateSelfAliasingPrototype(Instr);
+ return this->generateSelfAliasingCodeTemplate(Instr);
}
case llvm::X86II::CompareFP:
return Impl::handleCompareFP(Instr);
@@ -67,7 +67,7 @@ template <typename Impl> class X86BenchmarkRunner : public Impl {
}
// Fallback to generic implementation.
- return Impl::Base::generatePrototype(Opcode);
+ return Impl::Base::generateCodeTemplate(Opcode);
}
};
@@ -75,12 +75,10 @@ class X86LatencyImpl : public LatencyBenchmarkRunner {
protected:
using Base = LatencyBenchmarkRunner;
using Base::Base;
- llvm::Expected<SnippetPrototype>
- handleCompareFP(const Instruction &Instr) const {
+ llvm::Expected<CodeTemplate> handleCompareFP(const Instruction &Instr) const {
return llvm::make_error<BenchmarkFailure>("Unsupported x87 CompareFP");
}
- llvm::Expected<SnippetPrototype>
- handleCondMovFP(const Instruction &Instr) const {
+ llvm::Expected<CodeTemplate> handleCondMovFP(const Instruction &Instr) const {
return llvm::make_error<BenchmarkFailure>("Unsupported x87 CondMovFP");
}
};
@@ -91,14 +89,12 @@ protected:
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).
- llvm::Expected<SnippetPrototype>
- handleCompareFP(const Instruction &Instr) const {
- return generateUnconstrainedPrototype(
+ llvm::Expected<CodeTemplate> handleCompareFP(const Instruction &Instr) const {
+ return generateUnconstrainedCodeTemplate(
Instr, "instruction does not grow/shrink the FP stack");
}
- llvm::Expected<SnippetPrototype>
- handleCondMovFP(const Instruction &Instr) const {
- return generateUnconstrainedPrototype(
+ llvm::Expected<CodeTemplate> handleCondMovFP(const Instruction &Instr) const {
+ return generateUnconstrainedCodeTemplate(
Instr, "instruction does not grow/shrink the FP stack");
}
};