[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode

llvm-svn: 344145
This commit is contained in:
Guillaume Chatelet 2018-10-10 14:57:32 +00:00
parent 1b29ec6531
commit 9b59238822
11 changed files with 37 additions and 32 deletions

View File

@ -57,8 +57,7 @@ LatencySnippetGenerator::generateTwoInstructionPrototype(
}
llvm::Expected<CodeTemplate>
LatencySnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
const Instruction Instr(State, Opcode);
LatencySnippetGenerator::generateCodeTemplate(const Instruction &Instr) const {
if (Instr.hasMemoryOperands())
return llvm::make_error<BenchmarkFailure>(
"Infeasible : has memory operands");

View File

@ -27,7 +27,7 @@ public:
~LatencySnippetGenerator() override;
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override;
generateCodeTemplate(const Instruction &Instr) const override;
private:
llvm::Expected<CodeTemplate>

View File

@ -88,7 +88,8 @@ const llvm::MCOperandInfo &Operand::getExplicitOperandInfo() const {
}
Instruction::Instruction(const LLVMState &State, unsigned Opcode)
: Description(&State.getInstrInfo().get(Opcode)) {
: Description(&State.getInstrInfo().get(Opcode)),
Name(State.getInstrInfo().getName(Opcode)) {
const auto &RATC = State.getRATC();
unsigned OpIndex = 0;
for (; OpIndex < Description->getNumOperands(); ++OpIndex) {
@ -198,6 +199,7 @@ bool Instruction::hasAliasingRegisters() const {
void Instruction::dump(const llvm::MCRegisterInfo &RegInfo,
llvm::raw_ostream &Stream) const {
Stream << "- " << Name << "\n";
for (const auto &Op : Operands) {
Stream << "- Op" << Op.getIndex();
if (Op.isExplicit())
@ -227,10 +229,15 @@ void Instruction::dump(const llvm::MCRegisterInfo &RegInfo,
}
for (const auto &Var : Variables) {
Stream << "- Var" << Var.getIndex();
Stream << " (";
for (auto OperandIndex : Var.TiedOperands)
Stream << " [";
bool IsFirst = true;
for (auto OperandIndex : Var.TiedOperands) {
if (!IsFirst)
Stream << ",";
Stream << "Op" << OperandIndex;
Stream << ")";
IsFirst = false;
}
Stream << "]";
Stream << "\n";
}
if (hasMemoryOperands())

View File

@ -130,6 +130,7 @@ struct Instruction {
llvm::raw_ostream &Stream) const;
const llvm::MCInstrDesc *Description; // Never nullptr.
llvm::StringRef Name; // The name of this instruction.
llvm::SmallVector<Operand, 8> Operands;
llvm::SmallVector<Variable, 4> Variables;
llvm::BitVector ImplDefRegs; // The set of aliased implicit def registers.

View File

@ -30,8 +30,8 @@ SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {}
SnippetGenerator::~SnippetGenerator() = default;
llvm::Expected<std::vector<BenchmarkCode>>
SnippetGenerator::generateConfigurations(unsigned Opcode) const {
if (auto E = generateCodeTemplate(Opcode)) {
SnippetGenerator::generateConfigurations(const Instruction &Instr) const {
if (auto E = generateCodeTemplate(Instr)) {
CodeTemplate &CT = E.get();
const auto &RATC = State.getRATC();
const llvm::BitVector &ForbiddenRegs =

View File

@ -46,7 +46,7 @@ public:
// Calls generateCodeTemplate and expands it into one or more BenchmarkCode.
llvm::Expected<std::vector<BenchmarkCode>>
generateConfigurations(unsigned Opcode) const;
generateConfigurations(const Instruction &Instr) const;
// Given a snippet, computes which registers the setup code needs to define.
std::vector<RegisterValue> computeRegisterInitialValues(
@ -66,7 +66,7 @@ protected:
private:
// API to be implemented by subclasses.
virtual llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const = 0;
generateCodeTemplate(const Instruction &Instr) const = 0;
};
// A global Random Number Generator to randomize configurations.

View File

@ -125,13 +125,11 @@ void UopsSnippetGenerator::instantiateMemoryOperands(
}
llvm::Expected<CodeTemplate>
UopsSnippetGenerator::generateCodeTemplate(unsigned Opcode) const {
const auto &ET = State.getExegesisTarget();
UopsSnippetGenerator::generateCodeTemplate(const Instruction &Instr) const {
CodeTemplate CT;
const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr;
const Instruction Instr(State, Opcode);
if (Instr.hasMemoryOperands()) {
const auto &ET = State.getExegesisTarget();
CT.ScratchSpacePointerInReg =
ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple());
if (CT.ScratchSpacePointerInReg == 0)

View File

@ -26,7 +26,7 @@ public:
~UopsSnippetGenerator() override;
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override;
generateCodeTemplate(const Instruction &Instr) const override;
static constexpr const size_t kMinNumDifferentAddresses = 6;

View File

@ -26,10 +26,9 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
using Impl::Impl;
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override {
generateCodeTemplate(const Instruction &Instr) const override {
// Test whether we can generate a snippet for this instruction.
const auto &InstrInfo = this->State.getInstrInfo();
const auto OpcodeName = InstrInfo.getName(Opcode);
const auto OpcodeName = Instr.Name;
if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
OpcodeName.startswith("ADJCALLSTACK")) {
return llvm::make_error<BenchmarkFailure>(
@ -38,8 +37,7 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
// Handle X87.
const unsigned FPInstClass =
InstrInfo.get(Opcode).TSFlags & llvm::X86II::FPTypeMask;
const Instruction Instr(this->State, Opcode);
Instr.Description->TSFlags & llvm::X86II::FPTypeMask;
switch (FPInstClass) {
case llvm::X86II::NotFP:
break;
@ -67,7 +65,7 @@ template <typename Impl> class X86SnippetGenerator : public Impl {
}
// Fallback to generic implementation.
return Impl::Base::generateCodeTemplate(Opcode);
return Impl::Base::generateCodeTemplate(Instr);
}
};

View File

@ -124,12 +124,8 @@ static unsigned getOpcodeOrDie(const llvm::MCInstrInfo &MCInstrInfo) {
// Generates code snippets for opcode `Opcode`.
static llvm::Expected<std::vector<BenchmarkCode>>
generateSnippets(const LLVMState &State, unsigned Opcode) {
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);
const Instruction Instr(State, Opcode);
const llvm::MCInstrDesc &InstrDesc = *Instr.Description;
// Ignore instructions that we cannot run.
if (InstrDesc.isPseudo())
return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
@ -140,7 +136,11 @@ generateSnippets(const LLVMState &State, unsigned Opcode) {
return llvm::make_error<BenchmarkFailure>(
"Unsupported opcode: isCall/isReturn");
return Generator->generateConfigurations(Opcode);
const std::unique_ptr<SnippetGenerator> Generator =
State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State);
if (!Generator)
llvm::report_fatal_error("cannot create snippet generator");
return Generator->generateConfigurations(Instr);
}
namespace {

View File

@ -59,7 +59,8 @@ protected:
CodeTemplate checkAndGetCodeTemplate(unsigned Opcode) {
randomGenerator().seed(0); // Initialize seed.
auto CodeTemplateOrError = Generator.generateCodeTemplate(Opcode);
const Instruction Instr(State, Opcode);
auto CodeTemplateOrError = Generator.generateCodeTemplate(Instr);
EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
return std::move(CodeTemplateOrError.get());
}
@ -238,7 +239,8 @@ TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
TEST_F(UopsSnippetGeneratorTest, MemoryUse_Movsb) {
// MOVSB writes to scratch memory register.
const unsigned Opcode = llvm::X86::MOVSB;
auto Error = Generator.generateCodeTemplate(Opcode).takeError();
const Instruction Instr(State, Opcode);
auto Error = Generator.generateCodeTemplate(Instr).takeError();
EXPECT_TRUE((bool)Error);
llvm::consumeError(std::move(Error));
}
@ -253,7 +255,7 @@ public:
private:
llvm::Expected<CodeTemplate>
generateCodeTemplate(unsigned Opcode) const override {
generateCodeTemplate(const Instruction &Instr) const override {
return llvm::make_error<llvm::StringError>("not implemented",
llvm::inconvertibleErrorCode());
}