diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-A.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-A.s deleted file mode 100644 index bdc02d4af21551..00000000000000 --- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-A.s +++ /dev/null @@ -1,59 +0,0 @@ -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOAND_D -mattr="+a" | FileCheck --check-prefix=AMOAND_D %s - -AMOAND_D: --- -AMOAND_D-NEXT: mode: latency -AMOAND_D-NEXT: key: -AMOAND_D-NEXT: instructions: -AMOAND_D-NEXT: - 'AMOAND_D [[RE01:X[0-9]+]] X10 [[RE01:X[0-9]+]]' -AMOAND_D-NEXT: config: '' -AMOAND_D-NEXT: register_initial_values: -AMOAND_D-NEXT: - '[[RE01:X[0-9]+]]=0x0' -AMOAND_D-DAG: ... - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOADD_W -mattr="+a" | FileCheck --check-prefix=AMOADD_W %s - -AMOADD_W: --- -AMOADD_W-NEXT: mode: latency -AMOADD_W-NEXT: key: -AMOADD_W-NEXT: instructions: -AMOADD_W-NEXT: - 'AMOADD_W [[RE02:X[0-9]+]] X10 [[RE02:X[0-9]+]]' -AMOADD_W-NEXT: config: '' -AMOADD_W-NEXT: register_initial_values: -AMOADD_W-NEXT: - '[[RE02:X[0-9]+]]=0x0' -AMOADD_W-DAG: ... - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOMAXU_D -mattr="+a" | FileCheck --check-prefix=AMOMAXU_D %s - -AMOMAXU_D: --- -AMOMAXU_D-NEXT: mode: latency -AMOMAXU_D-NEXT: key: -AMOMAXU_D-NEXT: instructions: -AMOMAXU_D-NEXT: - 'AMOMAXU_D [[RE03:X[0-9]+]] X10 [[RE03:X[0-9]+]]' -AMOMAXU_D-NEXT: config: '' -AMOMAXU_D-NEXT: register_initial_values: -AMOMAXU_D-NEXT: - '[[RE03:X[0-9]+]]=0x0' -AMOMAXU_D-DAG: ... - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOMIN_W -mattr="+a" | FileCheck --check-prefix=AMOMIN_W %s - -AMOMIN_W: --- -AMOMIN_W-NEXT: mode: latency -AMOMIN_W-NEXT: key: -AMOMIN_W-NEXT: instructions: -AMOMIN_W-NEXT: - 'AMOMIN_W [[RE04:X[0-9]+]] X10 [[RE04:X[0-9]+]]' -AMOMIN_W-NEXT: config: '' -AMOMIN_W-NEXT: register_initial_values: -AMOMIN_W-NEXT: - '[[RE04:X[0-9]+]]=0x0' -AMOMIN_W-DAG: ... - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=AMOXOR_D -mattr="+a" | FileCheck --check-prefix=AMOXOR_D %s - -AMOXOR_D: --- -AMOXOR_D-NEXT: mode: latency -AMOXOR_D-NEXT: key: -AMOXOR_D-NEXT: instructions: -AMOXOR_D-NEXT: - 'AMOXOR_D [[RE05:X[0-9]+]] X10 [[RE05:X[0-9]+]]' -AMOXOR_D-NEXT: config: '' -AMOXOR_D-NEXT: register_initial_values: -AMOXOR_D-NEXT: - '[[RE05:X[0-9]+]]=0x0' -AMOXOR_D-DAG: ... diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s deleted file mode 100644 index 9e94f024ed1162..00000000000000 --- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-extension-C.s +++ /dev/null @@ -1,48 +0,0 @@ -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ADDI -mattr=+c | FileCheck --check-prefix=C_ADDI %s - -C_ADDI: --- -C_ADDI-NEXT: mode: latency -C_ADDI-NEXT: key: -C_ADDI-NEXT: instructions: -C_ADDI-NEXT: - 'C_ADDI [[REG01:X[0-9]+]] [[RE02:X[0-9]+]] [[IMM0:i_0x[0-9]+]]' - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ADDIW -mattr=+c | FileCheck --check-prefix=C_ADDIW %s - -C_ADDIW: --- -C_ADDIW-NEXT: mode: latency -C_ADDIW-NEXT: key: -C_ADDIW-NEXT: instructions: -C_ADDIW-NEXT: - 'C_ADDIW [[REG11:X[0-9]+]] [[RE12:X[0-9]+]] [[IMM1:i_0x[0-9]+]]' - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_ANDI -mattr=+c | FileCheck --check-prefix=C_ANDI %s - -C_ANDI: --- -C_ANDI-NEXT: mode: latency -C_ANDI-NEXT: key: -C_ANDI-NEXT: instructions: -C_ANDI-NEXT: - 'C_ANDI [[REG31:X[0-9]+]] [[REG32:X[0-9]+]] [[IMM3:i_0x[0-9]+]]' - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SLLI -mattr=+c | FileCheck --check-prefix=C_SLLI %s - -C_SLLI: --- -C_SLLI-NEXT: mode: latency -C_SLLI-NEXT: key: -C_SLLI-NEXT: instructions: -C_SLLI-NEXT: - 'C_SLLI [[REG81:X[0-9]+]] [[REG82:X[0-9]+]] [[IMM8:i_0x[0-9]+]]' - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SRAI -mattr=+c | FileCheck --check-prefix=C_SRAI %s - -C_SRAI: --- -C_SRAI-NEXT: mode: latency -C_SRAI-NEXT: key: -C_SRAI-NEXT: instructions: -C_SRAI-NEXT: - 'C_SRAI [[REG91:X[0-9]+]] [[REG92:X[0-9]+]] [[IMM9:i_0x[0-9]+]]' - -# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --mcpu=generic --benchmark-phase=assemble-measured-code -opcode-name=C_SRLI -mattr=+c | FileCheck --check-prefix=C_SRLI %s - -C_SRLI: --- -C_SRLI-NEXT: mode: latency -C_SRLI-NEXT: key: -C_SRLI-NEXT: instructions: -C_SRLI-NEXT: - 'C_SRLI [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]' -C_SRLI-DAG: ... diff --git a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-opcode-name-FADD_D.s b/llvm/test/tools/llvm-exegesis/RISCV/latency-by-opcode-name-FADD_D.s deleted file mode 100644 index 2dea89cca4d7e9..00000000000000 --- a/llvm/test/tools/llvm-exegesis/RISCV/latency-by-opcode-name-FADD_D.s +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: llvm-exegesis -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -mode=latency --benchmark-phase=assemble-measured-code -mattr=+d -opcode-name=FADD_D | FileCheck %s - -CHECK: --- -CHECK-NEXT: mode: latency -CHECK-NEXT: key: -CHECK-NEXT: instructions: -CHECK-NEXT: - 'FADD_D [[REG1:F[0-9]+_D]] [[REG2:F[0-9]+_D]] [[REG3:F[0-9]+_D]] i_0x7' -CHECK-NEXT: config: '' -CHECK-NEXT: register_initial_values: -CHECK-DAG: - '[[REG1]]=0x0' -CHECK-DAG: ... diff --git a/llvm/test/tools/llvm-exegesis/RISCV/lit.local.cfg b/llvm/test/tools/llvm-exegesis/RISCV/lit.local.cfg deleted file mode 100644 index 466ccc26e78e1b..00000000000000 --- a/llvm/test/tools/llvm-exegesis/RISCV/lit.local.cfg +++ /dev/null @@ -1,3 +0,0 @@ -if not ("RISCV" in config.root.targets): - # We need support for RISCV. - config.unsupported = True diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt index d95c37ff5426bd..414b49e5e021c2 100644 --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -12,9 +12,6 @@ endif() if (LLVM_TARGETS_TO_BUILD MATCHES "Mips") list(APPEND LLVM_EXEGESIS_TARGETS "Mips") endif() -if(LLVM_TARGETS_TO_BUILD MATCHES "RISCV") - list(APPEND LLVM_EXEGESIS_TARGETS "RISCV") -endif() set(LLVM_EXEGESIS_TARGETS ${LLVM_EXEGESIS_TARGETS} PARENT_SCOPE) diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp index c9225e51213e59..9c926d1fc61124 100644 --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.cpp @@ -95,12 +95,11 @@ Instruction::Instruction(const MCInstrDesc *Description, StringRef Name, const BitVector *ImplDefRegs, const BitVector *ImplUseRegs, const BitVector *AllDefRegs, - const BitVector *AllUseRegs, - const BitVector *NonMemoryRegs) + const BitVector *AllUseRegs) : Description(*Description), Name(Name), Operands(std::move(Operands)), Variables(std::move(Variables)), ImplDefRegs(*ImplDefRegs), ImplUseRegs(*ImplUseRegs), AllDefRegs(*AllDefRegs), - AllUseRegs(*AllUseRegs), NonMemoryRegs(*NonMemoryRegs) {} + AllUseRegs(*AllUseRegs) {} std::unique_ptr Instruction::create(const MCInstrInfo &InstrInfo, @@ -167,8 +166,6 @@ Instruction::create(const MCInstrInfo &InstrInfo, BitVector ImplUseRegs = RATC.emptyRegisters(); BitVector AllDefRegs = RATC.emptyRegisters(); BitVector AllUseRegs = RATC.emptyRegisters(); - BitVector NonMemoryRegs = RATC.emptyRegisters(); - for (const auto &Op : Operands) { if (Op.isReg()) { const auto &AliasingBits = Op.getRegisterAliasing().aliasedBits(); @@ -180,8 +177,6 @@ Instruction::create(const MCInstrInfo &InstrInfo, ImplDefRegs |= AliasingBits; if (Op.isUse() && Op.isImplicit()) ImplUseRegs |= AliasingBits; - if (Op.isUse() && !Op.isMemory()) - NonMemoryRegs |= AliasingBits; } } // Can't use make_unique because constructor is private. @@ -190,8 +185,7 @@ Instruction::create(const MCInstrInfo &InstrInfo, std::move(Variables), BVC.getUnique(std::move(ImplDefRegs)), BVC.getUnique(std::move(ImplUseRegs)), BVC.getUnique(std::move(AllDefRegs)), - BVC.getUnique(std::move(AllUseRegs)), - BVC.getUnique(std::move(NonMemoryRegs)))); + BVC.getUnique(std::move(AllUseRegs)))); } const Operand &Instruction::getPrimaryOperand(const Variable &Var) const { @@ -246,12 +240,6 @@ bool Instruction::hasAliasingRegisters( ForbiddenRegisters); } -bool Instruction::hasAliasingNotMemoryRegisters( - const BitVector &ForbiddenRegisters) const { - return anyCommonExcludingForbidden(AllDefRegs, NonMemoryRegs, - ForbiddenRegisters); -} - bool Instruction::hasOneUseOrOneDef() const { return AllDefRegs.count() || AllUseRegs.count(); } diff --git a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h index d7712e21c32c1c..f8ebc07d01f35e 100644 --- a/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h +++ b/llvm/tools/llvm-exegesis/lib/MCInstrDescView.h @@ -133,12 +133,6 @@ struct Instruction { // aliasing Use and Def registers. bool hasAliasingRegisters(const BitVector &ForbiddenRegisters) const; - // Whether this instruction is self aliasing through some registers. - // Repeating this instruction may execute sequentially by picking aliasing - // Def and Not Memory Use registers. It may also execute in parallel by - // picking non aliasing Def and Not Memory Use registers. - bool hasAliasingNotMemoryRegisters(const BitVector &ForbiddenRegisters) const; - // Whether this instruction's registers alias with OtherInstr's registers. bool hasAliasingRegistersThrough(const Instruction &OtherInstr, const BitVector &ForbiddenRegisters) const; @@ -166,15 +160,12 @@ struct Instruction { const BitVector &ImplUseRegs; // The set of aliased implicit use registers. const BitVector &AllDefRegs; // The set of all aliased def registers. const BitVector &AllUseRegs; // The set of all aliased use registers. - // The set of all aliased not memory use registers. - const BitVector &NonMemoryRegs; - private: Instruction(const MCInstrDesc *Description, StringRef Name, SmallVector Operands, SmallVector Variables, const BitVector *ImplDefRegs, const BitVector *ImplUseRegs, const BitVector *AllDefRegs, - const BitVector *AllUseRegs, const BitVector *NonMemoryRegs); + const BitVector *AllUseRegs); }; // Instructions are expensive to instantiate. This class provides a cache of diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt deleted file mode 100644 index 489ac6d6e34b33..00000000000000 --- a/llvm/tools/llvm-exegesis/lib/RISCV/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -include_directories( - ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV - ${LLVM_BINARY_DIR}/lib/Target/RISCV -) - -set(LLVM_LINK_COMPONENTS - CodeGen - RISCV - Exegesis - Core - Support - ) - -add_llvm_library(LLVMExegesisRISCV - DISABLE_LLVM_LINK_LLVM_DYLIB - STATIC - Target.cpp - - DEPENDS - intrinsics_gen - RISCVCommonTableGen - ) diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp deleted file mode 100644 index 891818b625fe14..00000000000000 --- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp +++ /dev/null @@ -1,275 +0,0 @@ -//===-- Target.cpp ----------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "../Target.h" - -#include "MCTargetDesc/RISCVBaseInfo.h" -#include "MCTargetDesc/RISCVMCTargetDesc.h" -#include "MCTargetDesc/RISCVMatInt.h" -#include "RISCVInstrInfo.h" - -// include computeAvailableFeatures and computeRequiredFeatures. -#define GET_AVAILABLE_OPCODE_CHECKER -#include "RISCVGenInstrInfo.inc" - -#include "llvm/CodeGen/MachineInstrBuilder.h" - -#include - -namespace llvm { -namespace exegesis { - -namespace { - -// Stores constant value to a general-purpose (integer) register. -static std::vector loadIntReg(const MCSubtargetInfo &STI, unsigned Reg, - const APInt &Value) { - SmallVector MCInstSeq; - std::vector MatIntInstrs; - MCRegister DestReg = Reg; - - RISCVMatInt::generateMCInstSeq(Value.getSExtValue(), STI, DestReg, MCInstSeq); - MatIntInstrs.resize(MCInstSeq.size()); - std::copy(MCInstSeq.begin(), MCInstSeq.end(), MatIntInstrs.begin()); - - return MatIntInstrs; -} - -const unsigned ScratchIntReg = RISCV::X30; // t5 - -// Stores constant bits to a floating-point register. -static std::vector loadFPRegBits(const MCSubtargetInfo &STI, - unsigned Reg, const APInt &Bits, - unsigned FmvOpcode) { - std::vector Instrs = loadIntReg(STI, ScratchIntReg, Bits); - Instrs.push_back(MCInstBuilder(FmvOpcode).addReg(Reg).addReg(ScratchIntReg)); - return Instrs; -} - -// main idea is: -// we support APInt only if (represented as double) it has zero fractional -// part: 1.0, 2.0, 3.0, etc... then we can do the trick: write int to tmp reg t5 -// and then do FCVT this is only reliable thing in 32-bit mode, otherwise we -// need to use __floatsidf -static std::vector loadFP64RegBits32(const MCSubtargetInfo &STI, - unsigned Reg, const APInt &Bits) { - double D = Bits.bitsToDouble(); - double IPart; - double FPart = std::modf(D, &IPart); - - if (std::abs(FPart) > std::numeric_limits::epsilon()) { - errs() << "loadFP64RegBits32 is not implemented for doubles like " << D - << ", please remove fractional part\n"; - return {}; - } - - std::vector Instrs = loadIntReg(STI, ScratchIntReg, Bits); - Instrs.push_back( - MCInstBuilder(RISCV::FCVT_D_W).addReg(Reg).addReg(ScratchIntReg)); - return Instrs; -} - -static MCInst nop() { - // ADDI X0, X0, 0 - return MCInstBuilder(RISCV::ADDI) - .addReg(RISCV::X0) - .addReg(RISCV::X0) - .addImm(0); -} - -static bool isVectorRegList(unsigned Reg) { - return RISCV::VRM2RegClass.contains(Reg) || - RISCV::VRM4RegClass.contains(Reg) || - RISCV::VRM8RegClass.contains(Reg) || - RISCV::VRN2M1RegClass.contains(Reg) || - RISCV::VRN2M2RegClass.contains(Reg) || - RISCV::VRN2M4RegClass.contains(Reg) || - RISCV::VRN3M1RegClass.contains(Reg) || - RISCV::VRN3M2RegClass.contains(Reg) || - RISCV::VRN4M1RegClass.contains(Reg) || - RISCV::VRN4M2RegClass.contains(Reg) || - RISCV::VRN5M1RegClass.contains(Reg) || - RISCV::VRN6M1RegClass.contains(Reg) || - RISCV::VRN7M1RegClass.contains(Reg) || - RISCV::VRN8M1RegClass.contains(Reg); -} - -class ExegesisRISCVTarget : public ExegesisTarget { -public: - ExegesisRISCVTarget(); - - bool matchesArch(Triple::ArchType Arch) const override; - - std::vector setRegTo(const MCSubtargetInfo &STI, unsigned Reg, - const APInt &Value) const override; - - unsigned getDefaultLoopCounterRegister(const Triple &) const override; - - void decrementLoopCounterAndJump(MachineBasicBlock &MBB, - MachineBasicBlock &TargetMBB, - const MCInstrInfo &MII, - unsigned LoopRegister) const override; - - unsigned getScratchMemoryRegister(const Triple &TT) const override; - - void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg, - unsigned Offset) const override; - - ArrayRef getUnavailableRegisters() const override; - - Error randomizeTargetMCOperand(const Instruction &Instr, const Variable &Var, - MCOperand &AssignedValue, - const BitVector &ForbiddenRegs) const override; - - std::vector - generateInstructionVariants(const Instruction &Instr, - unsigned MaxConfigsPerOpcode) const override; -}; - -ExegesisRISCVTarget::ExegesisRISCVTarget() - : ExegesisTarget(ArrayRef{}, - RISCV_MC::isOpcodeAvailable) {} - -#define GET_REGISTER_MATCHER -#include "RISCVGenAsmMatcher.inc" - -bool ExegesisRISCVTarget::matchesArch(Triple::ArchType Arch) const { - return Arch == Triple::riscv32 || Arch == Triple::riscv64; -} - -std::vector ExegesisRISCVTarget::setRegTo(const MCSubtargetInfo &STI, - unsigned Reg, - const APInt &Value) const { - if (RISCV::GPRRegClass.contains(Reg)) - return loadIntReg(STI, Reg, Value); - if (RISCV::FPR16RegClass.contains(Reg)) - return loadFPRegBits(STI, Reg, Value, RISCV::FMV_H_X); - if (RISCV::FPR32RegClass.contains(Reg)) - return loadFPRegBits(STI, Reg, Value, RISCV::FMV_W_X); - if (RISCV::FPR64RegClass.contains(Reg)) { - if (STI.hasFeature(RISCV::Feature64Bit)) - return loadFPRegBits(STI, Reg, Value, RISCV::FMV_D_X); - return loadFP64RegBits32(STI, Reg, Value); - } - if (Reg == RISCV::FRM || Reg == RISCV::VL || Reg == RISCV::VLENB || - Reg == RISCV::VTYPE || RISCV::GPRPairRegClass.contains(Reg) || - RISCV::VRRegClass.contains(Reg) || isVectorRegList(Reg)) { - // Don't initialize: - // - FRM - // - VL, VLENB, VTYPE - // - vector registers (and vector register lists) - // - Zfinx registers - // Generate 'NOP' so that exegesis treats such registers as initialized - // (it tries to initialize them with '0' anyway). - return {nop()}; - } - errs() << "setRegTo is not implemented for Reg " << Reg - << ", results will be unreliable\n"; - return {}; -} - -const unsigned DefaultLoopCounterReg = RISCV::X31; // t6 -const unsigned ScratchMemoryReg = RISCV::X10; // a0 - -unsigned -ExegesisRISCVTarget::getDefaultLoopCounterRegister(const Triple &) const { - return DefaultLoopCounterReg; -} - -void ExegesisRISCVTarget::decrementLoopCounterAndJump( - MachineBasicBlock &MBB, MachineBasicBlock &TargetMBB, - const MCInstrInfo &MII, unsigned LoopRegister) const { - BuildMI(&MBB, DebugLoc(), MII.get(RISCV::ADDI)) - .addDef(LoopRegister) - .addUse(LoopRegister) - .addImm(-1); - BuildMI(&MBB, DebugLoc(), MII.get(RISCV::BNE)) - .addUse(LoopRegister) - .addUse(RISCV::X0) - .addMBB(&TargetMBB); -} - -unsigned ExegesisRISCVTarget::getScratchMemoryRegister(const Triple &TT) const { - return ScratchMemoryReg; // a0 -} - -void ExegesisRISCVTarget::fillMemoryOperands(InstructionTemplate &IT, - unsigned Reg, - unsigned Offset) const { - // TODO: for now we ignore Offset because have no way - // to detect it in instruction. - auto &I = IT.getInstr(); - - auto MemOpIt = - find_if(I.Operands, [](const Operand &Op) { return Op.isMemory(); }); - assert(MemOpIt != I.Operands.end() && - "Instruction must have memory operands"); - - const Operand &MemOp = *MemOpIt; - - assert(MemOp.isReg() && "Memory operand expected to be register"); - - IT.getValueFor(MemOp) = MCOperand::createReg(Reg); -} - -const unsigned UnavailableRegisters[4] = {RISCV::X0, DefaultLoopCounterReg, - ScratchIntReg, ScratchMemoryReg}; - -ArrayRef ExegesisRISCVTarget::getUnavailableRegisters() const { - return UnavailableRegisters; -} - -Error ExegesisRISCVTarget::randomizeTargetMCOperand( - const Instruction &Instr, const Variable &Var, MCOperand &AssignedValue, - const BitVector &ForbiddenRegs) const { - uint8_t OperandType = - Instr.getPrimaryOperand(Var).getExplicitOperandInfo().OperandType; - - switch (OperandType) { - case RISCVOp::OPERAND_FRMARG: - AssignedValue = MCOperand::createImm(RISCVFPRndMode::DYN); - break; - case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO: - AssignedValue = MCOperand::createImm(0b1 << 4); - break; - case RISCVOp::OPERAND_SIMM6_NONZERO: - case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO: - AssignedValue = MCOperand::createImm(1); - break; - default: - if (OperandType >= RISCVOp::OPERAND_FIRST_RISCV_IMM && - OperandType <= RISCVOp::OPERAND_LAST_RISCV_IMM) - AssignedValue = MCOperand::createImm(0); - } - return Error::success(); -} - -std::vector -ExegesisRISCVTarget::generateInstructionVariants( - const Instruction &Instr, unsigned int MaxConfigsPerOpcode) const { - InstructionTemplate IT{&Instr}; - for (const Operand &Op : Instr.Operands) - if (Op.isMemory()) { - IT.getValueFor(Op) = MCOperand::createReg(ScratchMemoryReg); - } - return {IT}; -} - -} // anonymous namespace - -static ExegesisTarget *getTheRISCVExegesisTarget() { - static ExegesisRISCVTarget Target; - return &Target; -} - -void InitializeRISCVExegesisTarget() { - ExegesisTarget::registerTarget(getTheRISCVExegesisTarget()); -} - -} // namespace exegesis -} // namespace llvm diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp index 25cdf1ce66d449..7100b51bbb7298 100644 --- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp +++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp @@ -53,6 +53,13 @@ computeAliasingInstructions(const LLVMState &State, const Instruction *Instr, if (OtherOpcode == Instr->Description.getOpcode()) continue; const Instruction &OtherInstr = State.getIC().getInstr(OtherOpcode); + const MCInstrDesc &OtherInstrDesc = OtherInstr.Description; + // Ignore instructions that we cannot run. + if (OtherInstrDesc.isPseudo() || OtherInstrDesc.usesCustomInsertionHook() || + OtherInstrDesc.isBranch() || OtherInstrDesc.isIndirectBranch() || + OtherInstrDesc.isCall() || OtherInstrDesc.isReturn()) { + continue; + } if (OtherInstr.hasMemoryOperands()) continue; if (!ET.allowAsBackToBack(OtherInstr)) @@ -74,10 +81,12 @@ static ExecutionMode getExecutionModes(const Instruction &Instr, EM |= ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS; if (Instr.hasMemoryOperands()) EM |= ExecutionMode::SERIAL_VIA_MEMORY_INSTR; - if (Instr.hasAliasingNotMemoryRegisters(ForbiddenRegisters)) - EM |= ExecutionMode::SERIAL_VIA_EXPLICIT_REGS; - if (Instr.hasOneUseOrOneDef()) - EM |= ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR; + else { + if (Instr.hasAliasingRegisters(ForbiddenRegisters)) + EM |= ExecutionMode::SERIAL_VIA_EXPLICIT_REGS; + if (Instr.hasOneUseOrOneDef()) + EM |= ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR; + } return EM; } diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp index 48357d443f713e..7dcff60a8fd11f 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp @@ -73,9 +73,6 @@ Error SnippetGenerator::generateConfigurations( for (CodeTemplate &CT : Templates) { // TODO: Generate as many BenchmarkCode as needed. { - CT.ScratchSpacePointerInReg = - State.getExegesisTarget().getScratchMemoryRegister( - State.getTargetMachine().getTargetTriple()); BenchmarkCode BC; BC.Info = CT.Info; BC.Key.Instructions.reserve(CT.Instructions.size()); @@ -111,12 +108,6 @@ std::vector SnippetGenerator::computeRegisterInitialValues( // Loop invariant: DefinedRegs[i] is true iif it has been set at least once // before the current instruction. BitVector DefinedRegs = State.getRATC().emptyRegisters(); - // If target always expects a scratch memory register as live input, - // mark it as defined. - const ExegesisTarget &Target = State.getExegesisTarget(); - unsigned ScratchMemoryReg = Target.getScratchMemoryRegister( - State.getTargetMachine().getTargetTriple()); - DefinedRegs.set(ScratchMemoryReg); std::vector RIV; for (const InstructionTemplate &IT : Instructions) { // Returns the register that this Operand sets or uses, or 0 if this is not @@ -209,8 +200,7 @@ static void setRegisterOperandValue(const RegisterOperandAssignment &ROV, if (ROV.Op->isExplicit()) { auto &AssignedValue = IB.getValueFor(*ROV.Op); if (AssignedValue.isValid()) { - // TODO don't re-assign register operands which are already "locked" - // by Target in corresponding InstructionTemplate + assert(AssignedValue.isReg() && AssignedValue.getReg() == ROV.Reg); return; } AssignedValue = MCOperand::createReg(ROV.Reg); diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index fa37e05956be8c..546ec770a8d221 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -274,10 +274,6 @@ static cl::opt BenchmarkProcessCPU( cl::desc("The CPU number that the benchmarking process should executon on"), cl::cat(BenchmarkOptions), cl::init(-1)); -static cl::opt MAttr( - "mattr", cl::desc("comma-separated list of target architecture features"), - cl::value_desc("+feature1,-feature2,..."), cl::cat(Options), cl::init("")); - static ExitOnError ExitOnErr("llvm-exegesis error: "); // Helper function that logs the error(s) and exits. @@ -300,18 +296,6 @@ T ExitOnFileError(const Twine &FileName, Expected &&E) { return std::move(*E); } -static const char *getIgnoredOpcodeReasonOrNull(const LLVMState &State, - unsigned Opcode) { - const MCInstrDesc &InstrDesc = State.getIC().getInstr(Opcode).Description; - if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook()) - return "Unsupported opcode: isPseudo/usesCustomInserter"; - if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch()) - return "Unsupported opcode: isBranch/isIndirectBranch"; - if (InstrDesc.isCall() || InstrDesc.isReturn()) - return "Unsupported opcode: isCall/isReturn"; - return nullptr; -} - // Checks that only one of OpcodeNames, OpcodeIndex or SnippetsFile is provided, // and returns the opcode indices or {} if snippets should be read from // `SnippetsFile`. @@ -350,7 +334,6 @@ static std::vector getOpcodesOrDie(const LLVMState &State) { return I->getSecond(); return 0u; }; - SmallVector Pieces; StringRef(OpcodeNames.getValue()) .split(Pieces, ",", /* MaxSplit */ -1, /* KeepEmpty */ false); @@ -369,11 +352,17 @@ static std::vector getOpcodesOrDie(const LLVMState &State) { static Expected> generateSnippets(const LLVMState &State, unsigned Opcode, const BitVector &ForbiddenRegs) { + const Instruction &Instr = State.getIC().getInstr(Opcode); + const MCInstrDesc &InstrDesc = Instr.Description; // Ignore instructions that we cannot run. - if (const char *Reason = getIgnoredOpcodeReasonOrNull(State, Opcode)) - return make_error(Reason); + if (InstrDesc.isPseudo() || InstrDesc.usesCustomInsertionHook()) + return make_error( + "Unsupported opcode: isPseudo/usesCustomInserter"); + if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch()) + return make_error("Unsupported opcode: isBranch/isIndirectBranch"); + if (InstrDesc.isCall() || InstrDesc.isReturn()) + return make_error("Unsupported opcode: isCall/isReturn"); - const Instruction &Instr = State.getIC().getInstr(Opcode); const std::vector InstructionVariants = State.getExegesisTarget().generateInstructionVariants( Instr, MaxConfigsPerOpcode); @@ -496,8 +485,8 @@ void benchmarkMain() { LLVMInitialize##TargetName##AsmParser(); #include "llvm/Config/TargetExegesis.def" - const LLVMState State = ExitOnErr( - LLVMState::Create(TripleName, MCPU, MAttr, UseDummyPerfCounters)); + const LLVMState State = + ExitOnErr(LLVMState::Create(TripleName, MCPU, "", UseDummyPerfCounters)); // Preliminary check to ensure features needed for requested // benchmark mode are present on target CPU and/or OS.