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 #include "llvm/MC/MCContext.h" 23 24 using namespace llvm; 25 26 #define RISCV_EXPAND_PSEUDO_NAME "RISC-V pseudo instruction expansion pass" 27 #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISC-V Pre-RA pseudo instruction expansion pass" 28 29 namespace { 30 31 class RISCVExpandPseudo : public MachineFunctionPass { 32 public: 33 const RISCVSubtarget *STI; 34 const RISCVInstrInfo *TII; 35 static char ID; 36 37 RISCVExpandPseudo() : MachineFunctionPass(ID) { 38 initializeRISCVExpandPseudoPass(*PassRegistry::getPassRegistry()); 39 } 40 41 bool runOnMachineFunction(MachineFunction &MF) override; 42 43 StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; } 44 45 private: 46 bool expandMBB(MachineBasicBlock &MBB); 47 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 48 MachineBasicBlock::iterator &NextMBBI); 49 bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 50 MachineBasicBlock::iterator &NextMBBI); 51 bool expandVSetVL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 52 bool expandVMSET_VMCLR(MachineBasicBlock &MBB, 53 MachineBasicBlock::iterator MBBI, unsigned Opcode); 54 bool expandRV32ZdinxStore(MachineBasicBlock &MBB, 55 MachineBasicBlock::iterator MBBI); 56 bool expandRV32ZdinxLoad(MachineBasicBlock &MBB, 57 MachineBasicBlock::iterator MBBI); 58 #ifndef NDEBUG 59 unsigned getInstSizeInBytes(const MachineFunction &MF) const { 60 unsigned Size = 0; 61 for (auto &MBB : MF) 62 for (auto &MI : MBB) 63 Size += TII->getInstSizeInBytes(MI); 64 return Size; 65 } 66 #endif 67 }; 68 69 char RISCVExpandPseudo::ID = 0; 70 71 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 72 STI = &MF.getSubtarget<RISCVSubtarget>(); 73 TII = STI->getInstrInfo(); 74 75 #ifndef NDEBUG 76 const unsigned OldSize = getInstSizeInBytes(MF); 77 #endif 78 79 bool Modified = false; 80 for (auto &MBB : MF) 81 Modified |= expandMBB(MBB); 82 83 #ifndef NDEBUG 84 const unsigned NewSize = getInstSizeInBytes(MF); 85 assert(OldSize >= NewSize); 86 #endif 87 return Modified; 88 } 89 90 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 91 bool Modified = false; 92 93 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 94 while (MBBI != E) { 95 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 96 Modified |= expandMI(MBB, MBBI, NMBBI); 97 MBBI = NMBBI; 98 } 99 100 return Modified; 101 } 102 103 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, 104 MachineBasicBlock::iterator MBBI, 105 MachineBasicBlock::iterator &NextMBBI) { 106 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the 107 // expanded instructions for each pseudo is correct in the Size field of the 108 // tablegen definition for the pseudo. 109 switch (MBBI->getOpcode()) { 110 case RISCV::PseudoRV32ZdinxSD: 111 return expandRV32ZdinxStore(MBB, MBBI); 112 case RISCV::PseudoRV32ZdinxLD: 113 return expandRV32ZdinxLoad(MBB, MBBI); 114 case RISCV::PseudoCCMOVGPR: 115 case RISCV::PseudoCCADD: 116 case RISCV::PseudoCCSUB: 117 case RISCV::PseudoCCAND: 118 case RISCV::PseudoCCOR: 119 case RISCV::PseudoCCXOR: 120 case RISCV::PseudoCCADDW: 121 case RISCV::PseudoCCSUBW: 122 return expandCCOp(MBB, MBBI, NextMBBI); 123 case RISCV::PseudoVSETVLI: 124 case RISCV::PseudoVSETVLIX0: 125 case RISCV::PseudoVSETIVLI: 126 return expandVSetVL(MBB, MBBI); 127 case RISCV::PseudoVMCLR_M_B1: 128 case RISCV::PseudoVMCLR_M_B2: 129 case RISCV::PseudoVMCLR_M_B4: 130 case RISCV::PseudoVMCLR_M_B8: 131 case RISCV::PseudoVMCLR_M_B16: 132 case RISCV::PseudoVMCLR_M_B32: 133 case RISCV::PseudoVMCLR_M_B64: 134 // vmclr.m vd => vmxor.mm vd, vd, vd 135 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM); 136 case RISCV::PseudoVMSET_M_B1: 137 case RISCV::PseudoVMSET_M_B2: 138 case RISCV::PseudoVMSET_M_B4: 139 case RISCV::PseudoVMSET_M_B8: 140 case RISCV::PseudoVMSET_M_B16: 141 case RISCV::PseudoVMSET_M_B32: 142 case RISCV::PseudoVMSET_M_B64: 143 // vmset.m vd => vmxnor.mm vd, vd, vd 144 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM); 145 } 146 147 return false; 148 } 149 150 bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB, 151 MachineBasicBlock::iterator MBBI, 152 MachineBasicBlock::iterator &NextMBBI) { 153 154 MachineFunction *MF = MBB.getParent(); 155 MachineInstr &MI = *MBBI; 156 DebugLoc DL = MI.getDebugLoc(); 157 158 MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 159 MachineBasicBlock *MergeBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 160 161 MF->insert(++MBB.getIterator(), TrueBB); 162 MF->insert(++TrueBB->getIterator(), MergeBB); 163 164 // We want to copy the "true" value when the condition is true which means 165 // we need to invert the branch condition to jump over TrueBB when the 166 // condition is false. 167 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm()); 168 CC = RISCVCC::getOppositeBranchCondition(CC); 169 170 // Insert branch instruction. 171 BuildMI(MBB, MBBI, DL, TII->getBrCond(CC)) 172 .addReg(MI.getOperand(1).getReg()) 173 .addReg(MI.getOperand(2).getReg()) 174 .addMBB(MergeBB); 175 176 Register DestReg = MI.getOperand(0).getReg(); 177 assert(MI.getOperand(4).getReg() == DestReg); 178 179 if (MI.getOpcode() == RISCV::PseudoCCMOVGPR) { 180 // Add MV. 181 BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg) 182 .add(MI.getOperand(5)) 183 .addImm(0); 184 } else { 185 unsigned NewOpc; 186 switch (MI.getOpcode()) { 187 default: 188 llvm_unreachable("Unexpected opcode!"); 189 case RISCV::PseudoCCADD: NewOpc = RISCV::ADD; break; 190 case RISCV::PseudoCCSUB: NewOpc = RISCV::SUB; break; 191 case RISCV::PseudoCCAND: NewOpc = RISCV::AND; break; 192 case RISCV::PseudoCCOR: NewOpc = RISCV::OR; break; 193 case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR; break; 194 case RISCV::PseudoCCADDW: NewOpc = RISCV::ADDW; break; 195 case RISCV::PseudoCCSUBW: NewOpc = RISCV::SUBW; break; 196 } 197 BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg) 198 .add(MI.getOperand(5)) 199 .add(MI.getOperand(6)); 200 } 201 202 TrueBB->addSuccessor(MergeBB); 203 204 MergeBB->splice(MergeBB->end(), &MBB, MI, MBB.end()); 205 MergeBB->transferSuccessors(&MBB); 206 207 MBB.addSuccessor(TrueBB); 208 MBB.addSuccessor(MergeBB); 209 210 NextMBBI = MBB.end(); 211 MI.eraseFromParent(); 212 213 // Make sure live-ins are correctly attached to this new basic block. 214 LivePhysRegs LiveRegs; 215 computeAndAddLiveIns(LiveRegs, *TrueBB); 216 computeAndAddLiveIns(LiveRegs, *MergeBB); 217 218 return true; 219 } 220 221 bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB, 222 MachineBasicBlock::iterator MBBI) { 223 assert(MBBI->getNumExplicitOperands() == 3 && MBBI->getNumOperands() >= 5 && 224 "Unexpected instruction format"); 225 226 DebugLoc DL = MBBI->getDebugLoc(); 227 228 assert((MBBI->getOpcode() == RISCV::PseudoVSETVLI || 229 MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 || 230 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) && 231 "Unexpected pseudo instruction"); 232 unsigned Opcode; 233 if (MBBI->getOpcode() == RISCV::PseudoVSETIVLI) 234 Opcode = RISCV::VSETIVLI; 235 else 236 Opcode = RISCV::VSETVLI; 237 const MCInstrDesc &Desc = TII->get(Opcode); 238 assert(Desc.getNumOperands() == 3 && "Unexpected instruction format"); 239 240 Register DstReg = MBBI->getOperand(0).getReg(); 241 bool DstIsDead = MBBI->getOperand(0).isDead(); 242 BuildMI(MBB, MBBI, DL, Desc) 243 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 244 .add(MBBI->getOperand(1)) // VL 245 .add(MBBI->getOperand(2)); // VType 246 247 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 248 return true; 249 } 250 251 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB, 252 MachineBasicBlock::iterator MBBI, 253 unsigned Opcode) { 254 DebugLoc DL = MBBI->getDebugLoc(); 255 Register DstReg = MBBI->getOperand(0).getReg(); 256 const MCInstrDesc &Desc = TII->get(Opcode); 257 BuildMI(MBB, MBBI, DL, Desc, DstReg) 258 .addReg(DstReg, RegState::Undef) 259 .addReg(DstReg, RegState::Undef); 260 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 261 return true; 262 } 263 264 // This function expands the PseudoRV32ZdinxSD for storing a double-precision 265 // floating-point value into memory by generating an equivalent instruction 266 // sequence for RV32. 267 bool RISCVExpandPseudo::expandRV32ZdinxStore(MachineBasicBlock &MBB, 268 MachineBasicBlock::iterator MBBI) { 269 DebugLoc DL = MBBI->getDebugLoc(); 270 const TargetRegisterInfo *TRI = STI->getRegisterInfo(); 271 Register Lo = TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_32); 272 Register Hi = TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_32_hi); 273 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 274 .addReg(Lo, getKillRegState(MBBI->getOperand(0).isKill())) 275 .addReg(MBBI->getOperand(1).getReg()) 276 .add(MBBI->getOperand(2)); 277 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 278 // FIXME: Zdinx RV32 can not work on unaligned scalar memory. 279 assert(!STI->enableUnalignedScalarMem()); 280 281 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 282 MBBI->getOperand(2).setOffset(MBBI->getOperand(2).getOffset() + 4); 283 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 284 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 285 .add(MBBI->getOperand(1)) 286 .add(MBBI->getOperand(2)); 287 } else { 288 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 289 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 290 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 291 .add(MBBI->getOperand(1)) 292 .addImm(MBBI->getOperand(2).getImm() + 4); 293 } 294 MBBI->eraseFromParent(); 295 return true; 296 } 297 298 // This function expands PseudoRV32ZdinxLoad for loading a double-precision 299 // floating-point value from memory into an equivalent instruction sequence for 300 // RV32. 301 bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock &MBB, 302 MachineBasicBlock::iterator MBBI) { 303 DebugLoc DL = MBBI->getDebugLoc(); 304 const TargetRegisterInfo *TRI = STI->getRegisterInfo(); 305 Register Lo = TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_32); 306 Register Hi = TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_32_hi); 307 308 // If the register of operand 1 is equal to the Lo register, then swap the 309 // order of loading the Lo and Hi statements. 310 bool IsOp1EqualToLo = Lo == MBBI->getOperand(1).getReg(); 311 // Order: Lo, Hi 312 if (!IsOp1EqualToLo) { 313 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 314 .addReg(MBBI->getOperand(1).getReg()) 315 .add(MBBI->getOperand(2)); 316 } 317 318 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 319 auto Offset = MBBI->getOperand(2).getOffset(); 320 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 321 MBBI->getOperand(2).setOffset(Offset + 4); 322 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 323 .addReg(MBBI->getOperand(1).getReg()) 324 .add(MBBI->getOperand(2)); 325 MBBI->getOperand(2).setOffset(Offset); 326 } else { 327 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 328 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 329 .addReg(MBBI->getOperand(1).getReg()) 330 .addImm(MBBI->getOperand(2).getImm() + 4); 331 } 332 333 // Order: Hi, Lo 334 if (IsOp1EqualToLo) { 335 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 336 .addReg(MBBI->getOperand(1).getReg()) 337 .add(MBBI->getOperand(2)); 338 } 339 340 MBBI->eraseFromParent(); 341 return true; 342 } 343 344 class RISCVPreRAExpandPseudo : public MachineFunctionPass { 345 public: 346 const RISCVSubtarget *STI; 347 const RISCVInstrInfo *TII; 348 static char ID; 349 350 RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) { 351 initializeRISCVPreRAExpandPseudoPass(*PassRegistry::getPassRegistry()); 352 } 353 354 bool runOnMachineFunction(MachineFunction &MF) override; 355 356 void getAnalysisUsage(AnalysisUsage &AU) const override { 357 AU.setPreservesCFG(); 358 MachineFunctionPass::getAnalysisUsage(AU); 359 } 360 StringRef getPassName() const override { 361 return RISCV_PRERA_EXPAND_PSEUDO_NAME; 362 } 363 364 private: 365 bool expandMBB(MachineBasicBlock &MBB); 366 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 367 MachineBasicBlock::iterator &NextMBBI); 368 bool expandAuipcInstPair(MachineBasicBlock &MBB, 369 MachineBasicBlock::iterator MBBI, 370 MachineBasicBlock::iterator &NextMBBI, 371 unsigned FlagsHi, unsigned SecondOpcode); 372 bool expandLoadLocalAddress(MachineBasicBlock &MBB, 373 MachineBasicBlock::iterator MBBI, 374 MachineBasicBlock::iterator &NextMBBI); 375 bool expandLoadGlobalAddress(MachineBasicBlock &MBB, 376 MachineBasicBlock::iterator MBBI, 377 MachineBasicBlock::iterator &NextMBBI); 378 bool expandLoadTLSIEAddress(MachineBasicBlock &MBB, 379 MachineBasicBlock::iterator MBBI, 380 MachineBasicBlock::iterator &NextMBBI); 381 bool expandLoadTLSGDAddress(MachineBasicBlock &MBB, 382 MachineBasicBlock::iterator MBBI, 383 MachineBasicBlock::iterator &NextMBBI); 384 #ifndef NDEBUG 385 unsigned getInstSizeInBytes(const MachineFunction &MF) const { 386 unsigned Size = 0; 387 for (auto &MBB : MF) 388 for (auto &MI : MBB) 389 Size += TII->getInstSizeInBytes(MI); 390 return Size; 391 } 392 #endif 393 }; 394 395 char RISCVPreRAExpandPseudo::ID = 0; 396 397 bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 398 STI = &MF.getSubtarget<RISCVSubtarget>(); 399 TII = STI->getInstrInfo(); 400 401 #ifndef NDEBUG 402 const unsigned OldSize = getInstSizeInBytes(MF); 403 #endif 404 405 bool Modified = false; 406 for (auto &MBB : MF) 407 Modified |= expandMBB(MBB); 408 409 #ifndef NDEBUG 410 const unsigned NewSize = getInstSizeInBytes(MF); 411 assert(OldSize >= NewSize); 412 #endif 413 return Modified; 414 } 415 416 bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 417 bool Modified = false; 418 419 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 420 while (MBBI != E) { 421 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 422 Modified |= expandMI(MBB, MBBI, NMBBI); 423 MBBI = NMBBI; 424 } 425 426 return Modified; 427 } 428 429 bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB, 430 MachineBasicBlock::iterator MBBI, 431 MachineBasicBlock::iterator &NextMBBI) { 432 433 switch (MBBI->getOpcode()) { 434 case RISCV::PseudoLLA: 435 return expandLoadLocalAddress(MBB, MBBI, NextMBBI); 436 case RISCV::PseudoLGA: 437 return expandLoadGlobalAddress(MBB, MBBI, NextMBBI); 438 case RISCV::PseudoLA_TLS_IE: 439 return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); 440 case RISCV::PseudoLA_TLS_GD: 441 return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); 442 } 443 return false; 444 } 445 446 bool RISCVPreRAExpandPseudo::expandAuipcInstPair( 447 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 448 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 449 unsigned SecondOpcode) { 450 MachineFunction *MF = MBB.getParent(); 451 MachineInstr &MI = *MBBI; 452 DebugLoc DL = MI.getDebugLoc(); 453 454 Register DestReg = MI.getOperand(0).getReg(); 455 Register ScratchReg = 456 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 457 458 MachineOperand &Symbol = MI.getOperand(1); 459 Symbol.setTargetFlags(FlagsHi); 460 MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi"); 461 462 MachineInstr *MIAUIPC = 463 BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); 464 MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); 465 466 MachineInstr *SecondMI = 467 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 468 .addReg(ScratchReg) 469 .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO); 470 471 if (MI.hasOneMemOperand()) 472 SecondMI->addMemOperand(*MF, *MI.memoperands_begin()); 473 474 MI.eraseFromParent(); 475 return true; 476 } 477 478 bool RISCVPreRAExpandPseudo::expandLoadLocalAddress( 479 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 480 MachineBasicBlock::iterator &NextMBBI) { 481 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, 482 RISCV::ADDI); 483 } 484 485 bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress( 486 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 487 MachineBasicBlock::iterator &NextMBBI) { 488 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 489 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI, 490 SecondOpcode); 491 } 492 493 bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress( 494 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 495 MachineBasicBlock::iterator &NextMBBI) { 496 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 497 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI, 498 SecondOpcode); 499 } 500 501 bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress( 502 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 503 MachineBasicBlock::iterator &NextMBBI) { 504 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI, 505 RISCV::ADDI); 506 } 507 508 } // end of anonymous namespace 509 510 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", 511 RISCV_EXPAND_PSEUDO_NAME, false, false) 512 513 INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo", 514 RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false) 515 516 namespace llvm { 517 518 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } 519 FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); } 520 521 } // end of namespace llvm 522