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 bool expandVSPILL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 66 bool expandVRELOAD(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 67 }; 68 69 char RISCVExpandPseudo::ID = 0; 70 71 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 72 TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo()); 73 bool Modified = false; 74 for (auto &MBB : MF) 75 Modified |= expandMBB(MBB); 76 return Modified; 77 } 78 79 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 80 bool Modified = false; 81 82 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 83 while (MBBI != E) { 84 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 85 Modified |= expandMI(MBB, MBBI, NMBBI); 86 MBBI = NMBBI; 87 } 88 89 return Modified; 90 } 91 92 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, 93 MachineBasicBlock::iterator MBBI, 94 MachineBasicBlock::iterator &NextMBBI) { 95 // RISCVInstrInfo::getInstSizeInBytes hard-codes the number of expanded 96 // instructions for each pseudo, and must be updated when adding new pseudos 97 // or changing existing ones. 98 switch (MBBI->getOpcode()) { 99 case RISCV::PseudoLLA: 100 return expandLoadLocalAddress(MBB, MBBI, NextMBBI); 101 case RISCV::PseudoLA: 102 return expandLoadAddress(MBB, MBBI, NextMBBI); 103 case RISCV::PseudoLA_TLS_IE: 104 return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); 105 case RISCV::PseudoLA_TLS_GD: 106 return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); 107 case RISCV::PseudoVSETVLI: 108 case RISCV::PseudoVSETIVLI: 109 return expandVSetVL(MBB, MBBI); 110 case RISCV::PseudoVMCLR_M_B1: 111 case RISCV::PseudoVMCLR_M_B2: 112 case RISCV::PseudoVMCLR_M_B4: 113 case RISCV::PseudoVMCLR_M_B8: 114 case RISCV::PseudoVMCLR_M_B16: 115 case RISCV::PseudoVMCLR_M_B32: 116 case RISCV::PseudoVMCLR_M_B64: 117 // vmclr.m vd => vmxor.mm vd, vd, vd 118 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM); 119 case RISCV::PseudoVMSET_M_B1: 120 case RISCV::PseudoVMSET_M_B2: 121 case RISCV::PseudoVMSET_M_B4: 122 case RISCV::PseudoVMSET_M_B8: 123 case RISCV::PseudoVMSET_M_B16: 124 case RISCV::PseudoVMSET_M_B32: 125 case RISCV::PseudoVMSET_M_B64: 126 // vmset.m vd => vmxnor.mm vd, vd, vd 127 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM); 128 case RISCV::PseudoVSPILL2_M1: 129 case RISCV::PseudoVSPILL2_M2: 130 case RISCV::PseudoVSPILL2_M4: 131 case RISCV::PseudoVSPILL3_M1: 132 case RISCV::PseudoVSPILL3_M2: 133 case RISCV::PseudoVSPILL4_M1: 134 case RISCV::PseudoVSPILL4_M2: 135 case RISCV::PseudoVSPILL5_M1: 136 case RISCV::PseudoVSPILL6_M1: 137 case RISCV::PseudoVSPILL7_M1: 138 case RISCV::PseudoVSPILL8_M1: 139 return expandVSPILL(MBB, MBBI); 140 case RISCV::PseudoVRELOAD2_M1: 141 case RISCV::PseudoVRELOAD2_M2: 142 case RISCV::PseudoVRELOAD2_M4: 143 case RISCV::PseudoVRELOAD3_M1: 144 case RISCV::PseudoVRELOAD3_M2: 145 case RISCV::PseudoVRELOAD4_M1: 146 case RISCV::PseudoVRELOAD4_M2: 147 case RISCV::PseudoVRELOAD5_M1: 148 case RISCV::PseudoVRELOAD6_M1: 149 case RISCV::PseudoVRELOAD7_M1: 150 case RISCV::PseudoVRELOAD8_M1: 151 return expandVRELOAD(MBB, MBBI); 152 } 153 154 return false; 155 } 156 157 bool RISCVExpandPseudo::expandAuipcInstPair( 158 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 159 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 160 unsigned SecondOpcode) { 161 MachineFunction *MF = MBB.getParent(); 162 MachineInstr &MI = *MBBI; 163 DebugLoc DL = MI.getDebugLoc(); 164 165 Register DestReg = MI.getOperand(0).getReg(); 166 const MachineOperand &Symbol = MI.getOperand(1); 167 168 MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 169 170 // Tell AsmPrinter that we unconditionally want the symbol of this label to be 171 // emitted. 172 NewMBB->setLabelMustBeEmitted(); 173 174 MF->insert(++MBB.getIterator(), NewMBB); 175 176 BuildMI(NewMBB, DL, TII->get(RISCV::AUIPC), DestReg) 177 .addDisp(Symbol, 0, FlagsHi); 178 BuildMI(NewMBB, DL, TII->get(SecondOpcode), DestReg) 179 .addReg(DestReg) 180 .addMBB(NewMBB, RISCVII::MO_PCREL_LO); 181 182 // Move all the rest of the instructions to NewMBB. 183 NewMBB->splice(NewMBB->end(), &MBB, std::next(MBBI), MBB.end()); 184 // Update machine-CFG edges. 185 NewMBB->transferSuccessorsAndUpdatePHIs(&MBB); 186 // Make the original basic block fall-through to the new. 187 MBB.addSuccessor(NewMBB); 188 189 // Make sure live-ins are correctly attached to this new basic block. 190 LivePhysRegs LiveRegs; 191 computeAndAddLiveIns(LiveRegs, *NewMBB); 192 193 NextMBBI = MBB.end(); 194 MI.eraseFromParent(); 195 return true; 196 } 197 198 bool RISCVExpandPseudo::expandLoadLocalAddress( 199 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 200 MachineBasicBlock::iterator &NextMBBI) { 201 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, 202 RISCV::ADDI); 203 } 204 205 bool RISCVExpandPseudo::expandLoadAddress( 206 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 207 MachineBasicBlock::iterator &NextMBBI) { 208 MachineFunction *MF = MBB.getParent(); 209 210 unsigned SecondOpcode; 211 unsigned FlagsHi; 212 if (MF->getTarget().isPositionIndependent()) { 213 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 214 SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 215 FlagsHi = RISCVII::MO_GOT_HI; 216 } else { 217 SecondOpcode = RISCV::ADDI; 218 FlagsHi = RISCVII::MO_PCREL_HI; 219 } 220 return expandAuipcInstPair(MBB, MBBI, NextMBBI, FlagsHi, SecondOpcode); 221 } 222 223 bool RISCVExpandPseudo::expandLoadTLSIEAddress( 224 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 225 MachineBasicBlock::iterator &NextMBBI) { 226 MachineFunction *MF = MBB.getParent(); 227 228 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 229 unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 230 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI, 231 SecondOpcode); 232 } 233 234 bool RISCVExpandPseudo::expandLoadTLSGDAddress( 235 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 236 MachineBasicBlock::iterator &NextMBBI) { 237 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI, 238 RISCV::ADDI); 239 } 240 241 bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB, 242 MachineBasicBlock::iterator MBBI) { 243 assert(MBBI->getNumExplicitOperands() == 3 && MBBI->getNumOperands() >= 5 && 244 "Unexpected instruction format"); 245 246 DebugLoc DL = MBBI->getDebugLoc(); 247 248 assert((MBBI->getOpcode() == RISCV::PseudoVSETVLI || 249 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) && 250 "Unexpected pseudo instruction"); 251 unsigned Opcode; 252 if (MBBI->getOpcode() == RISCV::PseudoVSETVLI) 253 Opcode = RISCV::VSETVLI; 254 else 255 Opcode = RISCV::VSETIVLI; 256 const MCInstrDesc &Desc = TII->get(Opcode); 257 assert(Desc.getNumOperands() == 3 && "Unexpected instruction format"); 258 259 Register DstReg = MBBI->getOperand(0).getReg(); 260 bool DstIsDead = MBBI->getOperand(0).isDead(); 261 BuildMI(MBB, MBBI, DL, Desc) 262 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 263 .add(MBBI->getOperand(1)) // VL 264 .add(MBBI->getOperand(2)); // VType 265 266 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 267 return true; 268 } 269 270 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB, 271 MachineBasicBlock::iterator MBBI, 272 unsigned Opcode) { 273 DebugLoc DL = MBBI->getDebugLoc(); 274 Register DstReg = MBBI->getOperand(0).getReg(); 275 const MCInstrDesc &Desc = TII->get(Opcode); 276 BuildMI(MBB, MBBI, DL, Desc, DstReg) 277 .addReg(DstReg, RegState::Undef) 278 .addReg(DstReg, RegState::Undef); 279 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 280 return true; 281 } 282 283 bool RISCVExpandPseudo::expandVSPILL(MachineBasicBlock &MBB, 284 MachineBasicBlock::iterator MBBI) { 285 const TargetRegisterInfo *TRI = 286 MBB.getParent()->getSubtarget().getRegisterInfo(); 287 DebugLoc DL = MBBI->getDebugLoc(); 288 Register SrcReg = MBBI->getOperand(0).getReg(); 289 Register Base = MBBI->getOperand(1).getReg(); 290 Register VL = MBBI->getOperand(2).getReg(); 291 auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MBBI->getOpcode()); 292 if (!ZvlssegInfo) 293 return false; 294 unsigned NF = ZvlssegInfo->first; 295 unsigned LMUL = ZvlssegInfo->second; 296 assert(NF * LMUL <= 8 && "Invalid NF/LMUL combinations."); 297 unsigned Opcode = RISCV::VS1R_V; 298 unsigned SubRegIdx = RISCV::sub_vrm1_0; 299 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7, 300 "Unexpected subreg numbering"); 301 if (LMUL == 2) { 302 Opcode = RISCV::VS2R_V; 303 SubRegIdx = RISCV::sub_vrm2_0; 304 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3, 305 "Unexpected subreg numbering"); 306 } else if (LMUL == 4) { 307 Opcode = RISCV::VS4R_V; 308 SubRegIdx = RISCV::sub_vrm4_0; 309 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1, 310 "Unexpected subreg numbering"); 311 } else 312 assert(LMUL == 1 && "LMUL must be 1, 2, or 4."); 313 314 for (unsigned I = 0; I < NF; ++I) { 315 BuildMI(MBB, MBBI, DL, TII->get(Opcode)) 316 .addReg(TRI->getSubReg(SrcReg, SubRegIdx + I)) 317 .addReg(Base) 318 .addMemOperand(*(MBBI->memoperands_begin())); 319 if (I != NF - 1) 320 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), Base) 321 .addReg(Base) 322 .addReg(VL); 323 } 324 MBBI->eraseFromParent(); 325 return true; 326 } 327 328 bool RISCVExpandPseudo::expandVRELOAD(MachineBasicBlock &MBB, 329 MachineBasicBlock::iterator MBBI) { 330 const TargetRegisterInfo *TRI = 331 MBB.getParent()->getSubtarget().getRegisterInfo(); 332 DebugLoc DL = MBBI->getDebugLoc(); 333 Register DestReg = MBBI->getOperand(0).getReg(); 334 Register Base = MBBI->getOperand(1).getReg(); 335 Register VL = MBBI->getOperand(2).getReg(); 336 auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MBBI->getOpcode()); 337 if (!ZvlssegInfo) 338 return false; 339 unsigned NF = ZvlssegInfo->first; 340 unsigned LMUL = ZvlssegInfo->second; 341 assert(NF * LMUL <= 8 && "Invalid NF/LMUL combinations."); 342 unsigned Opcode = RISCV::VL1RE8_V; 343 unsigned SubRegIdx = RISCV::sub_vrm1_0; 344 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7, 345 "Unexpected subreg numbering"); 346 if (LMUL == 2) { 347 Opcode = RISCV::VL2RE8_V; 348 SubRegIdx = RISCV::sub_vrm2_0; 349 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3, 350 "Unexpected subreg numbering"); 351 } else if (LMUL == 4) { 352 Opcode = RISCV::VL4RE8_V; 353 SubRegIdx = RISCV::sub_vrm4_0; 354 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1, 355 "Unexpected subreg numbering"); 356 } else 357 assert(LMUL == 1 && "LMUL must be 1, 2, or 4."); 358 359 for (unsigned I = 0; I < NF; ++I) { 360 BuildMI(MBB, MBBI, DL, TII->get(Opcode), 361 TRI->getSubReg(DestReg, SubRegIdx + I)) 362 .addReg(Base) 363 .addMemOperand(*(MBBI->memoperands_begin())); 364 if (I != NF - 1) 365 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), Base) 366 .addReg(Base) 367 .addReg(VL); 368 } 369 MBBI->eraseFromParent(); 370 return true; 371 } 372 373 } // end of anonymous namespace 374 375 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", 376 RISCV_EXPAND_PSEUDO_NAME, false, false) 377 namespace llvm { 378 379 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } 380 381 } // end of namespace llvm 382