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