Skip to content

Commit

Permalink
[llvm-exegesis] Renaming classes and functions.
Browse files Browse the repository at this point in the history
Summary: Functional No Op.

Reviewers: gchatelet

Subscribers: tschuett, courbet, llvm-commits

Differential Revision: https://reviews.llvm.org/D50231

llvm-svn: 338836
  • Loading branch information
gchatelet committed Aug 3, 2018
1 parent d62c5ec commit e60866a
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 238 deletions.
122 changes: 61 additions & 61 deletions llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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
51 changes: 25 additions & 26 deletions llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
Expand Up @@ -37,18 +37,17 @@ class BenchmarkFailure : public llvm::StringError {
};

// 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;
Expand Down Expand Up @@ -90,34 +89,34 @@ class BenchmarkRunner {
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;
Expand Down
25 changes: 12 additions & 13 deletions llvm/tools/llvm-exegesis/lib/Latency.cpp
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions llvm/tools/llvm-exegesis/lib/Latency.h
Expand Up @@ -26,14 +26,14 @@ class LatencyBenchmarkRunner : public BenchmarkRunner {
: 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,
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp
Expand Up @@ -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 {
Expand Down

0 comments on commit e60866a

Please sign in to comment.