1 //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===// 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 pseudo instructions into target 10 // instructions. This pass should be run after register allocation but before 11 // the post-regalloc scheduling pass. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "RISCV.h" 16 #include "RISCVInstrInfo.h" 17 #include "RISCVTargetMachine.h" 18 19 #include "llvm/CodeGen/LivePhysRegs.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 23 using namespace llvm; 24 25 #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass" 26 27 namespace { 28 29 class RISCVExpandPseudo : public MachineFunctionPass { 30 public: 31 const RISCVInstrInfo *TII; 32 static char ID; 33 34 RISCVExpandPseudo() : MachineFunctionPass(ID) { 35 initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry()); 36 } 37 38 bool runOnMachineFunction(MachineFunction &MF) override; 39 40 StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; } 41 42 private: 43 bool expandMBB(MachineBasicBlock &MBB); 44 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 45 MachineBasicBlock::iterator &NextMBBI); 46 bool expandAuipcInstPair(MachineBasicBlock &MBB, 47 MachineBasicBlock::iterator MBBI, 48 MachineBasicBlock::iterator &NextMBBI, 49 unsigned FlagsHi, unsigned SecondOpcode); 50 bool expandLoadLocalAddress(MachineBasicBlock &MBB, 51 MachineBasicBlock::iterator MBBI, 52 MachineBasicBlock::iterator &NextMBBI); 53 bool expandLoadAddress(MachineBasicBlock &MBB, 54 MachineBasicBlock::iterator MBBI, 55 MachineBasicBlock::iterator &NextMBBI); 56 bool expandLoadTLSIEAddress(MachineBasicBlock &MBB, 57 MachineBasicBlock::iterator MBBI, 58 MachineBasicBlock::iterator &NextMBBI); 59 bool expandLoadTLSGDAddress(MachineBasicBlock &MBB, 60 MachineBasicBlock::iterator MBBI, 61 MachineBasicBlock::iterator &NextMBBI); 62 bool expandVSetVL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 63 bool expandVMSET_VMCLR(MachineBasicBlock &MBB, 64 MachineBasicBlock::iterator MBBI, unsigned Opcode); 65 }; 66 67 char RISCVExpandPseudo::ID = 0; 68 69 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 70 TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo()); 71 bool Modified = false; 72 for (auto &MBB : MF) 73 Modified |= expandMBB(MBB); 74 return Modified; 75 } 76 77 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 78 bool Modified = false; 79 80 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 81 while (MBBI != E) { 82 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 83 Modified |= expandMI(MBB, MBBI, NMBBI); 84 MBBI = NMBBI; 85 } 86 87 return Modified; 88 } 89 90 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, 91 MachineBasicBlock::iterator MBBI, 92 MachineBasicBlock::iterator &NextMBBI) { 93 // RISCVInstrInfo::getInstSizeInBytes hard-codes the number of expanded 94 // instructions for each pseudo, and must be updated when adding new pseudos 95 // or changing existing ones. 96 switch (MBBI->getOpcode()) { 97 case RISCV::PseudoLLA: 98 return expandLoadLocalAddress(MBB, MBBI, NextMBBI); 99 case RISCV::PseudoLA: 100 return expandLoadAddress(MBB, MBBI, NextMBBI); 101 case RISCV::PseudoLA_TLS_IE: 102 return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); 103 case RISCV::PseudoLA_TLS_GD: 104 return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); 105 case RISCV::PseudoVSETVLI: 106 return expandVSetVL(MBB, MBBI); 107 case RISCV::PseudoVMCLR_M_B1: 108 case RISCV::PseudoVMCLR_M_B2: 109 case RISCV::PseudoVMCLR_M_B4: 110 case RISCV::PseudoVMCLR_M_B8: 111 case RISCV::PseudoVMCLR_M_B16: 112 case RISCV::PseudoVMCLR_M_B32: 113 case RISCV::PseudoVMCLR_M_B64: 114 // vmclr.m vd => vmxor.mm vd, vd, vd 115 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM); 116 case RISCV::PseudoVMSET_M_B1: 117 case RISCV::PseudoVMSET_M_B2: 118 case RISCV::PseudoVMSET_M_B4: 119 case RISCV::PseudoVMSET_M_B8: 120 case RISCV::PseudoVMSET_M_B16: 121 case RISCV::PseudoVMSET_M_B32: 122 case RISCV::PseudoVMSET_M_B64: 123 // vmset.m vd => vmxnor.mm vd, vd, vd 124 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM); 125 } 126 127 return false; 128 } 129 130 bool RISCVExpandPseudo::expandAuipcInstPair( 131 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 132 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 133 unsigned SecondOpcode) { 134 MachineFunction *MF = MBB.getParent(); 135 MachineInstr &MI = *MBBI; 136 DebugLoc DL = MI.getDebugLoc(); 137 138 Register DestReg = MI.getOperand(0).getReg(); 139 const MachineOperand &Symbol = MI.getOperand(1); 140 141 MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 142 143 // Tell AsmPrinter that we unconditionally want the symbol of this label to be 144 // emitted. 145 NewMBB->setLabelMustBeEmitted(); 146 147 MF->insert(++MBB.getIterator(), NewMBB); 148 149 BuildMI(NewMBB, DL, TII->get(RISCV::AUIPC), DestReg) 150 .addDisp(Symbol, 0, FlagsHi); 151 BuildMI(NewMBB, DL, TII->get(SecondOpcode), DestReg) 152 .addReg(DestReg) 153 .addMBB(NewMBB, RISCVII::MO_PCREL_LO); 154 155 // Move all the rest of the instructions to NewMBB. 156 NewMBB->splice(NewMBB->end(), &MBB, std::next(MBBI), MBB.end()); 157 // Update machine-CFG edges. 158 NewMBB->transferSuccessorsAndUpdatePHIs(&MBB); 159 // Make the original basic block fall-through to the new. 160 MBB.addSuccessor(NewMBB); 161 162 // Make sure live-ins are correctly attached to this new basic block. 163 LivePhysRegs LiveRegs; 164 computeAndAddLiveIns(LiveRegs, *NewMBB); 165 166 NextMBBI = MBB.end(); 167 MI.eraseFromParent(); 168 return true; 169 } 170 171 bool RISCVExpandPseudo::expandLoadLocalAddress( 172 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 173 MachineBasicBlock::iterator &NextMBBI) { 174 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, 175 RISCV::ADDI); 176 } 177 178 bool RISCVExpandPseudo::expandLoadAddress( 179 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 180 MachineBasicBlock::iterator &NextMBBI) { 181 MachineFunction *MF = MBB.getParent(); 182 183 unsigned SecondOpcode; 184 unsigned FlagsHi; 185 if (MF->getTarget().isPositionIndependent()) { 186 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 187 SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 188 FlagsHi = RISCVII::MO_GOT_HI; 189 } else { 190 SecondOpcode = RISCV::ADDI; 191 FlagsHi = RISCVII::MO_PCREL_HI; 192 } 193 return expandAuipcInstPair(MBB, MBBI, NextMBBI, FlagsHi, SecondOpcode); 194 } 195 196 bool RISCVExpandPseudo::expandLoadTLSIEAddress( 197 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 198 MachineBasicBlock::iterator &NextMBBI) { 199 MachineFunction *MF = MBB.getParent(); 200 201 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 202 unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 203 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI, 204 SecondOpcode); 205 } 206 207 bool RISCVExpandPseudo::expandLoadTLSGDAddress( 208 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 209 MachineBasicBlock::iterator &NextMBBI) { 210 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI, 211 RISCV::ADDI); 212 } 213 214 bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB, 215 MachineBasicBlock::iterator MBBI) { 216 assert(MBBI->getNumOperands() == 5 && "Unexpected instruction format"); 217 218 DebugLoc DL = MBBI->getDebugLoc(); 219 220 assert(MBBI->getOpcode() == RISCV::PseudoVSETVLI && 221 "Unexpected pseudo instruction"); 222 const MCInstrDesc &Desc = TII->get(RISCV::VSETVLI); 223 assert(Desc.getNumOperands() == 3 && "Unexpected instruction format"); 224 225 Register DstReg = MBBI->getOperand(0).getReg(); 226 bool DstIsDead = MBBI->getOperand(0).isDead(); 227 BuildMI(MBB, MBBI, DL, Desc) 228 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 229 .add(MBBI->getOperand(1)) // VL 230 .add(MBBI->getOperand(2)); // VType 231 232 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 233 return true; 234 } 235 236 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB, 237 MachineBasicBlock::iterator MBBI, 238 unsigned Opcode) { 239 DebugLoc DL = MBBI->getDebugLoc(); 240 Register DstReg = MBBI->getOperand(0).getReg(); 241 const MCInstrDesc &Desc = TII->get(Opcode); 242 BuildMI(MBB, MBBI, DL, Desc, DstReg) 243 .addReg(DstReg, RegState::Undef) 244 .addReg(DstReg, RegState::Undef); 245 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 246 return true; 247 } 248 249 } // end of anonymous namespace 250 251 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", 252 RISCV_EXPAND_PSEUDO_NAME, false, false) 253 namespace llvm { 254 255 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } 256 257 } // end of namespace llvm 258