[llvm] [Exegesis][RISCV] Add initial RVV support (PR #128767)
Min-Yih Hsu via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 11:33:49 PST 2025
================
@@ -0,0 +1,130 @@
+//===- RISCVExegesisPostprocessing.cpp - Post processing MI for exegesis---===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// \file
+// Currently there is only one post-processing we need to do for exegesis:
+// Assign a physical register to VSETVL's rd if it's not X0 (i.e. VLMAX).
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "RISCVExegesisPasses.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-exegesis-post-processing"
+
+namespace {
+struct RISCVExegesisPostprocessing : public MachineFunctionPass {
+ static char ID;
+
+ RISCVExegesisPostprocessing() : MachineFunctionPass(ID) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+private:
+ // Extremely simple register allocator that picks a register that hasn't
+ // been defined or used in this function.
+ Register allocateGPRRegister(const MachineFunction &MF,
+ const MachineRegisterInfo &MRI);
+
+ bool processVSETVL(MachineInstr &MI, MachineRegisterInfo &MRI);
+ bool processWriteFRM(MachineInstr &MI, MachineRegisterInfo &MRI);
+};
+} // anonymous namespace
+
+char RISCVExegesisPostprocessing::ID = 0;
+
+bool RISCVExegesisPostprocessing::runOnMachineFunction(MachineFunction &MF) {
+ bool Changed = false;
+ for (auto &MBB : MF)
+ for (auto &MI : MBB) {
+ unsigned Opcode = MI.getOpcode();
+ switch (Opcode) {
+ case RISCV::VSETVLI:
+ case RISCV::VSETVL:
+ case RISCV::PseudoVSETVLI:
+ case RISCV::PseudoVSETVLIX0:
+ Changed |= processVSETVL(MI, MF.getRegInfo());
+ break;
+ case RISCV::SwapFRMImm:
+ case RISCV::WriteFRM:
+ Changed |= processWriteFRM(MI, MF.getRegInfo());
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (Changed)
+ MF.getRegInfo().clearVirtRegs();
+
+ LLVM_DEBUG(MF.print(dbgs() << "===After RISCVExegesisPostprocessing===\n");
+ dbgs() << "\n");
+
+ return Changed;
+}
+
+Register RISCVExegesisPostprocessing::allocateGPRRegister(
+ const MachineFunction &MF, const MachineRegisterInfo &MRI) {
+ const auto &TRI = *MRI.getTargetRegisterInfo();
+
+ const TargetRegisterClass *GPRClass =
+ TRI.getRegClass(RISCV::GPRJALRRegClassID);
----------------
mshockwave wrote:
The original idea was to avoid X0, X1(ra), X2(sp), and maybe X3(gp). As we're not able to spill them onto the stack if VSETVLI clobbers them. And GPRJALR happens to be a handy register class to skip them.
That said, now I think of this again, we probably should avoid all callee-saved registers (that are also not used in the snippet). I'll update this to use a different register class shortly.
https://github.com/llvm/llvm-project/pull/128767
More information about the llvm-commits
mailing list