1 //===- RISCVInsertVSETVLI.cpp - Insert VSETVLI 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 implements a function pass that inserts VSETVLI instructions where 10 // needed. 11 // 12 // This pass consists of 3 phases: 13 // 14 // Phase 1 collects how each basic block affects VL/VTYPE. 15 // 16 // Phase 2 uses the information from phase 1 to do a data flow analysis to 17 // propagate the VL/VTYPE changes through the function. This gives us the 18 // VL/VTYPE at the start of each basic block. 19 // 20 // Phase 3 inserts VSETVLI instructions in each basic block. Information from 21 // phase 2 is used to prevent inserting a VSETVLI before the first vector 22 // instruction in the block if possible. 23 // 24 //===----------------------------------------------------------------------===// 25 26 #include "RISCV.h" 27 #include "RISCVSubtarget.h" 28 #include "llvm/CodeGen/LiveIntervals.h" 29 #include "llvm/CodeGen/MachineFunctionPass.h" 30 #include <queue> 31 using namespace llvm; 32 33 #define DEBUG_TYPE "riscv-insert-vsetvli" 34 #define RISCV_INSERT_VSETVLI_NAME "RISCV Insert VSETVLI pass" 35 36 static cl::opt<bool> DisableInsertVSETVLPHIOpt( 37 "riscv-disable-insert-vsetvl-phi-opt", cl::init(false), cl::Hidden, 38 cl::desc("Disable looking through phis when inserting vsetvlis.")); 39 40 namespace { 41 42 class VSETVLIInfo { 43 union { 44 Register AVLReg; 45 unsigned AVLImm; 46 }; 47 48 enum : uint8_t { 49 Uninitialized, 50 AVLIsReg, 51 AVLIsImm, 52 Unknown, 53 } State = Uninitialized; 54 55 // Fields from VTYPE. 56 RISCVII::VLMUL VLMul = RISCVII::LMUL_1; 57 uint8_t SEW = 0; 58 uint8_t TailAgnostic : 1; 59 uint8_t MaskAgnostic : 1; 60 uint8_t MaskRegOp : 1; 61 62 public: 63 VSETVLIInfo() 64 : AVLImm(0), TailAgnostic(false), MaskAgnostic(false), MaskRegOp(false) {} 65 66 static VSETVLIInfo getUnknown() { 67 VSETVLIInfo Info; 68 Info.setUnknown(); 69 return Info; 70 } 71 72 bool isValid() const { return State != Uninitialized; } 73 void setUnknown() { State = Unknown; } 74 bool isUnknown() const { return State == Unknown; } 75 76 void setAVLReg(Register Reg) { 77 AVLReg = Reg; 78 State = AVLIsReg; 79 } 80 81 void setAVLImm(unsigned Imm) { 82 AVLImm = Imm; 83 State = AVLIsImm; 84 } 85 86 bool hasAVLImm() const { return State == AVLIsImm; } 87 bool hasAVLReg() const { return State == AVLIsReg; } 88 Register getAVLReg() const { 89 assert(hasAVLReg()); 90 return AVLReg; 91 } 92 unsigned getAVLImm() const { 93 assert(hasAVLImm()); 94 return AVLImm; 95 } 96 97 bool hasSameAVL(const VSETVLIInfo &Other) const { 98 assert(isValid() && Other.isValid() && 99 "Can't compare invalid VSETVLIInfos"); 100 assert(!isUnknown() && !Other.isUnknown() && 101 "Can't compare AVL in unknown state"); 102 if (hasAVLReg() && Other.hasAVLReg()) 103 return getAVLReg() == Other.getAVLReg(); 104 105 if (hasAVLImm() && Other.hasAVLImm()) 106 return getAVLImm() == Other.getAVLImm(); 107 108 return false; 109 } 110 111 void setVTYPE(unsigned VType) { 112 assert(isValid() && !isUnknown() && 113 "Can't set VTYPE for uninitialized or unknown"); 114 VLMul = RISCVVType::getVLMUL(VType); 115 SEW = RISCVVType::getSEW(VType); 116 TailAgnostic = RISCVVType::isTailAgnostic(VType); 117 MaskAgnostic = RISCVVType::isMaskAgnostic(VType); 118 } 119 void setVTYPE(RISCVII::VLMUL L, unsigned S, bool TA, bool MA, bool MRO) { 120 assert(isValid() && !isUnknown() && 121 "Can't set VTYPE for uninitialized or unknown"); 122 VLMul = L; 123 SEW = S; 124 TailAgnostic = TA; 125 MaskAgnostic = MA; 126 MaskRegOp = MRO; 127 } 128 129 unsigned encodeVTYPE() const { 130 assert(isValid() && !isUnknown() && 131 "Can't encode VTYPE for uninitialized or unknown"); 132 return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic); 133 } 134 135 bool hasSameVTYPE(const VSETVLIInfo &Other) const { 136 assert(isValid() && Other.isValid() && 137 "Can't compare invalid VSETVLIInfos"); 138 assert(!isUnknown() && !Other.isUnknown() && 139 "Can't compare VTYPE in unknown state"); 140 return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) == 141 std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic, 142 Other.MaskAgnostic); 143 } 144 145 // Convert VLMUL to a fixed point value with 3 bits of fraction. 146 unsigned getSEWLMULRatio() const { 147 assert(isValid() && !isUnknown() && 148 "Can't use VTYPE for uninitialized or unknown"); 149 unsigned LMul; 150 bool Fractional; 151 std::tie(LMul, Fractional) = RISCVVType::decodeVLMUL(VLMul); 152 153 // Convert LMul to a fixed point value with 3 fractional bits. 154 LMul = Fractional ? (8 / LMul) : (LMul * 8); 155 156 assert(SEW >= 8 && "Unexpected SEW value"); 157 return (SEW * 8) / LMul; 158 } 159 160 // Check if the VTYPE for these two VSETVLIInfos produce the same VLMAX. 161 bool hasSameVLMAX(const VSETVLIInfo &Other) const { 162 assert(isValid() && Other.isValid() && 163 "Can't compare invalid VSETVLIInfos"); 164 assert(!isUnknown() && !Other.isUnknown() && 165 "Can't compare VTYPE in unknown state"); 166 return getSEWLMULRatio() == Other.getSEWLMULRatio(); 167 } 168 169 // Determine whether the vector instructions requirements represented by 170 // InstrInfo are compatible with the previous vsetvli instruction represented 171 // by this. 172 bool isCompatible(const VSETVLIInfo &InstrInfo) const { 173 assert(isValid() && InstrInfo.isValid() && 174 "Can't compare invalid VSETVLIInfos"); 175 // Nothing is compatible with Unknown. 176 if (isUnknown() || InstrInfo.isUnknown()) 177 return false; 178 179 // If the instruction doesn't need an AVLReg and the SEW matches, consider 180 // it/ compatible. 181 if (InstrInfo.hasAVLReg() && InstrInfo.AVLReg == RISCV::NoRegister) { 182 if (SEW == InstrInfo.SEW) 183 return true; 184 } 185 186 // VTypes must match unless the instruction is a mask reg operation, then it 187 // only care about VLMAX. 188 // FIXME: Mask reg operations are probably ok if "this" VLMAX is larger 189 // than "InstrInfo". 190 if (!hasSameVTYPE(InstrInfo) && 191 !(InstrInfo.MaskRegOp && hasSameVLMAX(InstrInfo) && 192 TailAgnostic == InstrInfo.TailAgnostic && 193 MaskAgnostic == InstrInfo.MaskAgnostic)) 194 return false; 195 196 return hasSameAVL(InstrInfo); 197 } 198 199 bool operator==(const VSETVLIInfo &Other) const { 200 // Uninitialized is only equal to another Uninitialized. 201 if (!isValid()) 202 return !Other.isValid(); 203 if (!Other.isValid()) 204 return !isValid(); 205 206 // Unknown is only equal to another Unknown. 207 if (isUnknown()) 208 return Other.isUnknown(); 209 if (Other.isUnknown()) 210 return isUnknown(); 211 212 // Otherwise compare the VTYPE and AVL. 213 return hasSameVTYPE(Other) && hasSameAVL(Other); 214 } 215 216 // Calculate the VSETVLIInfo visible to a block assuming this and Other are 217 // both predecessors. 218 VSETVLIInfo intersect(const VSETVLIInfo &Other) const { 219 // If the new value isn't valid, ignore it. 220 if (!Other.isValid()) 221 return *this; 222 223 // If this value isn't valid, this must be the first predecessor, use it. 224 if (!isValid()) 225 return Other; 226 227 if (*this == Other) 228 return *this; 229 230 // If the configurations don't match, assume unknown. 231 return VSETVLIInfo::getUnknown(); 232 } 233 234 // Calculate the VSETVLIInfo visible at the end of the block assuming this 235 // is the predecessor value, and Other is change for this block. 236 VSETVLIInfo merge(const VSETVLIInfo &Other) const { 237 assert(isValid() && "Can only merge with a valid VSETVLInfo"); 238 239 // Nothing changed from the predecessor, keep it. 240 if (!Other.isValid()) 241 return *this; 242 243 // If the change is compatible with the input, we won't create a VSETVLI 244 // and should keep the predecessor. 245 if (isCompatible(Other)) 246 return *this; 247 248 // Otherwise just use whatever is in this block. 249 return Other; 250 } 251 }; 252 253 struct BlockData { 254 // The VSETVLIInfo that represents the net changes to the VL/VTYPE registers 255 // made by this block. Calculated in Phase 1. 256 VSETVLIInfo Change; 257 258 // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this 259 // block. Calculated in Phase 2. 260 VSETVLIInfo Exit; 261 262 // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor 263 // blocks. Calculated in Phase 2, and used by Phase 3. 264 VSETVLIInfo Pred; 265 266 // Keeps track of whether the block is already in the queue. 267 bool InQueue = false; 268 269 BlockData() {} 270 }; 271 272 class RISCVInsertVSETVLI : public MachineFunctionPass { 273 const TargetInstrInfo *TII; 274 MachineRegisterInfo *MRI; 275 276 std::vector<BlockData> BlockInfo; 277 std::queue<const MachineBasicBlock *> WorkList; 278 279 public: 280 static char ID; 281 282 RISCVInsertVSETVLI() : MachineFunctionPass(ID) { 283 initializeRISCVInsertVSETVLIPass(*PassRegistry::getPassRegistry()); 284 } 285 bool runOnMachineFunction(MachineFunction &MF) override; 286 287 void getAnalysisUsage(AnalysisUsage &AU) const override { 288 AU.setPreservesCFG(); 289 MachineFunctionPass::getAnalysisUsage(AU); 290 } 291 292 StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; } 293 294 private: 295 bool needVSETVLI(const VSETVLIInfo &Require, const VSETVLIInfo &CurInfo); 296 bool needVSETVLIPHI(const VSETVLIInfo &Require, const MachineBasicBlock &MBB); 297 void insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 298 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo); 299 300 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB); 301 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); 302 void emitVSETVLIs(MachineBasicBlock &MBB); 303 }; 304 305 } // end anonymous namespace 306 307 char RISCVInsertVSETVLI::ID = 0; 308 309 INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME, 310 false, false) 311 312 static MachineInstr *elideCopies(MachineInstr *MI, 313 const MachineRegisterInfo *MRI) { 314 while (true) { 315 if (!MI->isFullCopy()) 316 return MI; 317 if (!Register::isVirtualRegister(MI->getOperand(1).getReg())) 318 return nullptr; 319 MI = MRI->getVRegDef(MI->getOperand(1).getReg()); 320 if (!MI) 321 return nullptr; 322 } 323 } 324 325 static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, 326 const MachineRegisterInfo *MRI) { 327 VSETVLIInfo InstrInfo; 328 unsigned NumOperands = MI.getNumExplicitOperands(); 329 330 RISCVII::VLMUL VLMul = RISCVII::getLMul(TSFlags); 331 332 unsigned Log2SEW = MI.getOperand(NumOperands - 1).getImm(); 333 // A Log2SEW of 0 is an operation on mask registers only. 334 bool MaskRegOp = Log2SEW == 0; 335 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8; 336 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW"); 337 338 // Default to tail agnostic unless the destination is tied to a source. 339 // Unless the source is undef. In that case the user would have some control 340 // over the tail values. The tail policy is also ignored on instructions 341 // that only update element 0 like vmv.s.x or reductions so use agnostic 342 // there to match the common case. 343 // FIXME: This is conservatively correct, but we might want to detect that 344 // the input is undefined. 345 bool ForceTailAgnostic = RISCVII::doesForceTailAgnostic(TSFlags); 346 bool TailAgnostic = true; 347 unsigned UseOpIdx; 348 if (!ForceTailAgnostic && MI.isRegTiedToUseOperand(0, &UseOpIdx)) { 349 TailAgnostic = false; 350 // If the tied operand is an IMPLICIT_DEF we can keep TailAgnostic. 351 const MachineOperand &UseMO = MI.getOperand(UseOpIdx); 352 MachineInstr *UseMI = MRI->getVRegDef(UseMO.getReg()); 353 if (UseMI) { 354 UseMI = elideCopies(UseMI, MRI); 355 if (UseMI && UseMI->isImplicitDef()) 356 TailAgnostic = true; 357 } 358 } 359 360 if (RISCVII::hasVLOp(TSFlags)) { 361 const MachineOperand &VLOp = MI.getOperand(MI.getNumExplicitOperands() - 2); 362 if (VLOp.isImm()) 363 InstrInfo.setAVLImm(VLOp.getImm()); 364 else 365 InstrInfo.setAVLReg(VLOp.getReg()); 366 } else 367 InstrInfo.setAVLReg(RISCV::NoRegister); 368 InstrInfo.setVTYPE(VLMul, SEW, /*TailAgnostic*/ TailAgnostic, 369 /*MaskAgnostic*/ false, MaskRegOp); 370 371 return InstrInfo; 372 } 373 374 void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 375 const VSETVLIInfo &Info, 376 const VSETVLIInfo &PrevInfo) { 377 DebugLoc DL = MI.getDebugLoc(); 378 379 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same 380 // VLMAX. 381 if (PrevInfo.isValid() && !PrevInfo.isUnknown() && 382 Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) { 383 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI)) 384 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 385 .addReg(RISCV::X0, RegState::Kill) 386 .addImm(Info.encodeVTYPE()) 387 .addReg(RISCV::VL, RegState::Implicit); 388 return; 389 } 390 391 if (Info.hasAVLImm()) { 392 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETIVLI)) 393 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 394 .addImm(Info.getAVLImm()) 395 .addImm(Info.encodeVTYPE()); 396 return; 397 } 398 399 Register AVLReg = Info.getAVLReg(); 400 if (AVLReg == RISCV::NoRegister) { 401 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI)) 402 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 403 .addReg(RISCV::X0, RegState::Kill) 404 .addImm(Info.encodeVTYPE()) 405 .addReg(RISCV::VL, RegState::Implicit); 406 return; 407 } 408 409 // Use X0 as the DestReg unless AVLReg is X0. 410 Register DestReg = RISCV::X0; 411 if (AVLReg == RISCV::X0) 412 DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 413 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI)) 414 .addReg(DestReg, RegState::Define | RegState::Dead) 415 .addReg(AVLReg) 416 .addImm(Info.encodeVTYPE()); 417 } 418 419 // Return a VSETVLIInfo representing the changes made by this VSETVLI or 420 // VSETIVLI instruction. 421 static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) { 422 VSETVLIInfo NewInfo; 423 if (MI.getOpcode() == RISCV::PseudoVSETVLI) { 424 Register AVLReg = MI.getOperand(1).getReg(); 425 assert((AVLReg != RISCV::X0 || MI.getOperand(0).getReg() != RISCV::X0) && 426 "Can't handle X0, X0 vsetvli yet"); 427 NewInfo.setAVLReg(AVLReg); 428 } else { 429 assert(MI.getOpcode() == RISCV::PseudoVSETIVLI); 430 NewInfo.setAVLImm(MI.getOperand(1).getImm()); 431 } 432 NewInfo.setVTYPE(MI.getOperand(2).getImm()); 433 434 return NewInfo; 435 } 436 437 bool RISCVInsertVSETVLI::needVSETVLI(const VSETVLIInfo &Require, 438 const VSETVLIInfo &CurInfo) { 439 if (CurInfo.isCompatible(Require)) 440 return false; 441 442 // We didn't find a compatible value. If our AVL is a virtual register, 443 // it might be defined by a VSET(I)VLI. If it has the same VTYPE we need 444 // and the last VL/VTYPE we observed is the same, we don't need a 445 // VSETVLI here. 446 if (!CurInfo.isUnknown() && Require.hasAVLReg() && 447 Require.getAVLReg().isVirtual() && Require.hasSameVTYPE(CurInfo)) { 448 if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { 449 if (DefMI->getOpcode() == RISCV::PseudoVSETVLI || 450 DefMI->getOpcode() == RISCV::PseudoVSETIVLI) { 451 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 452 if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVTYPE(CurInfo)) 453 return false; 454 } 455 } 456 } 457 458 return true; 459 } 460 461 bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB) { 462 bool HadVectorOp = false; 463 464 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 465 for (const MachineInstr &MI : MBB) { 466 // If this is an explicit VSETVLI or VSETIVLI, update our state. 467 if (MI.getOpcode() == RISCV::PseudoVSETVLI || 468 MI.getOpcode() == RISCV::PseudoVSETIVLI) { 469 HadVectorOp = true; 470 BBInfo.Change = getInfoForVSETVLI(MI); 471 continue; 472 } 473 474 uint64_t TSFlags = MI.getDesc().TSFlags; 475 if (RISCVII::hasSEWOp(TSFlags)) { 476 HadVectorOp = true; 477 478 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 479 480 if (!BBInfo.Change.isValid()) { 481 BBInfo.Change = NewInfo; 482 } else { 483 // If this instruction isn't compatible with the previous VL/VTYPE 484 // we need to insert a VSETVLI. 485 if (needVSETVLI(NewInfo, BBInfo.Change)) 486 BBInfo.Change = NewInfo; 487 } 488 } 489 490 // If this is something that updates VL/VTYPE that we don't know about, set 491 // the state to unknown. 492 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 493 MI.modifiesRegister(RISCV::VTYPE)) { 494 BBInfo.Change = VSETVLIInfo::getUnknown(); 495 } 496 } 497 498 // Initial exit state is whatever change we found in the block. 499 BBInfo.Exit = BBInfo.Change; 500 501 return HadVectorOp; 502 } 503 504 void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) { 505 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 506 507 BBInfo.InQueue = false; 508 509 VSETVLIInfo InInfo; 510 if (MBB.pred_empty()) { 511 // There are no predecessors, so use the default starting status. 512 InInfo.setUnknown(); 513 } else { 514 for (MachineBasicBlock *P : MBB.predecessors()) 515 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit); 516 } 517 518 // If we don't have any valid predecessor value, wait until we do. 519 if (!InInfo.isValid()) 520 return; 521 522 BBInfo.Pred = InInfo; 523 524 VSETVLIInfo TmpStatus = BBInfo.Pred.merge(BBInfo.Change); 525 526 // If the new exit value matches the old exit value, we don't need to revisit 527 // any blocks. 528 if (BBInfo.Exit == TmpStatus) 529 return; 530 531 BBInfo.Exit = TmpStatus; 532 533 // Add the successors to the work list so we can propagate the changed exit 534 // status. 535 for (MachineBasicBlock *S : MBB.successors()) 536 if (!BlockInfo[S->getNumber()].InQueue) 537 WorkList.push(S); 538 } 539 540 // If we weren't able to prove a vsetvli was directly unneeded, it might still 541 // be/ unneeded if the AVL is a phi node where all incoming values are VL 542 // outputs from the last VSETVLI in their respective basic blocks. 543 bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, 544 const MachineBasicBlock &MBB) { 545 if (DisableInsertVSETVLPHIOpt) 546 return true; 547 548 if (!Require.hasAVLReg()) 549 return true; 550 551 Register AVLReg = Require.getAVLReg(); 552 if (!AVLReg.isVirtual()) 553 return true; 554 555 // We need the AVL to be produce by a PHI node in this basic block. 556 MachineInstr *PHI = MRI->getVRegDef(AVLReg); 557 if (!PHI || PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB) 558 return true; 559 560 for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps; 561 PHIOp += 2) { 562 Register InReg = PHI->getOperand(PHIOp).getReg(); 563 MachineBasicBlock *PBB = PHI->getOperand(PHIOp + 1).getMBB(); 564 const BlockData &PBBInfo = BlockInfo[PBB->getNumber()]; 565 // If the exit from the predecessor has the VTYPE we are looking for 566 // we might be able to avoid a VSETVLI. 567 if (PBBInfo.Exit.isUnknown() || !PBBInfo.Exit.hasSameVTYPE(Require)) 568 return true; 569 570 // We need the PHI input to the be the output of a VSET(I)VLI. 571 MachineInstr *DefMI = MRI->getVRegDef(InReg); 572 if (!DefMI || (DefMI->getOpcode() != RISCV::PseudoVSETVLI && 573 DefMI->getOpcode() != RISCV::PseudoVSETIVLI)) 574 return true; 575 576 // We found a VSET(I)VLI make sure it matches the output of the 577 // predecessor block. 578 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 579 if (!DefInfo.hasSameAVL(PBBInfo.Exit) || 580 !DefInfo.hasSameVTYPE(PBBInfo.Exit)) 581 return true; 582 } 583 584 // If all the incoming values to the PHI checked out, we don't need 585 // to insert a VSETVLI. 586 return false; 587 } 588 589 void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { 590 VSETVLIInfo CurInfo; 591 592 for (MachineInstr &MI : MBB) { 593 // If this is an explicit VSETVLI or VSETIVLI, update our state. 594 if (MI.getOpcode() == RISCV::PseudoVSETVLI || 595 MI.getOpcode() == RISCV::PseudoVSETIVLI) { 596 // Conservatively, mark the VL and VTYPE as live. 597 assert(MI.getOperand(3).getReg() == RISCV::VL && 598 MI.getOperand(4).getReg() == RISCV::VTYPE && 599 "Unexpected operands where VL and VTYPE should be"); 600 MI.getOperand(3).setIsDead(false); 601 MI.getOperand(4).setIsDead(false); 602 CurInfo = getInfoForVSETVLI(MI); 603 continue; 604 } 605 606 uint64_t TSFlags = MI.getDesc().TSFlags; 607 if (RISCVII::hasSEWOp(TSFlags)) { 608 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 609 if (RISCVII::hasVLOp(TSFlags)) { 610 MachineOperand &VLOp = MI.getOperand(MI.getNumExplicitOperands() - 2); 611 if (VLOp.isReg()) { 612 // Erase the AVL operand from the instruction. 613 VLOp.setReg(RISCV::NoRegister); 614 VLOp.setIsKill(false); 615 } 616 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false, 617 /*isImp*/ true)); 618 } 619 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false, 620 /*isImp*/ true)); 621 622 if (!CurInfo.isValid()) { 623 // We haven't found any vector instructions or VL/VTYPE changes yet, 624 // use the predecessor information. 625 assert(BlockInfo[MBB.getNumber()].Pred.isValid() && 626 "Expected a valid predecessor state."); 627 if (needVSETVLI(NewInfo, BlockInfo[MBB.getNumber()].Pred) && 628 needVSETVLIPHI(NewInfo, MBB)) { 629 insertVSETVLI(MBB, MI, NewInfo, BlockInfo[MBB.getNumber()].Pred); 630 CurInfo = NewInfo; 631 } 632 } else { 633 // If this instruction isn't compatible with the previous VL/VTYPE 634 // we need to insert a VSETVLI. 635 if (needVSETVLI(NewInfo, CurInfo)) { 636 insertVSETVLI(MBB, MI, NewInfo, CurInfo); 637 CurInfo = NewInfo; 638 } 639 } 640 } 641 642 // If this is something updates VL/VTYPE that we don't know about, set 643 // the state to unknown. 644 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 645 MI.modifiesRegister(RISCV::VTYPE)) { 646 CurInfo = VSETVLIInfo::getUnknown(); 647 } 648 } 649 } 650 651 bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { 652 // Skip if the vector extension is not enabled. 653 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 654 if (!ST.hasStdExtV()) 655 return false; 656 657 TII = ST.getInstrInfo(); 658 MRI = &MF.getRegInfo(); 659 660 assert(BlockInfo.empty() && "Expect empty block infos"); 661 BlockInfo.resize(MF.getNumBlockIDs()); 662 663 bool HaveVectorOp = false; 664 665 // Phase 1 - determine how VL/VTYPE are affected by the each block. 666 for (const MachineBasicBlock &MBB : MF) 667 HaveVectorOp |= computeVLVTYPEChanges(MBB); 668 669 // If we didn't find any instructions that need VSETVLI, we're done. 670 if (HaveVectorOp) { 671 // Phase 2 - determine the exit VL/VTYPE from each block. We add all 672 // blocks to the list here, but will also add any that need to be revisited 673 // during Phase 2 processing. 674 for (const MachineBasicBlock &MBB : MF) { 675 WorkList.push(&MBB); 676 BlockInfo[MBB.getNumber()].InQueue = true; 677 } 678 while (!WorkList.empty()) { 679 const MachineBasicBlock &MBB = *WorkList.front(); 680 WorkList.pop(); 681 computeIncomingVLVTYPE(MBB); 682 } 683 684 // Phase 3 - add any vsetvli instructions needed in the block. Use the 685 // Phase 2 information to avoid adding vsetvlis before the first vector 686 // instruction in the block if the VL/VTYPE is satisfied by its 687 // predecessors. 688 for (MachineBasicBlock &MBB : MF) 689 emitVSETVLIs(MBB); 690 } 691 692 BlockInfo.clear(); 693 694 return HaveVectorOp; 695 } 696 697 /// Returns an instance of the Insert VSETVLI pass. 698 FunctionPass *llvm::createRISCVInsertVSETVLIPass() { 699 return new RISCVInsertVSETVLI(); 700 } 701