brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 13317c6 Raw
130 lines · cpp
1//===- RISCVExegesisPostprocessing.cpp - Post processing MI for exegesis---===//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// This Pass converts some of the virtual register operands in VSETVLI and FRM10// pseudos into physical registers.11//12//===----------------------------------------------------------------------===//13 14#include "RISCV.h"15#include "RISCVExegesisPasses.h"16#include "llvm/CodeGen/MachineFunctionPass.h"17#include "llvm/CodeGen/MachineRegisterInfo.h"18#include "llvm/Support/Debug.h"19 20using namespace llvm;21 22#define DEBUG_TYPE "riscv-exegesis-post-processing"23 24namespace {25struct RISCVExegesisPostprocessing : public MachineFunctionPass {26  static char ID;27 28  RISCVExegesisPostprocessing() : MachineFunctionPass(ID) {}29 30  bool runOnMachineFunction(MachineFunction &MF) override;31 32  void getAnalysisUsage(AnalysisUsage &AU) const override {33    AU.setPreservesCFG();34    MachineFunctionPass::getAnalysisUsage(AU);35  }36 37private:38  // Extremely simple register allocator that picks a register that hasn't39  // been defined or used in this function.40  Register allocateGPRRegister(const MachineFunction &MF,41                               const MachineRegisterInfo &MRI);42 43  bool processVSETVL(MachineInstr &MI, MachineRegisterInfo &MRI);44  bool processWriteFRM(MachineInstr &MI, MachineRegisterInfo &MRI);45};46} // anonymous namespace47 48char RISCVExegesisPostprocessing::ID = 0;49 50bool RISCVExegesisPostprocessing::runOnMachineFunction(MachineFunction &MF) {51  bool Changed = false;52  for (auto &MBB : MF)53    for (auto &MI : MBB) {54      unsigned Opcode = MI.getOpcode();55      switch (Opcode) {56      case RISCV::VSETVLI:57      case RISCV::VSETVL:58      case RISCV::PseudoVSETVLI:59      case RISCV::PseudoVSETVLIX0:60        Changed |= processVSETVL(MI, MF.getRegInfo());61        break;62      case RISCV::SwapFRMImm:63      case RISCV::WriteFRM:64        Changed |= processWriteFRM(MI, MF.getRegInfo());65        break;66      default:67        break;68      }69    }70 71  if (Changed)72    MF.getRegInfo().clearVirtRegs();73 74  LLVM_DEBUG(MF.print(dbgs() << "===After RISCVExegesisPostprocessing===\n");75             dbgs() << "\n");76 77  return Changed;78}79 80Register RISCVExegesisPostprocessing::allocateGPRRegister(81    const MachineFunction &MF, const MachineRegisterInfo &MRI) {82  const auto &TRI = *MRI.getTargetRegisterInfo();83 84  // We hope to avoid allocating callee-saved registers. And GPRTC85  // happens to account for nearly all caller-saved registers.86  const TargetRegisterClass *GPRClass = TRI.getRegClass(RISCV::GPRTCRegClassID);87  BitVector Candidates = TRI.getAllocatableSet(MF, GPRClass);88 89  for (unsigned SetIdx : Candidates.set_bits()) {90    if (MRI.reg_empty(Register(SetIdx)))91      return Register(SetIdx);92  }93 94  // All bets are off, assign a fixed one.95  return RISCV::X5;96}97 98bool RISCVExegesisPostprocessing::processVSETVL(MachineInstr &MI,99                                                MachineRegisterInfo &MRI) {100  bool Changed = false;101  // Replace both AVL and VL (i.e. the result) operands with physical102  // registers.103  for (unsigned Idx = 0U; Idx < 2; ++Idx)104    if (MI.getOperand(Idx).isReg()) {105      Register RegOp = MI.getOperand(Idx).getReg();106      if (RegOp.isVirtual()) {107        MRI.replaceRegWith(RegOp, allocateGPRRegister(*MI.getMF(), MRI));108        Changed = true;109      }110    }111 112  return Changed;113}114 115bool RISCVExegesisPostprocessing::processWriteFRM(MachineInstr &MI,116                                                  MachineRegisterInfo &MRI) {117  // The virtual register will be the first operand in both SwapFRMImm and118  // WriteFRM.119  Register DestReg = MI.getOperand(0).getReg();120  if (DestReg.isVirtual()) {121    MRI.replaceRegWith(DestReg, allocateGPRRegister(*MI.getMF(), MRI));122    return true;123  }124  return false;125}126 127FunctionPass *llvm::exegesis::createRISCVPostprocessingPass() {128  return new RISCVExegesisPostprocessing();129}130