Index: test/tools/llvm-exegesis/X86/latency-CMOV32rr.s =================================================================== --- /dev/null +++ test/tools/llvm-exegesis/X86/latency-CMOV32rr.s @@ -0,0 +1,9 @@ +# RUN: llvm-exegesis -mode=latency -opcode-name=CMOV32rr | FileCheck %s + +CHECK: --- +CHECK-NEXT: mode: latency +CHECK-NEXT: key: +CHECK-NEXT: instructions: +CHECK-NEXT: CMOV32rr +CHECK-NEXT: config: '' +CHECK-LAST: ... Index: tools/llvm-exegesis/lib/SnippetGenerator.h =================================================================== --- tools/llvm-exegesis/lib/SnippetGenerator.h +++ tools/llvm-exegesis/lib/SnippetGenerator.h @@ -88,7 +88,8 @@ // Assigns a Random Value to all Variables in IT that are still Invalid. // Do not use any of the registers in `ForbiddenRegs`. -void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs, +void randomizeUnsetVariables(const ExegesisTarget &Target, + const llvm::BitVector &ForbiddenRegs, InstructionTemplate &IT); } // namespace exegesis Index: tools/llvm-exegesis/lib/SnippetGenerator.cpp =================================================================== --- tools/llvm-exegesis/lib/SnippetGenerator.cpp +++ tools/llvm-exegesis/lib/SnippetGenerator.cpp @@ -12,6 +12,7 @@ #include "Assembler.h" #include "MCInstrDescView.h" #include "SnippetGenerator.h" +#include "Target.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" @@ -50,7 +51,7 @@ BenchmarkCode BC; BC.Info = CT.Info; for (InstructionTemplate &IT : CT.Instructions) { - randomizeUnsetVariables(ForbiddenRegs, IT); + randomizeUnsetVariables(State.getExegesisTarget(), ForbiddenRegs, IT); BC.Instructions.push_back(IT.build()); } if (CT.ScratchSpacePointerInReg) @@ -156,29 +157,6 @@ return Container[randomIndex(Container.size())]; } -static void randomize(const Instruction &Instr, const Variable &Var, - llvm::MCOperand &AssignedValue, - const llvm::BitVector &ForbiddenRegs) { - const Operand &Op = Instr.getPrimaryOperand(Var); - switch (Op.getExplicitOperandInfo().OperandType) { - case llvm::MCOI::OperandType::OPERAND_IMMEDIATE: - // FIXME: explore immediate values too. - AssignedValue = llvm::MCOperand::createImm(1); - break; - case llvm::MCOI::OperandType::OPERAND_REGISTER: { - assert(Op.isReg()); - auto AllowedRegs = Op.getRegisterAliasing().sourceBits(); - assert(AllowedRegs.size() == ForbiddenRegs.size()); - for (auto I : ForbiddenRegs.set_bits()) - AllowedRegs.reset(I); - AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs)); - break; - } - default: - break; - } -} - static void setRegisterOperandValue(const RegisterOperandAssignment &ROV, InstructionTemplate &IB) { assert(ROV.Op); @@ -212,12 +190,13 @@ setRegisterOperandValue(randomElement(RandomConf.Uses), UseIB); } -void randomizeUnsetVariables(const llvm::BitVector &ForbiddenRegs, +void randomizeUnsetVariables(const ExegesisTarget &Target, + const llvm::BitVector &ForbiddenRegs, InstructionTemplate &IT) { for (const Variable &Var : IT.Instr.Variables) { llvm::MCOperand &AssignedValue = IT.getValueFor(Var); if (!AssignedValue.isValid()) - randomize(IT.Instr, Var, AssignedValue, ForbiddenRegs); + Target.randomizeMCOperand(IT.Instr, Var, AssignedValue, ForbiddenRegs); } } Index: tools/llvm-exegesis/lib/Target.h =================================================================== --- tools/llvm-exegesis/lib/Target.h +++ tools/llvm-exegesis/lib/Target.h @@ -102,6 +102,10 @@ // matter as long as it's large enough. virtual unsigned getMaxMemoryAccessSize() const { return 0; } + virtual void randomizeMCOperand(const Instruction &Instr, const Variable &Var, + llvm::MCOperand &AssignedValue, + const llvm::BitVector &ForbiddenRegs) const; + // Creates a snippet generator for the given mode. std::unique_ptr createSnippetGenerator(InstructionBenchmark::ModeE Mode, Index: tools/llvm-exegesis/lib/Target.cpp =================================================================== --- tools/llvm-exegesis/lib/Target.cpp +++ tools/llvm-exegesis/lib/Target.cpp @@ -86,6 +86,30 @@ return llvm::make_unique(State); } +void ExegesisTarget::randomizeMCOperand( + const Instruction &Instr, const Variable &Var, + llvm::MCOperand &AssignedValue, + const llvm::BitVector &ForbiddenRegs) const { + const Operand &Op = Instr.getPrimaryOperand(Var); + switch (Op.getExplicitOperandInfo().OperandType) { + case llvm::MCOI::OperandType::OPERAND_IMMEDIATE: + // FIXME: explore immediate values too. + AssignedValue = llvm::MCOperand::createImm(1); + break; + case llvm::MCOI::OperandType::OPERAND_REGISTER: { + assert(Op.isReg()); + auto AllowedRegs = Op.getRegisterAliasing().sourceBits(); + assert(AllowedRegs.size() == ForbiddenRegs.size()); + for (auto I : ForbiddenRegs.set_bits()) + AllowedRegs.reset(I); + AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs)); + break; + } + default: + break; + } +} + static_assert(std::is_pod::value, "We shouldn't have dynamic initialization here"); const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, Index: tools/llvm-exegesis/lib/X86/Target.cpp =================================================================== --- tools/llvm-exegesis/lib/X86/Target.cpp +++ tools/llvm-exegesis/lib/X86/Target.cpp @@ -430,6 +430,10 @@ unsigned getMaxMemoryAccessSize() const override { return 64; } + void randomizeMCOperand(const Instruction &Instr, const Variable &Var, + llvm::MCOperand &AssignedValue, + const llvm::BitVector &ForbiddenRegs) const override; + void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg, unsigned Offset) const override; @@ -482,6 +486,23 @@ return TT.isOSWindows() ? llvm::X86::RCX : llvm::X86::RDI; } +void ExegesisX86Target::randomizeMCOperand( + const Instruction &Instr, const Variable &Var, + llvm::MCOperand &AssignedValue, + const llvm::BitVector &ForbiddenRegs) const { + ExegesisTarget::randomizeMCOperand(Instr, Var, AssignedValue, ForbiddenRegs); + + const Operand &Op = Instr.getPrimaryOperand(Var); + switch (Op.getExplicitOperandInfo().OperandType) { + case llvm::X86::OperandType::OPERAND_COND_CODE: + // FIXME: explore all CC variants. + AssignedValue = llvm::MCOperand::createImm(1); + break; + default: + break; + } +} + void ExegesisX86Target::fillMemoryOperands(InstructionTemplate &IT, unsigned Reg, unsigned Offset) const {