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