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