1 //===-- RISCVPostRAExpandPseudoInsts.cpp - Expand pseudo instrs ----===// 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 // 9 // This file contains a pass that expands the pseudo instruction pseudolisimm32 10 // into target instructions. This pass should be run during the post-regalloc 11 // passes, before post RA scheduling. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "RISCV.h" 16 #include "RISCVInstrInfo.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 20 using namespace llvm; 21 22 #define RISCV_POST_RA_EXPAND_PSEUDO_NAME \ 23 "RISC-V post-regalloc pseudo instruction expansion pass" 24 25 namespace { 26 27 class RISCVPostRAExpandPseudo : public MachineFunctionPass { 28 public: 29 const RISCVInstrInfo *TII; 30 static char ID; 31 32 RISCVPostRAExpandPseudo() : MachineFunctionPass(ID) {} 33 34 bool runOnMachineFunction(MachineFunction &MF) override; 35 36 StringRef getPassName() const override { 37 return RISCV_POST_RA_EXPAND_PSEUDO_NAME; 38 } 39 40 private: 41 bool expandMBB(MachineBasicBlock &MBB); 42 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 43 MachineBasicBlock::iterator &NextMBBI); 44 bool expandMovImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 45 bool expandMovAddr(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 46 }; 47 48 char RISCVPostRAExpandPseudo::ID = 0; 49 50 bool RISCVPostRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 51 TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo()); 52 bool Modified = false; 53 for (auto &MBB : MF) 54 Modified |= expandMBB(MBB); 55 return Modified; 56 } 57 58 bool RISCVPostRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 59 bool Modified = false; 60 61 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 62 while (MBBI != E) { 63 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 64 Modified |= expandMI(MBB, MBBI, NMBBI); 65 MBBI = NMBBI; 66 } 67 68 return Modified; 69 } 70 71 bool RISCVPostRAExpandPseudo::expandMI(MachineBasicBlock &MBB, 72 MachineBasicBlock::iterator MBBI, 73 MachineBasicBlock::iterator &NextMBBI) { 74 switch (MBBI->getOpcode()) { 75 case RISCV::PseudoMovImm: 76 return expandMovImm(MBB, MBBI); 77 case RISCV::PseudoMovAddr: 78 return expandMovAddr(MBB, MBBI); 79 default: 80 return false; 81 } 82 } 83 84 bool RISCVPostRAExpandPseudo::expandMovImm(MachineBasicBlock &MBB, 85 MachineBasicBlock::iterator MBBI) { 86 DebugLoc DL = MBBI->getDebugLoc(); 87 88 int64_t Val = MBBI->getOperand(1).getImm(); 89 90 Register DstReg = MBBI->getOperand(0).getReg(); 91 bool DstIsDead = MBBI->getOperand(0).isDead(); 92 bool Renamable = MBBI->getOperand(0).isRenamable(); 93 94 TII->movImm(MBB, MBBI, DL, DstReg, Val, MachineInstr::NoFlags, Renamable, 95 DstIsDead); 96 97 MBBI->eraseFromParent(); 98 return true; 99 } 100 101 bool RISCVPostRAExpandPseudo::expandMovAddr(MachineBasicBlock &MBB, 102 MachineBasicBlock::iterator MBBI) { 103 DebugLoc DL = MBBI->getDebugLoc(); 104 105 Register DstReg = MBBI->getOperand(0).getReg(); 106 bool DstIsDead = MBBI->getOperand(0).isDead(); 107 bool Renamable = MBBI->getOperand(0).isRenamable(); 108 109 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LUI)) 110 .addReg(DstReg, RegState::Define | getRenamableRegState(Renamable)) 111 .add(MBBI->getOperand(1)); 112 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI)) 113 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead) | 114 getRenamableRegState(Renamable)) 115 .addReg(DstReg, RegState::Kill | getRenamableRegState(Renamable)) 116 .add(MBBI->getOperand(2)); 117 MBBI->eraseFromParent(); 118 return true; 119 } 120 121 } // end of anonymous namespace 122 123 INITIALIZE_PASS(RISCVPostRAExpandPseudo, "riscv-post-ra-expand-pseudo", 124 RISCV_POST_RA_EXPAND_PSEUDO_NAME, false, false) 125 namespace llvm { 126 127 FunctionPass *createRISCVPostRAExpandPseudoPass() { 128 return new RISCVPostRAExpandPseudo(); 129 } 130 131 } // end of namespace llvm 132