1*5f757f3fSDimitry Andric //===-- RISCVPostRAExpandPseudoInsts.cpp - Expand pseudo instrs ----===// 2*5f757f3fSDimitry Andric // 3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5f757f3fSDimitry Andric // 7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 8*5f757f3fSDimitry Andric // 9*5f757f3fSDimitry Andric // This file contains a pass that expands the pseudo instruction pseudolisimm32 10*5f757f3fSDimitry Andric // into target instructions. This pass should be run during the post-regalloc 11*5f757f3fSDimitry Andric // passes, before post RA scheduling. 12*5f757f3fSDimitry Andric // 13*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 14*5f757f3fSDimitry Andric 15*5f757f3fSDimitry Andric #include "MCTargetDesc/RISCVMatInt.h" 16*5f757f3fSDimitry Andric #include "RISCV.h" 17*5f757f3fSDimitry Andric #include "RISCVInstrInfo.h" 18*5f757f3fSDimitry Andric #include "RISCVTargetMachine.h" 19*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 20*5f757f3fSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 21*5f757f3fSDimitry Andric 22*5f757f3fSDimitry Andric using namespace llvm; 23*5f757f3fSDimitry Andric 24*5f757f3fSDimitry Andric #define RISCV_POST_RA_EXPAND_PSEUDO_NAME \ 25*5f757f3fSDimitry Andric "RISC-V post-regalloc pseudo instruction expansion pass" 26*5f757f3fSDimitry Andric 27*5f757f3fSDimitry Andric namespace { 28*5f757f3fSDimitry Andric 29*5f757f3fSDimitry Andric class RISCVPostRAExpandPseudo : public MachineFunctionPass { 30*5f757f3fSDimitry Andric public: 31*5f757f3fSDimitry Andric const RISCVInstrInfo *TII; 32*5f757f3fSDimitry Andric static char ID; 33*5f757f3fSDimitry Andric 34*5f757f3fSDimitry Andric RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) { 35*5f757f3fSDimitry Andric initializeRISCVPostRAExpandPseudoPass(*PassRegistry::getPassRegistry()); 36*5f757f3fSDimitry Andric } 37*5f757f3fSDimitry Andric 38*5f757f3fSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 39*5f757f3fSDimitry Andric 40*5f757f3fSDimitry Andric StringRef getPassName() const override { 41*5f757f3fSDimitry Andric return RISCV_POST_RA_EXPAND_PSEUDO_NAME; 42*5f757f3fSDimitry Andric } 43*5f757f3fSDimitry Andric 44*5f757f3fSDimitry Andric private: 45*5f757f3fSDimitry Andric bool expandMBB(MachineBasicBlock &MBB); 46*5f757f3fSDimitry Andric bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 47*5f757f3fSDimitry Andric MachineBasicBlock::iterator &NextMBBI); 48*5f757f3fSDimitry Andric bool expandMovImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 49*5f757f3fSDimitry Andric }; 50*5f757f3fSDimitry Andric 51*5f757f3fSDimitry Andric char RISCVPostRAExpandPseudo::ID = 0; 52*5f757f3fSDimitry Andric 53*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 54*5f757f3fSDimitry Andric TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo()); 55*5f757f3fSDimitry Andric bool Modified = false; 56*5f757f3fSDimitry Andric for (auto &MBB : MF) 57*5f757f3fSDimitry Andric Modified |= expandMBB(MBB); 58*5f757f3fSDimitry Andric return Modified; 59*5f757f3fSDimitry Andric } 60*5f757f3fSDimitry Andric 61*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 62*5f757f3fSDimitry Andric bool Modified = false; 63*5f757f3fSDimitry Andric 64*5f757f3fSDimitry Andric MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 65*5f757f3fSDimitry Andric while (MBBI != E) { 66*5f757f3fSDimitry Andric MachineBasicBlock::iterator NMBBI = std::next(MBBI); 67*5f757f3fSDimitry Andric Modified |= expandMI(MBB, MBBI, NMBBI); 68*5f757f3fSDimitry Andric MBBI = NMBBI; 69*5f757f3fSDimitry Andric } 70*5f757f3fSDimitry Andric 71*5f757f3fSDimitry Andric return Modified; 72*5f757f3fSDimitry Andric } 73*5f757f3fSDimitry Andric 74*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMI(MachineBasicBlock &MBB, 75*5f757f3fSDimitry Andric MachineBasicBlock::iterator MBBI, 76*5f757f3fSDimitry Andric MachineBasicBlock::iterator &NextMBBI) { 77*5f757f3fSDimitry Andric switch (MBBI->getOpcode()) { 78*5f757f3fSDimitry Andric case RISCV::PseudoMovImm: 79*5f757f3fSDimitry Andric return expandMovImm(MBB, MBBI); 80*5f757f3fSDimitry Andric default: 81*5f757f3fSDimitry Andric return false; 82*5f757f3fSDimitry Andric } 83*5f757f3fSDimitry Andric } 84*5f757f3fSDimitry Andric 85*5f757f3fSDimitry Andric bool RISCVPostRAExpandPseudo::expandMovImm(MachineBasicBlock &MBB, 86*5f757f3fSDimitry Andric MachineBasicBlock::iterator MBBI) { 87*5f757f3fSDimitry Andric DebugLoc DL = MBBI->getDebugLoc(); 88*5f757f3fSDimitry Andric 89*5f757f3fSDimitry Andric int64_t Val = MBBI->getOperand(1).getImm(); 90*5f757f3fSDimitry Andric 91*5f757f3fSDimitry Andric RISCVMatInt::InstSeq Seq = 92*5f757f3fSDimitry Andric RISCVMatInt::generateInstSeq(Val, MBB.getParent()->getSubtarget()); 93*5f757f3fSDimitry Andric assert(!Seq.empty()); 94*5f757f3fSDimitry Andric 95*5f757f3fSDimitry Andric Register DstReg = MBBI->getOperand(0).getReg(); 96*5f757f3fSDimitry Andric bool DstIsDead = MBBI->getOperand(0).isDead(); 97*5f757f3fSDimitry Andric bool Renamable = MBBI->getOperand(0).isRenamable(); 98*5f757f3fSDimitry Andric 99*5f757f3fSDimitry Andric TII->movImm(MBB, MBBI, DL, DstReg, Val, MachineInstr::NoFlags, Renamable, 100*5f757f3fSDimitry Andric DstIsDead); 101*5f757f3fSDimitry Andric 102*5f757f3fSDimitry Andric MBBI->eraseFromParent(); 103*5f757f3fSDimitry Andric return true; 104*5f757f3fSDimitry Andric } 105*5f757f3fSDimitry Andric 106*5f757f3fSDimitry Andric } // end of anonymous namespace 107*5f757f3fSDimitry Andric 108*5f757f3fSDimitry Andric INITIALIZE_PASS(RISCVPostRAExpandPseudo, "riscv-expand-pseudolisimm32", 109*5f757f3fSDimitry Andric RISCV_POST_RA_EXPAND_PSEUDO_NAME, false, false) 110*5f757f3fSDimitry Andric namespace llvm { 111*5f757f3fSDimitry Andric 112*5f757f3fSDimitry Andric FunctionPass *createRISCVPostRAExpandPseudoPass() { 113*5f757f3fSDimitry Andric return new RISCVPostRAExpandPseudo(); 114*5f757f3fSDimitry Andric } 115*5f757f3fSDimitry Andric 116*5f757f3fSDimitry Andric } // end of namespace llvm 117