[llvm] [Exegesis][RISCV] Add RISCV support for llvm-exegesis (PR #89047)

Bushev Dmitry via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 05:48:46 PDT 2024


================
@@ -0,0 +1,403 @@
+//===-- 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 "RISCVCounters.h"
+
+#include "MCTargetDesc/RISCVBaseInfo.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "MCTargetDesc/RISCVMatInt.h"
+#include "RISCVInstrInfo.h"
+
+// include computeAvailableFeatures and computeRequiredFeatures.
+#define GET_COMPUTE_FEATURES
+#define GET_AVAILABLE_OPCODE_CHECKER
+#include "RISCVGenInstrInfo.inc"
+#undef GET_COMPUTE_FEATURES
+#undef GET_AVAILABLE_OPCODE_CHECKER
+
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+
+#include <vector>
+
+namespace llvm {
+namespace exegesis {
+
+namespace {
+
+#include "RISCVGenExegesis.inc"
+
+class ExegesisRISCVTarget : public ExegesisTarget {
+public:
+  ExegesisRISCVTarget();
+
+  Expected<std::unique_ptr<pfm::CounterGroup>>
+  createCounter(StringRef CounterName, const LLVMState &State,
+                ArrayRef<const char *> ValidationCounters,
+                const pid_t ProcessID) const override;
+
+  bool checkOpcodeSupported(int Opcode,
+                            const MCSubtargetInfo &SI) const override;
+
+  MCRegister findRegisterByName(const StringRef RegName) const override;
+
+  bool matchesArch(Triple::ArchType Arch) const override;
+
+  std::vector<MCInst> 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;
+
+  virtual std::vector<MCInst>
+  storeRegValueToScratch(const MCSubtargetInfo &STI, unsigned Reg,
+                         unsigned Offset) const override;
+  ArrayRef<unsigned> getUnavailableRegisters() const override;
+
+  Error randomizeTargetMCOperand(const Instruction &Instr, const Variable &Var,
+                                 MCOperand &AssignedValue,
+                                 const BitVector &ForbiddenRegs) const override;
+
+  void processInstructionReservedRegs(InstructionTemplate &IT) const override;
+
+  std::vector<InstructionTemplate>
+  generateInstructionVariants(const Instruction &Instr,
+                              unsigned MaxConfigsPerOpcode) const override;
+};
+
+ExegesisRISCVTarget::ExegesisRISCVTarget()
+    : ExegesisTarget(RISCVCpuPfmCounters, RISCV_MC::isOpcodeAvailable) {}
+
+Expected<std::unique_ptr<pfm::CounterGroup>> ExegesisRISCVTarget::createCounter(
+    StringRef CounterName, const LLVMState &State,
+    ArrayRef<const char *> ValidationCounters, const pid_t ProcessID) const {
+  if (CounterName == RISCVPfmCounterNames[0]) {
+    // TODO add support for Linux perf counters
+    return createRISCVCpuCyclesCounter(pfm::PerfEvent(CounterName));
+  }
+  return make_error<Failure>(Twine("Unsupported performance counter '")
+                                 .concat(CounterName)
+                                 .concat("'"));
+}
+
+bool ExegesisRISCVTarget::checkOpcodeSupported(
+    int Opcode, const MCSubtargetInfo &SI) const {
+  auto Features = SI.getFeatureBits();
+  FeatureBitset AvailableFeatures =
+      RISCV_MC::computeAvailableFeatures(Features);
+  FeatureBitset RequiredFeatures = RISCV_MC::computeRequiredFeatures(Opcode);
+  FeatureBitset MissingFeatures = RequiredFeatures & ~AvailableFeatures;
+  return MissingFeatures.none();
+}
+
+#define GET_REGISTER_MATCHER
+#include "RISCVGenAsmMatcher.inc"
+
+MCRegister
+ExegesisRISCVTarget::findRegisterByName(const StringRef RegName) const {
+  MCRegister Reg;
+  if ((Reg = MatchRegisterName(RegName)))
+    return Reg;
+  if ((Reg = MatchRegisterAltName(RegName)))
+    return Reg;
+  return RISCV::NoRegister;
+}
+
+bool ExegesisRISCVTarget::matchesArch(Triple::ArchType Arch) const {
+  return Arch == Triple::riscv32 || Arch == Triple::riscv64;
+}
+
+// Stores constant value to a general-purpose (integer) register.
+static std::vector<MCInst> loadIntReg(const MCSubtargetInfo &STI, unsigned Reg,
+                                      const APInt &Value) {
+  RISCVMatInt::InstSeq InstSeq =
+      RISCVMatInt::generateInstSeq(Value.getSExtValue(), STI);
+  // First instruction has form 'Op DestReg, X0, Imm'
+  MCRegister SrcReg = RISCV::X0;
+  MCRegister DestReg = Reg;
+  std::vector<MCInst> MatIntInstrs;
+  MatIntInstrs.reserve(InstSeq.size());
+  for (const RISCVMatInt::Inst &Inst : InstSeq) {
+    switch (Inst.getOpndKind()) {
+    case RISCVMatInt::Imm:
+      MatIntInstrs.push_back(
+          MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.getImm()));
----------------
dybv-sc wrote:

Fixed

https://github.com/llvm/llvm-project/pull/89047


More information about the llvm-commits mailing list