86 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8// \file9//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 namespace37 38char RISCVExegesisPreprocessing::ID = 0;39 40static bool processAVLOperand(MachineInstr &MI, MachineRegisterInfo &MRI,41 const TargetInstrInfo &TII) {42 const MCInstrDesc &Desc = TII.get(MI.getOpcode());43 uint64_t TSFlags = Desc.TSFlags;44 if (!RISCVII::hasVLOp(TSFlags))45 return false;46 47 const MachineOperand &VLOp = MI.getOperand(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 virtual54 // register. The only reason we can do such replacement here is because it's55 // almost certain that VLReg only has a single definition.56 Register NewVLReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);57 MRI.replaceRegWith(VLReg, 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