1//===- RISCVExegesisPreprocessing.cpp -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// \file
9//
10//===----------------------------------------------------------------------===//
11
12#include "RISCV.h"
13#include "RISCVExegesisPasses.h"
14#include "RISCVRegisterInfo.h"
15#include "RISCVSubtarget.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
17#include "llvm/CodeGen/MachineRegisterInfo.h"
18
19using namespace llvm;
20
21#define DEBUG_TYPE "riscv-exegesis-preprocessing"
22
23namespace {
24struct RISCVExegesisPreprocessing : public MachineFunctionPass {
25 static char ID;
26
27 RISCVExegesisPreprocessing() : MachineFunctionPass(ID) {}
28
29 bool runOnMachineFunction(MachineFunction &MF) override;
30
31 void getAnalysisUsage(AnalysisUsage &AU) const override {
32 AU.setPreservesCFG();
33 MachineFunctionPass::getAnalysisUsage(AU);
34 }
35};
36} // anonymous namespace
37
38char RISCVExegesisPreprocessing::ID = 0;
39
40static bool processAVLOperand(MachineInstr &MI, MachineRegisterInfo &MRI,
41 const TargetInstrInfo &TII) {
42 const MCInstrDesc &Desc = TII.get(Opcode: MI.getOpcode());
43 uint64_t TSFlags = Desc.TSFlags;
44 if (!RISCVII::hasVLOp(TSFlags))
45 return false;
46
47 const MachineOperand &VLOp = MI.getOperand(i: RISCVII::getVLOpNum(Desc));
48 if (VLOp.isReg()) {
49 Register VLReg = VLOp.getReg();
50 if (VLReg.isVirtual())
51 return false;
52 assert(RISCV::GPRRegClass.contains(VLReg));
53 // Replace all uses of the original physical register with a new virtual
54 // register. The only reason we can do such replacement here is because it's
55 // almost certain that VLReg only has a single definition.
56 Register NewVLReg = MRI.createVirtualRegister(RegClass: &RISCV::GPRRegClass);
57 MRI.replaceRegWith(FromReg: VLReg, ToReg: NewVLReg);
58 return true;
59 }
60
61 return false;
62}
63
64bool RISCVExegesisPreprocessing::runOnMachineFunction(MachineFunction &MF) {
65 MachineRegisterInfo &MRI = MF.getRegInfo();
66 const auto &STI = MF.getSubtarget<RISCVSubtarget>();
67 if (!STI.hasVInstructions())
68 return false;
69 const TargetInstrInfo &TII = *STI.getInstrInfo();
70
71 LLVM_DEBUG(MF.print(dbgs() << "===Before RISCVExegesisPoreprocessing===\n");
72 dbgs() << "\n");
73
74 bool Changed = false;
75 for (auto &MBB : MF)
76 for (auto &MI : MBB) {
77 Changed |= processAVLOperand(MI, MRI, TII);
78 }
79
80 return Changed;
81}
82
83FunctionPass *llvm::exegesis::createRISCVPreprocessingPass() {
84 return new RISCVExegesisPreprocessing();
85}
86