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