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 uint8_t SEWLMULRatioOnly : 1; 62 63 public: 64 VSETVLIInfo() 65 : AVLImm(0), TailAgnostic(false), MaskAgnostic(false), MaskRegOp(false), 66 SEWLMULRatioOnly(false) {} 67 68 static VSETVLIInfo getUnknown() { 69 VSETVLIInfo Info; 70 Info.setUnknown(); 71 return Info; 72 } 73 74 bool isValid() const { return State != Uninitialized; } 75 void setUnknown() { State = Unknown; } 76 bool isUnknown() const { return State == Unknown; } 77 78 void setAVLReg(Register Reg) { 79 AVLReg = Reg; 80 State = AVLIsReg; 81 } 82 83 void setAVLImm(unsigned Imm) { 84 AVLImm = Imm; 85 State = AVLIsImm; 86 } 87 88 bool hasAVLImm() const { return State == AVLIsImm; } 89 bool hasAVLReg() const { return State == AVLIsReg; } 90 Register getAVLReg() const { 91 assert(hasAVLReg()); 92 return AVLReg; 93 } 94 unsigned getAVLImm() const { 95 assert(hasAVLImm()); 96 return AVLImm; 97 } 98 99 bool hasSameAVL(const VSETVLIInfo &Other) const { 100 assert(isValid() && Other.isValid() && 101 "Can't compare invalid VSETVLIInfos"); 102 assert(!isUnknown() && !Other.isUnknown() && 103 "Can't compare AVL in unknown state"); 104 if (hasAVLReg() && Other.hasAVLReg()) 105 return getAVLReg() == Other.getAVLReg(); 106 107 if (hasAVLImm() && Other.hasAVLImm()) 108 return getAVLImm() == Other.getAVLImm(); 109 110 return false; 111 } 112 113 void setVTYPE(unsigned VType) { 114 assert(isValid() && !isUnknown() && 115 "Can't set VTYPE for uninitialized or unknown"); 116 VLMul = RISCVVType::getVLMUL(VType); 117 SEW = RISCVVType::getSEW(VType); 118 TailAgnostic = RISCVVType::isTailAgnostic(VType); 119 MaskAgnostic = RISCVVType::isMaskAgnostic(VType); 120 } 121 void setVTYPE(RISCVII::VLMUL L, unsigned S, bool TA, bool MA, bool MRO) { 122 assert(isValid() && !isUnknown() && 123 "Can't set VTYPE for uninitialized or unknown"); 124 VLMul = L; 125 SEW = S; 126 TailAgnostic = TA; 127 MaskAgnostic = MA; 128 MaskRegOp = MRO; 129 } 130 131 unsigned encodeVTYPE() const { 132 assert(isValid() && !isUnknown() && !SEWLMULRatioOnly && 133 "Can't encode VTYPE for uninitialized or unknown"); 134 return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic); 135 } 136 137 bool hasSEWLMULRatioOnly() const { return SEWLMULRatioOnly; } 138 139 bool hasSameVTYPE(const VSETVLIInfo &Other) const { 140 assert(isValid() && Other.isValid() && 141 "Can't compare invalid VSETVLIInfos"); 142 assert(!isUnknown() && !Other.isUnknown() && 143 "Can't compare VTYPE in unknown state"); 144 assert(!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly && 145 "Can't compare when only LMUL/SEW ratio is valid."); 146 return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) == 147 std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic, 148 Other.MaskAgnostic); 149 } 150 151 static unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) { 152 unsigned LMul; 153 bool Fractional; 154 std::tie(LMul, Fractional) = RISCVVType::decodeVLMUL(VLMul); 155 156 // Convert LMul to a fixed point value with 3 fractional bits. 157 LMul = Fractional ? (8 / LMul) : (LMul * 8); 158 159 assert(SEW >= 8 && "Unexpected SEW value"); 160 return (SEW * 8) / LMul; 161 } 162 163 unsigned getSEWLMULRatio() const { 164 assert(isValid() && !isUnknown() && 165 "Can't use VTYPE for uninitialized or unknown"); 166 return getSEWLMULRatio(SEW, VLMul); 167 } 168 169 // Check if the VTYPE for these two VSETVLIInfos produce the same VLMAX. 170 bool hasSameVLMAX(const VSETVLIInfo &Other) const { 171 assert(isValid() && Other.isValid() && 172 "Can't compare invalid VSETVLIInfos"); 173 assert(!isUnknown() && !Other.isUnknown() && 174 "Can't compare VTYPE in unknown state"); 175 return getSEWLMULRatio() == Other.getSEWLMULRatio(); 176 } 177 178 // Determine whether the vector instructions requirements represented by 179 // InstrInfo are compatible with the previous vsetvli instruction represented 180 // by this. 181 bool isCompatible(const VSETVLIInfo &InstrInfo) const { 182 assert(isValid() && InstrInfo.isValid() && 183 "Can't compare invalid VSETVLIInfos"); 184 assert(!InstrInfo.SEWLMULRatioOnly && 185 "Expected a valid VTYPE for instruction!"); 186 // Nothing is compatible with Unknown. 187 if (isUnknown() || InstrInfo.isUnknown()) 188 return false; 189 190 // If only our VLMAX ratio is valid, then this isn't compatible. 191 if (SEWLMULRatioOnly) 192 return false; 193 194 // If the instruction doesn't need an AVLReg and the SEW matches, consider 195 // it compatible. 196 if (InstrInfo.hasAVLReg() && InstrInfo.AVLReg == RISCV::NoRegister) { 197 if (SEW == InstrInfo.SEW) 198 return true; 199 } 200 201 // VTypes must match unless the instruction is a mask reg operation, then it 202 // only care about VLMAX. 203 // FIXME: Mask reg operations are probably ok if "this" VLMAX is larger 204 // than "InstrInfo". 205 if (!hasSameVTYPE(InstrInfo) && 206 !(InstrInfo.MaskRegOp && hasSameVLMAX(InstrInfo) && 207 TailAgnostic == InstrInfo.TailAgnostic && 208 MaskAgnostic == InstrInfo.MaskAgnostic)) 209 return false; 210 211 return hasSameAVL(InstrInfo); 212 } 213 214 bool isCompatibleWithLoadStoreEEW(unsigned EEW, 215 const VSETVLIInfo &InstrInfo) const { 216 assert(isValid() && InstrInfo.isValid() && 217 "Can't compare invalid VSETVLIInfos"); 218 assert(!InstrInfo.SEWLMULRatioOnly && 219 "Expected a valid VTYPE for instruction!"); 220 assert(EEW == InstrInfo.SEW && "Mismatched EEW/SEW for store"); 221 222 if (isUnknown() || hasSEWLMULRatioOnly()) 223 return false; 224 225 if (!hasSameAVL(InstrInfo)) 226 return false; 227 228 // TODO: This check isn't required for stores. But we should ignore for all 229 // stores not just unit-stride and strided so leaving it for now. 230 if (TailAgnostic != InstrInfo.TailAgnostic || 231 MaskAgnostic != InstrInfo.MaskAgnostic) 232 return false; 233 234 return getSEWLMULRatio() == getSEWLMULRatio(EEW, InstrInfo.VLMul); 235 } 236 237 bool operator==(const VSETVLIInfo &Other) const { 238 // Uninitialized is only equal to another Uninitialized. 239 if (!isValid()) 240 return !Other.isValid(); 241 if (!Other.isValid()) 242 return !isValid(); 243 244 // Unknown is only equal to another Unknown. 245 if (isUnknown()) 246 return Other.isUnknown(); 247 if (Other.isUnknown()) 248 return isUnknown(); 249 250 if (!hasSameAVL(Other)) 251 return false; 252 253 // If only the VLMAX is valid, check that it is the same. 254 if (SEWLMULRatioOnly && Other.SEWLMULRatioOnly) 255 return hasSameVLMAX(Other); 256 257 // If the full VTYPE is valid, check that it is the same. 258 if (!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly) 259 return hasSameVTYPE(Other); 260 261 // If the SEWLMULRatioOnly bits are different, then they aren't equal. 262 return false; 263 } 264 265 // Calculate the VSETVLIInfo visible to a block assuming this and Other are 266 // both predecessors. 267 VSETVLIInfo intersect(const VSETVLIInfo &Other) const { 268 // If the new value isn't valid, ignore it. 269 if (!Other.isValid()) 270 return *this; 271 272 // If this value isn't valid, this must be the first predecessor, use it. 273 if (!isValid()) 274 return Other; 275 276 // If either is unknown, the result is unknown. 277 if (isUnknown() || Other.isUnknown()) 278 return VSETVLIInfo::getUnknown(); 279 280 // If we have an exact, match return this. 281 if (*this == Other) 282 return *this; 283 284 // Not an exact match, but maybe the AVL and VLMAX are the same. If so, 285 // return an SEW/LMUL ratio only value. 286 if (hasSameAVL(Other) && hasSameVLMAX(Other)) { 287 VSETVLIInfo MergeInfo = *this; 288 MergeInfo.SEWLMULRatioOnly = true; 289 return MergeInfo; 290 } 291 292 // Otherwise the result is unknown. 293 return VSETVLIInfo::getUnknown(); 294 } 295 296 // Calculate the VSETVLIInfo visible at the end of the block assuming this 297 // is the predecessor value, and Other is change for this block. 298 VSETVLIInfo merge(const VSETVLIInfo &Other) const { 299 assert(isValid() && "Can only merge with a valid VSETVLInfo"); 300 301 // Nothing changed from the predecessor, keep it. 302 if (!Other.isValid()) 303 return *this; 304 305 // If the change is compatible with the input, we won't create a VSETVLI 306 // and should keep the predecessor. 307 if (isCompatible(Other)) 308 return *this; 309 310 // Otherwise just use whatever is in this block. 311 return Other; 312 } 313 }; 314 315 struct BlockData { 316 // The VSETVLIInfo that represents the net changes to the VL/VTYPE registers 317 // made by this block. Calculated in Phase 1. 318 VSETVLIInfo Change; 319 320 // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this 321 // block. Calculated in Phase 2. 322 VSETVLIInfo Exit; 323 324 // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor 325 // blocks. Calculated in Phase 2, and used by Phase 3. 326 VSETVLIInfo Pred; 327 328 // Keeps track of whether the block is already in the queue. 329 bool InQueue = false; 330 331 BlockData() {} 332 }; 333 334 class RISCVInsertVSETVLI : public MachineFunctionPass { 335 const TargetInstrInfo *TII; 336 MachineRegisterInfo *MRI; 337 338 std::vector<BlockData> BlockInfo; 339 std::queue<const MachineBasicBlock *> WorkList; 340 341 public: 342 static char ID; 343 344 RISCVInsertVSETVLI() : MachineFunctionPass(ID) { 345 initializeRISCVInsertVSETVLIPass(*PassRegistry::getPassRegistry()); 346 } 347 bool runOnMachineFunction(MachineFunction &MF) override; 348 349 void getAnalysisUsage(AnalysisUsage &AU) const override { 350 AU.setPreservesCFG(); 351 MachineFunctionPass::getAnalysisUsage(AU); 352 } 353 354 StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; } 355 356 private: 357 bool needVSETVLI(const VSETVLIInfo &Require, const VSETVLIInfo &CurInfo); 358 bool needVSETVLIPHI(const VSETVLIInfo &Require, const MachineBasicBlock &MBB); 359 void insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 360 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo); 361 362 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB); 363 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); 364 void emitVSETVLIs(MachineBasicBlock &MBB); 365 }; 366 367 } // end anonymous namespace 368 369 char RISCVInsertVSETVLI::ID = 0; 370 371 INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME, 372 false, false) 373 374 static MachineInstr *elideCopies(MachineInstr *MI, 375 const MachineRegisterInfo *MRI) { 376 while (true) { 377 if (!MI->isFullCopy()) 378 return MI; 379 if (!Register::isVirtualRegister(MI->getOperand(1).getReg())) 380 return nullptr; 381 MI = MRI->getVRegDef(MI->getOperand(1).getReg()); 382 if (!MI) 383 return nullptr; 384 } 385 } 386 387 static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, 388 const MachineRegisterInfo *MRI) { 389 VSETVLIInfo InstrInfo; 390 unsigned NumOperands = MI.getNumExplicitOperands(); 391 bool HasPolicy = RISCVII::hasVecPolicyOp(TSFlags); 392 393 // Default to tail agnostic unless the destination is tied to a source. 394 // Unless the source is undef. In that case the user would have some control 395 // over the tail values. Some pseudo instructions force a tail agnostic policy 396 // despite having a tied def. 397 bool ForceTailAgnostic = RISCVII::doesForceTailAgnostic(TSFlags); 398 bool TailAgnostic = true; 399 // If the instruction has policy argument, use the argument. 400 if (HasPolicy) { 401 const MachineOperand &Op = MI.getOperand(MI.getNumExplicitOperands() - 1); 402 TailAgnostic = Op.getImm() & 0x1; 403 } 404 405 unsigned UseOpIdx; 406 if (!(ForceTailAgnostic || (HasPolicy && TailAgnostic)) && 407 MI.isRegTiedToUseOperand(0, &UseOpIdx)) { 408 TailAgnostic = false; 409 // If the tied operand is an IMPLICIT_DEF we can keep TailAgnostic. 410 const MachineOperand &UseMO = MI.getOperand(UseOpIdx); 411 MachineInstr *UseMI = MRI->getVRegDef(UseMO.getReg()); 412 if (UseMI) { 413 UseMI = elideCopies(UseMI, MRI); 414 if (UseMI && UseMI->isImplicitDef()) 415 TailAgnostic = true; 416 } 417 } 418 419 // Remove the tail policy so we can find the SEW and VL. 420 if (HasPolicy) 421 --NumOperands; 422 423 RISCVII::VLMUL VLMul = RISCVII::getLMul(TSFlags); 424 425 unsigned Log2SEW = MI.getOperand(NumOperands - 1).getImm(); 426 // A Log2SEW of 0 is an operation on mask registers only. 427 bool MaskRegOp = Log2SEW == 0; 428 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8; 429 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW"); 430 431 if (RISCVII::hasVLOp(TSFlags)) { 432 const MachineOperand &VLOp = MI.getOperand(NumOperands - 2); 433 if (VLOp.isImm()) { 434 int64_t Imm = VLOp.getImm(); 435 // Conver the VLMax sentintel to X0 register. 436 if (Imm == RISCV::VLMaxSentinel) 437 InstrInfo.setAVLReg(RISCV::X0); 438 else 439 InstrInfo.setAVLImm(Imm); 440 } else { 441 InstrInfo.setAVLReg(VLOp.getReg()); 442 } 443 } else 444 InstrInfo.setAVLReg(RISCV::NoRegister); 445 InstrInfo.setVTYPE(VLMul, SEW, /*TailAgnostic*/ TailAgnostic, 446 /*MaskAgnostic*/ false, MaskRegOp); 447 448 return InstrInfo; 449 } 450 451 void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 452 const VSETVLIInfo &Info, 453 const VSETVLIInfo &PrevInfo) { 454 DebugLoc DL = MI.getDebugLoc(); 455 456 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same 457 // VLMAX. 458 if (PrevInfo.isValid() && !PrevInfo.isUnknown() && 459 Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) { 460 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLIX0)) 461 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 462 .addReg(RISCV::X0, RegState::Kill) 463 .addImm(Info.encodeVTYPE()) 464 .addReg(RISCV::VL, RegState::Implicit); 465 return; 466 } 467 468 if (Info.hasAVLImm()) { 469 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETIVLI)) 470 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 471 .addImm(Info.getAVLImm()) 472 .addImm(Info.encodeVTYPE()); 473 return; 474 } 475 476 Register AVLReg = Info.getAVLReg(); 477 if (AVLReg == RISCV::NoRegister) { 478 // We can only use x0, x0 if there's no chance of the vtype change causing 479 // the previous vl to become invalid. 480 if (PrevInfo.isValid() && !PrevInfo.isUnknown() && 481 Info.hasSameVLMAX(PrevInfo)) { 482 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLIX0)) 483 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 484 .addReg(RISCV::X0, RegState::Kill) 485 .addImm(Info.encodeVTYPE()) 486 .addReg(RISCV::VL, RegState::Implicit); 487 return; 488 } 489 // Otherwise use an AVL of 0 to avoid depending on previous vl. 490 BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETIVLI)) 491 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 492 .addImm(0) 493 .addImm(Info.encodeVTYPE()); 494 return; 495 } 496 497 if (AVLReg.isVirtual()) 498 MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass); 499 500 // Use X0 as the DestReg unless AVLReg is X0. We also need to change the 501 // opcode if the AVLReg is X0 as they have different register classes for 502 // the AVL operand. 503 Register DestReg = RISCV::X0; 504 unsigned Opcode = RISCV::PseudoVSETVLI; 505 if (AVLReg == RISCV::X0) { 506 DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 507 Opcode = RISCV::PseudoVSETVLIX0; 508 } 509 BuildMI(MBB, MI, DL, TII->get(Opcode)) 510 .addReg(DestReg, RegState::Define | RegState::Dead) 511 .addReg(AVLReg) 512 .addImm(Info.encodeVTYPE()); 513 } 514 515 // Return a VSETVLIInfo representing the changes made by this VSETVLI or 516 // VSETIVLI instruction. 517 static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) { 518 VSETVLIInfo NewInfo; 519 if (MI.getOpcode() == RISCV::PseudoVSETIVLI) { 520 NewInfo.setAVLImm(MI.getOperand(1).getImm()); 521 } else { 522 assert(MI.getOpcode() == RISCV::PseudoVSETVLI || 523 MI.getOpcode() == RISCV::PseudoVSETVLIX0); 524 Register AVLReg = MI.getOperand(1).getReg(); 525 assert((AVLReg != RISCV::X0 || MI.getOperand(0).getReg() != RISCV::X0) && 526 "Can't handle X0, X0 vsetvli yet"); 527 NewInfo.setAVLReg(AVLReg); 528 } 529 NewInfo.setVTYPE(MI.getOperand(2).getImm()); 530 531 return NewInfo; 532 } 533 534 bool RISCVInsertVSETVLI::needVSETVLI(const VSETVLIInfo &Require, 535 const VSETVLIInfo &CurInfo) { 536 if (CurInfo.isCompatible(Require)) 537 return false; 538 539 // We didn't find a compatible value. If our AVL is a virtual register, 540 // it might be defined by a VSET(I)VLI. If it has the same VTYPE we need 541 // and the last VL/VTYPE we observed is the same, we don't need a 542 // VSETVLI here. 543 if (!CurInfo.isUnknown() && Require.hasAVLReg() && 544 Require.getAVLReg().isVirtual() && !CurInfo.hasSEWLMULRatioOnly() && 545 Require.hasSameVTYPE(CurInfo)) { 546 if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { 547 if (DefMI->getOpcode() == RISCV::PseudoVSETVLI || 548 DefMI->getOpcode() == RISCV::PseudoVSETVLIX0 || 549 DefMI->getOpcode() == RISCV::PseudoVSETIVLI) { 550 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 551 if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVTYPE(CurInfo)) 552 return false; 553 } 554 } 555 } 556 557 return true; 558 } 559 560 bool canSkipVSETVLIForLoadStore(const MachineInstr &MI, 561 const VSETVLIInfo &Require, 562 const VSETVLIInfo &CurInfo) { 563 unsigned EEW; 564 switch (MI.getOpcode()) { 565 default: 566 return false; 567 case RISCV::PseudoVLE8_V_M1: 568 case RISCV::PseudoVLE8_V_M1_MASK: 569 case RISCV::PseudoVLE8_V_M2: 570 case RISCV::PseudoVLE8_V_M2_MASK: 571 case RISCV::PseudoVLE8_V_M4: 572 case RISCV::PseudoVLE8_V_M4_MASK: 573 case RISCV::PseudoVLE8_V_M8: 574 case RISCV::PseudoVLE8_V_M8_MASK: 575 case RISCV::PseudoVLE8_V_MF2: 576 case RISCV::PseudoVLE8_V_MF2_MASK: 577 case RISCV::PseudoVLE8_V_MF4: 578 case RISCV::PseudoVLE8_V_MF4_MASK: 579 case RISCV::PseudoVLE8_V_MF8: 580 case RISCV::PseudoVLE8_V_MF8_MASK: 581 case RISCV::PseudoVLSE8_V_M1: 582 case RISCV::PseudoVLSE8_V_M1_MASK: 583 case RISCV::PseudoVLSE8_V_M2: 584 case RISCV::PseudoVLSE8_V_M2_MASK: 585 case RISCV::PseudoVLSE8_V_M4: 586 case RISCV::PseudoVLSE8_V_M4_MASK: 587 case RISCV::PseudoVLSE8_V_M8: 588 case RISCV::PseudoVLSE8_V_M8_MASK: 589 case RISCV::PseudoVLSE8_V_MF2: 590 case RISCV::PseudoVLSE8_V_MF2_MASK: 591 case RISCV::PseudoVLSE8_V_MF4: 592 case RISCV::PseudoVLSE8_V_MF4_MASK: 593 case RISCV::PseudoVLSE8_V_MF8: 594 case RISCV::PseudoVLSE8_V_MF8_MASK: 595 case RISCV::PseudoVSE8_V_M1: 596 case RISCV::PseudoVSE8_V_M1_MASK: 597 case RISCV::PseudoVSE8_V_M2: 598 case RISCV::PseudoVSE8_V_M2_MASK: 599 case RISCV::PseudoVSE8_V_M4: 600 case RISCV::PseudoVSE8_V_M4_MASK: 601 case RISCV::PseudoVSE8_V_M8: 602 case RISCV::PseudoVSE8_V_M8_MASK: 603 case RISCV::PseudoVSE8_V_MF2: 604 case RISCV::PseudoVSE8_V_MF2_MASK: 605 case RISCV::PseudoVSE8_V_MF4: 606 case RISCV::PseudoVSE8_V_MF4_MASK: 607 case RISCV::PseudoVSE8_V_MF8: 608 case RISCV::PseudoVSE8_V_MF8_MASK: 609 case RISCV::PseudoVSSE8_V_M1: 610 case RISCV::PseudoVSSE8_V_M1_MASK: 611 case RISCV::PseudoVSSE8_V_M2: 612 case RISCV::PseudoVSSE8_V_M2_MASK: 613 case RISCV::PseudoVSSE8_V_M4: 614 case RISCV::PseudoVSSE8_V_M4_MASK: 615 case RISCV::PseudoVSSE8_V_M8: 616 case RISCV::PseudoVSSE8_V_M8_MASK: 617 case RISCV::PseudoVSSE8_V_MF2: 618 case RISCV::PseudoVSSE8_V_MF2_MASK: 619 case RISCV::PseudoVSSE8_V_MF4: 620 case RISCV::PseudoVSSE8_V_MF4_MASK: 621 case RISCV::PseudoVSSE8_V_MF8: 622 case RISCV::PseudoVSSE8_V_MF8_MASK: 623 EEW = 8; 624 break; 625 case RISCV::PseudoVLE16_V_M1: 626 case RISCV::PseudoVLE16_V_M1_MASK: 627 case RISCV::PseudoVLE16_V_M2: 628 case RISCV::PseudoVLE16_V_M2_MASK: 629 case RISCV::PseudoVLE16_V_M4: 630 case RISCV::PseudoVLE16_V_M4_MASK: 631 case RISCV::PseudoVLE16_V_M8: 632 case RISCV::PseudoVLE16_V_M8_MASK: 633 case RISCV::PseudoVLE16_V_MF2: 634 case RISCV::PseudoVLE16_V_MF2_MASK: 635 case RISCV::PseudoVLE16_V_MF4: 636 case RISCV::PseudoVLE16_V_MF4_MASK: 637 case RISCV::PseudoVLSE16_V_M1: 638 case RISCV::PseudoVLSE16_V_M1_MASK: 639 case RISCV::PseudoVLSE16_V_M2: 640 case RISCV::PseudoVLSE16_V_M2_MASK: 641 case RISCV::PseudoVLSE16_V_M4: 642 case RISCV::PseudoVLSE16_V_M4_MASK: 643 case RISCV::PseudoVLSE16_V_M8: 644 case RISCV::PseudoVLSE16_V_M8_MASK: 645 case RISCV::PseudoVLSE16_V_MF2: 646 case RISCV::PseudoVLSE16_V_MF2_MASK: 647 case RISCV::PseudoVLSE16_V_MF4: 648 case RISCV::PseudoVLSE16_V_MF4_MASK: 649 case RISCV::PseudoVSE16_V_M1: 650 case RISCV::PseudoVSE16_V_M1_MASK: 651 case RISCV::PseudoVSE16_V_M2: 652 case RISCV::PseudoVSE16_V_M2_MASK: 653 case RISCV::PseudoVSE16_V_M4: 654 case RISCV::PseudoVSE16_V_M4_MASK: 655 case RISCV::PseudoVSE16_V_M8: 656 case RISCV::PseudoVSE16_V_M8_MASK: 657 case RISCV::PseudoVSE16_V_MF2: 658 case RISCV::PseudoVSE16_V_MF2_MASK: 659 case RISCV::PseudoVSE16_V_MF4: 660 case RISCV::PseudoVSE16_V_MF4_MASK: 661 case RISCV::PseudoVSSE16_V_M1: 662 case RISCV::PseudoVSSE16_V_M1_MASK: 663 case RISCV::PseudoVSSE16_V_M2: 664 case RISCV::PseudoVSSE16_V_M2_MASK: 665 case RISCV::PseudoVSSE16_V_M4: 666 case RISCV::PseudoVSSE16_V_M4_MASK: 667 case RISCV::PseudoVSSE16_V_M8: 668 case RISCV::PseudoVSSE16_V_M8_MASK: 669 case RISCV::PseudoVSSE16_V_MF2: 670 case RISCV::PseudoVSSE16_V_MF2_MASK: 671 case RISCV::PseudoVSSE16_V_MF4: 672 case RISCV::PseudoVSSE16_V_MF4_MASK: 673 EEW = 16; 674 break; 675 case RISCV::PseudoVLE32_V_M1: 676 case RISCV::PseudoVLE32_V_M1_MASK: 677 case RISCV::PseudoVLE32_V_M2: 678 case RISCV::PseudoVLE32_V_M2_MASK: 679 case RISCV::PseudoVLE32_V_M4: 680 case RISCV::PseudoVLE32_V_M4_MASK: 681 case RISCV::PseudoVLE32_V_M8: 682 case RISCV::PseudoVLE32_V_M8_MASK: 683 case RISCV::PseudoVLE32_V_MF2: 684 case RISCV::PseudoVLE32_V_MF2_MASK: 685 case RISCV::PseudoVLSE32_V_M1: 686 case RISCV::PseudoVLSE32_V_M1_MASK: 687 case RISCV::PseudoVLSE32_V_M2: 688 case RISCV::PseudoVLSE32_V_M2_MASK: 689 case RISCV::PseudoVLSE32_V_M4: 690 case RISCV::PseudoVLSE32_V_M4_MASK: 691 case RISCV::PseudoVLSE32_V_M8: 692 case RISCV::PseudoVLSE32_V_M8_MASK: 693 case RISCV::PseudoVLSE32_V_MF2: 694 case RISCV::PseudoVLSE32_V_MF2_MASK: 695 case RISCV::PseudoVSE32_V_M1: 696 case RISCV::PseudoVSE32_V_M1_MASK: 697 case RISCV::PseudoVSE32_V_M2: 698 case RISCV::PseudoVSE32_V_M2_MASK: 699 case RISCV::PseudoVSE32_V_M4: 700 case RISCV::PseudoVSE32_V_M4_MASK: 701 case RISCV::PseudoVSE32_V_M8: 702 case RISCV::PseudoVSE32_V_M8_MASK: 703 case RISCV::PseudoVSE32_V_MF2: 704 case RISCV::PseudoVSE32_V_MF2_MASK: 705 case RISCV::PseudoVSSE32_V_M1: 706 case RISCV::PseudoVSSE32_V_M1_MASK: 707 case RISCV::PseudoVSSE32_V_M2: 708 case RISCV::PseudoVSSE32_V_M2_MASK: 709 case RISCV::PseudoVSSE32_V_M4: 710 case RISCV::PseudoVSSE32_V_M4_MASK: 711 case RISCV::PseudoVSSE32_V_M8: 712 case RISCV::PseudoVSSE32_V_M8_MASK: 713 case RISCV::PseudoVSSE32_V_MF2: 714 case RISCV::PseudoVSSE32_V_MF2_MASK: 715 EEW = 32; 716 break; 717 case RISCV::PseudoVLE64_V_M1: 718 case RISCV::PseudoVLE64_V_M1_MASK: 719 case RISCV::PseudoVLE64_V_M2: 720 case RISCV::PseudoVLE64_V_M2_MASK: 721 case RISCV::PseudoVLE64_V_M4: 722 case RISCV::PseudoVLE64_V_M4_MASK: 723 case RISCV::PseudoVLE64_V_M8: 724 case RISCV::PseudoVLE64_V_M8_MASK: 725 case RISCV::PseudoVLSE64_V_M1: 726 case RISCV::PseudoVLSE64_V_M1_MASK: 727 case RISCV::PseudoVLSE64_V_M2: 728 case RISCV::PseudoVLSE64_V_M2_MASK: 729 case RISCV::PseudoVLSE64_V_M4: 730 case RISCV::PseudoVLSE64_V_M4_MASK: 731 case RISCV::PseudoVLSE64_V_M8: 732 case RISCV::PseudoVLSE64_V_M8_MASK: 733 case RISCV::PseudoVSE64_V_M1: 734 case RISCV::PseudoVSE64_V_M1_MASK: 735 case RISCV::PseudoVSE64_V_M2: 736 case RISCV::PseudoVSE64_V_M2_MASK: 737 case RISCV::PseudoVSE64_V_M4: 738 case RISCV::PseudoVSE64_V_M4_MASK: 739 case RISCV::PseudoVSE64_V_M8: 740 case RISCV::PseudoVSE64_V_M8_MASK: 741 case RISCV::PseudoVSSE64_V_M1: 742 case RISCV::PseudoVSSE64_V_M1_MASK: 743 case RISCV::PseudoVSSE64_V_M2: 744 case RISCV::PseudoVSSE64_V_M2_MASK: 745 case RISCV::PseudoVSSE64_V_M4: 746 case RISCV::PseudoVSSE64_V_M4_MASK: 747 case RISCV::PseudoVSSE64_V_M8: 748 case RISCV::PseudoVSSE64_V_M8_MASK: 749 EEW = 64; 750 break; 751 } 752 753 return CurInfo.isCompatibleWithLoadStoreEEW(EEW, Require); 754 } 755 756 bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB) { 757 bool HadVectorOp = false; 758 759 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 760 for (const MachineInstr &MI : MBB) { 761 // If this is an explicit VSETVLI or VSETIVLI, update our state. 762 if (MI.getOpcode() == RISCV::PseudoVSETVLI || 763 MI.getOpcode() == RISCV::PseudoVSETVLIX0 || 764 MI.getOpcode() == RISCV::PseudoVSETIVLI) { 765 HadVectorOp = true; 766 BBInfo.Change = getInfoForVSETVLI(MI); 767 continue; 768 } 769 770 uint64_t TSFlags = MI.getDesc().TSFlags; 771 if (RISCVII::hasSEWOp(TSFlags)) { 772 HadVectorOp = true; 773 774 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 775 776 if (!BBInfo.Change.isValid()) { 777 BBInfo.Change = NewInfo; 778 } else { 779 // If this instruction isn't compatible with the previous VL/VTYPE 780 // we need to insert a VSETVLI. 781 // If this is a unit-stride or strided load/store, we may be able to use 782 // the EMUL=(EEW/SEW)*LMUL relationship to avoid changing vtype. 783 // NOTE: We only do this if the vtype we're comparing against was 784 // created in this block. We need the first and third phase to treat 785 // the store the same way. 786 if (!canSkipVSETVLIForLoadStore(MI, NewInfo, BBInfo.Change) && 787 needVSETVLI(NewInfo, BBInfo.Change)) 788 BBInfo.Change = NewInfo; 789 } 790 } 791 792 // If this is something that updates VL/VTYPE that we don't know about, set 793 // the state to unknown. 794 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 795 MI.modifiesRegister(RISCV::VTYPE)) { 796 BBInfo.Change = VSETVLIInfo::getUnknown(); 797 } 798 } 799 800 // Initial exit state is whatever change we found in the block. 801 BBInfo.Exit = BBInfo.Change; 802 803 return HadVectorOp; 804 } 805 806 void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) { 807 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 808 809 BBInfo.InQueue = false; 810 811 VSETVLIInfo InInfo; 812 if (MBB.pred_empty()) { 813 // There are no predecessors, so use the default starting status. 814 InInfo.setUnknown(); 815 } else { 816 for (MachineBasicBlock *P : MBB.predecessors()) 817 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit); 818 } 819 820 // If we don't have any valid predecessor value, wait until we do. 821 if (!InInfo.isValid()) 822 return; 823 824 BBInfo.Pred = InInfo; 825 826 VSETVLIInfo TmpStatus = BBInfo.Pred.merge(BBInfo.Change); 827 828 // If the new exit value matches the old exit value, we don't need to revisit 829 // any blocks. 830 if (BBInfo.Exit == TmpStatus) 831 return; 832 833 BBInfo.Exit = TmpStatus; 834 835 // Add the successors to the work list so we can propagate the changed exit 836 // status. 837 for (MachineBasicBlock *S : MBB.successors()) 838 if (!BlockInfo[S->getNumber()].InQueue) 839 WorkList.push(S); 840 } 841 842 // If we weren't able to prove a vsetvli was directly unneeded, it might still 843 // be/ unneeded if the AVL is a phi node where all incoming values are VL 844 // outputs from the last VSETVLI in their respective basic blocks. 845 bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, 846 const MachineBasicBlock &MBB) { 847 if (DisableInsertVSETVLPHIOpt) 848 return true; 849 850 if (!Require.hasAVLReg()) 851 return true; 852 853 Register AVLReg = Require.getAVLReg(); 854 if (!AVLReg.isVirtual()) 855 return true; 856 857 // We need the AVL to be produce by a PHI node in this basic block. 858 MachineInstr *PHI = MRI->getVRegDef(AVLReg); 859 if (!PHI || PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB) 860 return true; 861 862 for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps; 863 PHIOp += 2) { 864 Register InReg = PHI->getOperand(PHIOp).getReg(); 865 MachineBasicBlock *PBB = PHI->getOperand(PHIOp + 1).getMBB(); 866 const BlockData &PBBInfo = BlockInfo[PBB->getNumber()]; 867 // If the exit from the predecessor has the VTYPE we are looking for 868 // we might be able to avoid a VSETVLI. 869 if (PBBInfo.Exit.isUnknown() || !PBBInfo.Exit.hasSameVTYPE(Require)) 870 return true; 871 872 // We need the PHI input to the be the output of a VSET(I)VLI. 873 MachineInstr *DefMI = MRI->getVRegDef(InReg); 874 if (!DefMI || (DefMI->getOpcode() != RISCV::PseudoVSETVLI && 875 DefMI->getOpcode() != RISCV::PseudoVSETVLIX0 && 876 DefMI->getOpcode() != RISCV::PseudoVSETIVLI)) 877 return true; 878 879 // We found a VSET(I)VLI make sure it matches the output of the 880 // predecessor block. 881 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 882 if (!DefInfo.hasSameAVL(PBBInfo.Exit) || 883 !DefInfo.hasSameVTYPE(PBBInfo.Exit)) 884 return true; 885 } 886 887 // If all the incoming values to the PHI checked out, we don't need 888 // to insert a VSETVLI. 889 return false; 890 } 891 892 void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { 893 VSETVLIInfo CurInfo; 894 // Only be set if current VSETVLIInfo is from an explicit VSET(I)VLI. 895 MachineInstr *PrevVSETVLIMI = nullptr; 896 897 for (MachineInstr &MI : MBB) { 898 // If this is an explicit VSETVLI or VSETIVLI, update our state. 899 if (MI.getOpcode() == RISCV::PseudoVSETVLI || 900 MI.getOpcode() == RISCV::PseudoVSETVLIX0 || 901 MI.getOpcode() == RISCV::PseudoVSETIVLI) { 902 // Conservatively, mark the VL and VTYPE as live. 903 assert(MI.getOperand(3).getReg() == RISCV::VL && 904 MI.getOperand(4).getReg() == RISCV::VTYPE && 905 "Unexpected operands where VL and VTYPE should be"); 906 MI.getOperand(3).setIsDead(false); 907 MI.getOperand(4).setIsDead(false); 908 CurInfo = getInfoForVSETVLI(MI); 909 PrevVSETVLIMI = &MI; 910 continue; 911 } 912 913 uint64_t TSFlags = MI.getDesc().TSFlags; 914 if (RISCVII::hasSEWOp(TSFlags)) { 915 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 916 if (RISCVII::hasVLOp(TSFlags)) { 917 MachineOperand &VLOp = MI.getOperand(MI.getNumExplicitOperands() - 2); 918 if (VLOp.isReg()) { 919 // Erase the AVL operand from the instruction. 920 VLOp.setReg(RISCV::NoRegister); 921 VLOp.setIsKill(false); 922 } 923 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false, 924 /*isImp*/ true)); 925 } 926 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false, 927 /*isImp*/ true)); 928 929 if (!CurInfo.isValid()) { 930 // We haven't found any vector instructions or VL/VTYPE changes yet, 931 // use the predecessor information. 932 assert(BlockInfo[MBB.getNumber()].Pred.isValid() && 933 "Expected a valid predecessor state."); 934 if (needVSETVLI(NewInfo, BlockInfo[MBB.getNumber()].Pred) && 935 needVSETVLIPHI(NewInfo, MBB)) { 936 insertVSETVLI(MBB, MI, NewInfo, BlockInfo[MBB.getNumber()].Pred); 937 CurInfo = NewInfo; 938 } 939 } else { 940 // If this instruction isn't compatible with the previous VL/VTYPE 941 // we need to insert a VSETVLI. 942 // If this is a unit-stride or strided load/store, we may be able to use 943 // the EMUL=(EEW/SEW)*LMUL relationship to avoid changing vtype. 944 // NOTE: We can't use predecessor information for the store. We must 945 // treat it the same as the first phase so that we produce the correct 946 // vl/vtype for succesor blocks. 947 if (!canSkipVSETVLIForLoadStore(MI, NewInfo, CurInfo) && 948 needVSETVLI(NewInfo, CurInfo)) { 949 // If the previous VL/VTYPE is set by VSETVLI and do not use, Merge it 950 // with current VL/VTYPE. 951 bool NeedInsertVSETVLI = true; 952 if (PrevVSETVLIMI) { 953 bool HasSameAVL = 954 CurInfo.hasSameAVL(NewInfo) || 955 (NewInfo.hasAVLReg() && NewInfo.getAVLReg().isVirtual() && 956 NewInfo.getAVLReg() == PrevVSETVLIMI->getOperand(0).getReg()); 957 // If these two VSETVLI have the same AVL and the same VLMAX, 958 // we could merge these two VSETVLI. 959 if (HasSameAVL && 960 CurInfo.getSEWLMULRatio() == NewInfo.getSEWLMULRatio()) { 961 PrevVSETVLIMI->getOperand(2).setImm(NewInfo.encodeVTYPE()); 962 NeedInsertVSETVLI = false; 963 } 964 } 965 if (NeedInsertVSETVLI) 966 insertVSETVLI(MBB, MI, NewInfo, CurInfo); 967 CurInfo = NewInfo; 968 } 969 } 970 PrevVSETVLIMI = nullptr; 971 } 972 973 // If this is something updates VL/VTYPE that we don't know about, set 974 // the state to unknown. 975 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 976 MI.modifiesRegister(RISCV::VTYPE)) { 977 CurInfo = VSETVLIInfo::getUnknown(); 978 PrevVSETVLIMI = nullptr; 979 } 980 } 981 } 982 983 bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { 984 // Skip if the vector extension is not enabled. 985 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 986 if (!ST.hasStdExtV()) 987 return false; 988 989 TII = ST.getInstrInfo(); 990 MRI = &MF.getRegInfo(); 991 992 assert(BlockInfo.empty() && "Expect empty block infos"); 993 BlockInfo.resize(MF.getNumBlockIDs()); 994 995 bool HaveVectorOp = false; 996 997 // Phase 1 - determine how VL/VTYPE are affected by the each block. 998 for (const MachineBasicBlock &MBB : MF) 999 HaveVectorOp |= computeVLVTYPEChanges(MBB); 1000 1001 // If we didn't find any instructions that need VSETVLI, we're done. 1002 if (HaveVectorOp) { 1003 // Phase 2 - determine the exit VL/VTYPE from each block. We add all 1004 // blocks to the list here, but will also add any that need to be revisited 1005 // during Phase 2 processing. 1006 for (const MachineBasicBlock &MBB : MF) { 1007 WorkList.push(&MBB); 1008 BlockInfo[MBB.getNumber()].InQueue = true; 1009 } 1010 while (!WorkList.empty()) { 1011 const MachineBasicBlock &MBB = *WorkList.front(); 1012 WorkList.pop(); 1013 computeIncomingVLVTYPE(MBB); 1014 } 1015 1016 // Phase 3 - add any vsetvli instructions needed in the block. Use the 1017 // Phase 2 information to avoid adding vsetvlis before the first vector 1018 // instruction in the block if the VL/VTYPE is satisfied by its 1019 // predecessors. 1020 for (MachineBasicBlock &MBB : MF) 1021 emitVSETVLIs(MBB); 1022 } 1023 1024 BlockInfo.clear(); 1025 1026 return HaveVectorOp; 1027 } 1028 1029 /// Returns an instance of the Insert VSETVLI pass. 1030 FunctionPass *llvm::createRISCVInsertVSETVLIPass() { 1031 return new RISCVInsertVSETVLI(); 1032 } 1033