forked from OSchip/llvm-project
[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode
llvm-svn: 344145
This commit is contained in:
parent
1b29ec6531
commit
9b59238822
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue