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 VSETVLIInfo &Require, 457 const VSETVLIInfo &CurInfo) const; 458 bool needVSETVLI(const MachineInstr &MI, const VSETVLIInfo &Require, 459 const VSETVLIInfo &CurInfo) const; 460 bool needVSETVLIPHI(const VSETVLIInfo &Require, 461 const MachineBasicBlock &MBB) const; 462 void insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 463 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo); 464 void insertVSETVLI(MachineBasicBlock &MBB, 465 MachineBasicBlock::iterator InsertPt, DebugLoc DL, 466 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo); 467 468 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB); 469 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB); 470 void emitVSETVLIs(MachineBasicBlock &MBB); 471 void doLocalPrepass(MachineBasicBlock &MBB); 472 void doLocalPostpass(MachineBasicBlock &MBB); 473 void doPRE(MachineBasicBlock &MBB); 474 }; 475 476 } // end anonymous namespace 477 478 char RISCVInsertVSETVLI::ID = 0; 479 480 INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME, 481 false, false) 482 483 static bool isVectorConfigInstr(const MachineInstr &MI) { 484 return MI.getOpcode() == RISCV::PseudoVSETVLI || 485 MI.getOpcode() == RISCV::PseudoVSETVLIX0 || 486 MI.getOpcode() == RISCV::PseudoVSETIVLI; 487 } 488 489 /// Return true if this is 'vsetvli x0, x0, vtype' which preserves 490 /// VL and only sets VTYPE. 491 static bool isVLPreservingConfig(const MachineInstr &MI) { 492 if (MI.getOpcode() != RISCV::PseudoVSETVLIX0) 493 return false; 494 assert(RISCV::X0 == MI.getOperand(1).getReg()); 495 return RISCV::X0 == MI.getOperand(0).getReg(); 496 } 497 498 static MachineInstr *elideCopies(MachineInstr *MI, 499 const MachineRegisterInfo *MRI) { 500 while (true) { 501 if (!MI->isFullCopy()) 502 return MI; 503 if (!Register::isVirtualRegister(MI->getOperand(1).getReg())) 504 return nullptr; 505 MI = MRI->getVRegDef(MI->getOperand(1).getReg()); 506 if (!MI) 507 return nullptr; 508 } 509 } 510 511 static bool isScalarMoveInstr(const MachineInstr &MI) { 512 switch (MI.getOpcode()) { 513 default: 514 return false; 515 case RISCV::PseudoVMV_S_X_M1: 516 case RISCV::PseudoVMV_S_X_M2: 517 case RISCV::PseudoVMV_S_X_M4: 518 case RISCV::PseudoVMV_S_X_M8: 519 case RISCV::PseudoVMV_S_X_MF2: 520 case RISCV::PseudoVMV_S_X_MF4: 521 case RISCV::PseudoVMV_S_X_MF8: 522 case RISCV::PseudoVFMV_S_F16_M1: 523 case RISCV::PseudoVFMV_S_F16_M2: 524 case RISCV::PseudoVFMV_S_F16_M4: 525 case RISCV::PseudoVFMV_S_F16_M8: 526 case RISCV::PseudoVFMV_S_F16_MF2: 527 case RISCV::PseudoVFMV_S_F16_MF4: 528 case RISCV::PseudoVFMV_S_F32_M1: 529 case RISCV::PseudoVFMV_S_F32_M2: 530 case RISCV::PseudoVFMV_S_F32_M4: 531 case RISCV::PseudoVFMV_S_F32_M8: 532 case RISCV::PseudoVFMV_S_F32_MF2: 533 case RISCV::PseudoVFMV_S_F64_M1: 534 case RISCV::PseudoVFMV_S_F64_M2: 535 case RISCV::PseudoVFMV_S_F64_M4: 536 case RISCV::PseudoVFMV_S_F64_M8: 537 return true; 538 } 539 } 540 541 static unsigned getVLOpNum(const MachineInstr &MI) { 542 return RISCVII::getVLOpNum(MI.getDesc()); 543 } 544 545 static unsigned getSEWOpNum(const MachineInstr &MI) { 546 return RISCVII::getSEWOpNum(MI.getDesc()); 547 } 548 549 static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, 550 const MachineRegisterInfo *MRI) { 551 VSETVLIInfo InstrInfo; 552 553 // If the instruction has policy argument, use the argument. 554 // If there is no policy argument, default to tail agnostic unless the 555 // destination is tied to a source. Unless the source is undef. In that case 556 // the user would have some control over the policy values. 557 bool TailAgnostic = true; 558 bool UsesMaskPolicy = RISCVII::usesMaskPolicy(TSFlags); 559 // FIXME: Could we look at the above or below instructions to choose the 560 // matched mask policy to reduce vsetvli instructions? Default mask policy is 561 // agnostic if instructions use mask policy, otherwise is undisturbed. Because 562 // most mask operations are mask undisturbed, so we could possibly reduce the 563 // vsetvli between mask and nomasked instruction sequence. 564 bool MaskAgnostic = UsesMaskPolicy; 565 unsigned UseOpIdx; 566 if (RISCVII::hasVecPolicyOp(TSFlags)) { 567 const MachineOperand &Op = MI.getOperand(MI.getNumExplicitOperands() - 1); 568 uint64_t Policy = Op.getImm(); 569 assert(Policy <= (RISCVII::TAIL_AGNOSTIC | RISCVII::MASK_AGNOSTIC) && 570 "Invalid Policy Value"); 571 // Although in some cases, mismatched passthru/maskedoff with policy value 572 // does not make sense (ex. tied operand is IMPLICIT_DEF with non-TAMA 573 // policy, or tied operand is not IMPLICIT_DEF with TAMA policy), but users 574 // have set the policy value explicitly, so compiler would not fix it. 575 TailAgnostic = Policy & RISCVII::TAIL_AGNOSTIC; 576 MaskAgnostic = Policy & RISCVII::MASK_AGNOSTIC; 577 } else if (MI.isRegTiedToUseOperand(0, &UseOpIdx)) { 578 TailAgnostic = false; 579 if (UsesMaskPolicy) 580 MaskAgnostic = false; 581 // If the tied operand is an IMPLICIT_DEF we can keep TailAgnostic. 582 const MachineOperand &UseMO = MI.getOperand(UseOpIdx); 583 MachineInstr *UseMI = MRI->getVRegDef(UseMO.getReg()); 584 if (UseMI) { 585 UseMI = elideCopies(UseMI, MRI); 586 if (UseMI && UseMI->isImplicitDef()) { 587 TailAgnostic = true; 588 if (UsesMaskPolicy) 589 MaskAgnostic = true; 590 } 591 } 592 // Some pseudo instructions force a tail agnostic policy despite having a 593 // tied def. 594 if (RISCVII::doesForceTailAgnostic(TSFlags)) 595 TailAgnostic = true; 596 } 597 598 RISCVII::VLMUL VLMul = RISCVII::getLMul(TSFlags); 599 600 unsigned Log2SEW = MI.getOperand(getSEWOpNum(MI)).getImm(); 601 // A Log2SEW of 0 is an operation on mask registers only. 602 bool MaskRegOp = Log2SEW == 0; 603 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8; 604 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW"); 605 606 // If there are no explicit defs, this is a store instruction which can 607 // ignore the tail and mask policies. 608 bool StoreOp = MI.getNumExplicitDefs() == 0; 609 bool ScalarMovOp = isScalarMoveInstr(MI); 610 611 if (RISCVII::hasVLOp(TSFlags)) { 612 const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); 613 if (VLOp.isImm()) { 614 int64_t Imm = VLOp.getImm(); 615 // Conver the VLMax sentintel to X0 register. 616 if (Imm == RISCV::VLMaxSentinel) 617 InstrInfo.setAVLReg(RISCV::X0); 618 else 619 InstrInfo.setAVLImm(Imm); 620 } else { 621 InstrInfo.setAVLReg(VLOp.getReg()); 622 } 623 } else { 624 InstrInfo.setAVLReg(RISCV::NoRegister); 625 } 626 InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, MaskRegOp, StoreOp, 627 ScalarMovOp); 628 629 return InstrInfo; 630 } 631 632 void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI, 633 const VSETVLIInfo &Info, 634 const VSETVLIInfo &PrevInfo) { 635 DebugLoc DL = MI.getDebugLoc(); 636 insertVSETVLI(MBB, MachineBasicBlock::iterator(&MI), DL, Info, PrevInfo); 637 } 638 639 void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, 640 MachineBasicBlock::iterator InsertPt, DebugLoc DL, 641 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo) { 642 643 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same 644 // VLMAX. 645 if (PrevInfo.isValid() && !PrevInfo.isUnknown() && 646 Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) { 647 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0)) 648 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 649 .addReg(RISCV::X0, RegState::Kill) 650 .addImm(Info.encodeVTYPE()) 651 .addReg(RISCV::VL, RegState::Implicit); 652 return; 653 } 654 655 if (Info.hasAVLImm()) { 656 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI)) 657 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 658 .addImm(Info.getAVLImm()) 659 .addImm(Info.encodeVTYPE()); 660 return; 661 } 662 663 Register AVLReg = Info.getAVLReg(); 664 if (AVLReg == RISCV::NoRegister) { 665 // We can only use x0, x0 if there's no chance of the vtype change causing 666 // the previous vl to become invalid. 667 if (PrevInfo.isValid() && !PrevInfo.isUnknown() && 668 Info.hasSameVLMAX(PrevInfo)) { 669 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0)) 670 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 671 .addReg(RISCV::X0, RegState::Kill) 672 .addImm(Info.encodeVTYPE()) 673 .addReg(RISCV::VL, RegState::Implicit); 674 return; 675 } 676 // Otherwise use an AVL of 0 to avoid depending on previous vl. 677 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI)) 678 .addReg(RISCV::X0, RegState::Define | RegState::Dead) 679 .addImm(0) 680 .addImm(Info.encodeVTYPE()); 681 return; 682 } 683 684 if (AVLReg.isVirtual()) 685 MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass); 686 687 // Use X0 as the DestReg unless AVLReg is X0. We also need to change the 688 // opcode if the AVLReg is X0 as they have different register classes for 689 // the AVL operand. 690 Register DestReg = RISCV::X0; 691 unsigned Opcode = RISCV::PseudoVSETVLI; 692 if (AVLReg == RISCV::X0) { 693 DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); 694 Opcode = RISCV::PseudoVSETVLIX0; 695 } 696 BuildMI(MBB, InsertPt, DL, TII->get(Opcode)) 697 .addReg(DestReg, RegState::Define | RegState::Dead) 698 .addReg(AVLReg) 699 .addImm(Info.encodeVTYPE()); 700 } 701 702 // Return a VSETVLIInfo representing the changes made by this VSETVLI or 703 // VSETIVLI instruction. 704 static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) { 705 VSETVLIInfo NewInfo; 706 if (MI.getOpcode() == RISCV::PseudoVSETIVLI) { 707 NewInfo.setAVLImm(MI.getOperand(1).getImm()); 708 } else { 709 assert(MI.getOpcode() == RISCV::PseudoVSETVLI || 710 MI.getOpcode() == RISCV::PseudoVSETVLIX0); 711 Register AVLReg = MI.getOperand(1).getReg(); 712 assert((AVLReg != RISCV::X0 || MI.getOperand(0).getReg() != RISCV::X0) && 713 "Can't handle X0, X0 vsetvli yet"); 714 NewInfo.setAVLReg(AVLReg); 715 } 716 NewInfo.setVTYPE(MI.getOperand(2).getImm()); 717 718 return NewInfo; 719 } 720 721 bool RISCVInsertVSETVLI::needVSETVLI(const VSETVLIInfo &Require, 722 const VSETVLIInfo &CurInfo) const { 723 if (CurInfo.isCompatible(Require)) 724 return false; 725 726 // We didn't find a compatible value. If our AVL is a virtual register, 727 // it might be defined by a VSET(I)VLI. If it has the same VLMAX we need 728 // and the last VL/VTYPE we observed is the same, we don't need a 729 // VSETVLI here. 730 if (!CurInfo.isUnknown() && Require.hasAVLReg() && 731 Require.getAVLReg().isVirtual() && !CurInfo.hasSEWLMULRatioOnly() && 732 CurInfo.hasCompatibleVTYPE(Require)) { 733 if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { 734 if (isVectorConfigInstr(*DefMI)) { 735 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 736 if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo)) 737 return false; 738 } 739 } 740 } 741 742 return true; 743 } 744 745 bool canSkipVSETVLIForLoadStore(const MachineInstr &MI, 746 const VSETVLIInfo &Require, 747 const VSETVLIInfo &CurInfo) { 748 unsigned EEW; 749 switch (MI.getOpcode()) { 750 default: 751 return false; 752 case RISCV::PseudoVLE8_V_M1: 753 case RISCV::PseudoVLE8_V_M1_MASK: 754 case RISCV::PseudoVLE8_V_M2: 755 case RISCV::PseudoVLE8_V_M2_MASK: 756 case RISCV::PseudoVLE8_V_M4: 757 case RISCV::PseudoVLE8_V_M4_MASK: 758 case RISCV::PseudoVLE8_V_M8: 759 case RISCV::PseudoVLE8_V_M8_MASK: 760 case RISCV::PseudoVLE8_V_MF2: 761 case RISCV::PseudoVLE8_V_MF2_MASK: 762 case RISCV::PseudoVLE8_V_MF4: 763 case RISCV::PseudoVLE8_V_MF4_MASK: 764 case RISCV::PseudoVLE8_V_MF8: 765 case RISCV::PseudoVLE8_V_MF8_MASK: 766 case RISCV::PseudoVLSE8_V_M1: 767 case RISCV::PseudoVLSE8_V_M1_MASK: 768 case RISCV::PseudoVLSE8_V_M2: 769 case RISCV::PseudoVLSE8_V_M2_MASK: 770 case RISCV::PseudoVLSE8_V_M4: 771 case RISCV::PseudoVLSE8_V_M4_MASK: 772 case RISCV::PseudoVLSE8_V_M8: 773 case RISCV::PseudoVLSE8_V_M8_MASK: 774 case RISCV::PseudoVLSE8_V_MF2: 775 case RISCV::PseudoVLSE8_V_MF2_MASK: 776 case RISCV::PseudoVLSE8_V_MF4: 777 case RISCV::PseudoVLSE8_V_MF4_MASK: 778 case RISCV::PseudoVLSE8_V_MF8: 779 case RISCV::PseudoVLSE8_V_MF8_MASK: 780 case RISCV::PseudoVSE8_V_M1: 781 case RISCV::PseudoVSE8_V_M1_MASK: 782 case RISCV::PseudoVSE8_V_M2: 783 case RISCV::PseudoVSE8_V_M2_MASK: 784 case RISCV::PseudoVSE8_V_M4: 785 case RISCV::PseudoVSE8_V_M4_MASK: 786 case RISCV::PseudoVSE8_V_M8: 787 case RISCV::PseudoVSE8_V_M8_MASK: 788 case RISCV::PseudoVSE8_V_MF2: 789 case RISCV::PseudoVSE8_V_MF2_MASK: 790 case RISCV::PseudoVSE8_V_MF4: 791 case RISCV::PseudoVSE8_V_MF4_MASK: 792 case RISCV::PseudoVSE8_V_MF8: 793 case RISCV::PseudoVSE8_V_MF8_MASK: 794 case RISCV::PseudoVSSE8_V_M1: 795 case RISCV::PseudoVSSE8_V_M1_MASK: 796 case RISCV::PseudoVSSE8_V_M2: 797 case RISCV::PseudoVSSE8_V_M2_MASK: 798 case RISCV::PseudoVSSE8_V_M4: 799 case RISCV::PseudoVSSE8_V_M4_MASK: 800 case RISCV::PseudoVSSE8_V_M8: 801 case RISCV::PseudoVSSE8_V_M8_MASK: 802 case RISCV::PseudoVSSE8_V_MF2: 803 case RISCV::PseudoVSSE8_V_MF2_MASK: 804 case RISCV::PseudoVSSE8_V_MF4: 805 case RISCV::PseudoVSSE8_V_MF4_MASK: 806 case RISCV::PseudoVSSE8_V_MF8: 807 case RISCV::PseudoVSSE8_V_MF8_MASK: 808 EEW = 8; 809 break; 810 case RISCV::PseudoVLE16_V_M1: 811 case RISCV::PseudoVLE16_V_M1_MASK: 812 case RISCV::PseudoVLE16_V_M2: 813 case RISCV::PseudoVLE16_V_M2_MASK: 814 case RISCV::PseudoVLE16_V_M4: 815 case RISCV::PseudoVLE16_V_M4_MASK: 816 case RISCV::PseudoVLE16_V_M8: 817 case RISCV::PseudoVLE16_V_M8_MASK: 818 case RISCV::PseudoVLE16_V_MF2: 819 case RISCV::PseudoVLE16_V_MF2_MASK: 820 case RISCV::PseudoVLE16_V_MF4: 821 case RISCV::PseudoVLE16_V_MF4_MASK: 822 case RISCV::PseudoVLSE16_V_M1: 823 case RISCV::PseudoVLSE16_V_M1_MASK: 824 case RISCV::PseudoVLSE16_V_M2: 825 case RISCV::PseudoVLSE16_V_M2_MASK: 826 case RISCV::PseudoVLSE16_V_M4: 827 case RISCV::PseudoVLSE16_V_M4_MASK: 828 case RISCV::PseudoVLSE16_V_M8: 829 case RISCV::PseudoVLSE16_V_M8_MASK: 830 case RISCV::PseudoVLSE16_V_MF2: 831 case RISCV::PseudoVLSE16_V_MF2_MASK: 832 case RISCV::PseudoVLSE16_V_MF4: 833 case RISCV::PseudoVLSE16_V_MF4_MASK: 834 case RISCV::PseudoVSE16_V_M1: 835 case RISCV::PseudoVSE16_V_M1_MASK: 836 case RISCV::PseudoVSE16_V_M2: 837 case RISCV::PseudoVSE16_V_M2_MASK: 838 case RISCV::PseudoVSE16_V_M4: 839 case RISCV::PseudoVSE16_V_M4_MASK: 840 case RISCV::PseudoVSE16_V_M8: 841 case RISCV::PseudoVSE16_V_M8_MASK: 842 case RISCV::PseudoVSE16_V_MF2: 843 case RISCV::PseudoVSE16_V_MF2_MASK: 844 case RISCV::PseudoVSE16_V_MF4: 845 case RISCV::PseudoVSE16_V_MF4_MASK: 846 case RISCV::PseudoVSSE16_V_M1: 847 case RISCV::PseudoVSSE16_V_M1_MASK: 848 case RISCV::PseudoVSSE16_V_M2: 849 case RISCV::PseudoVSSE16_V_M2_MASK: 850 case RISCV::PseudoVSSE16_V_M4: 851 case RISCV::PseudoVSSE16_V_M4_MASK: 852 case RISCV::PseudoVSSE16_V_M8: 853 case RISCV::PseudoVSSE16_V_M8_MASK: 854 case RISCV::PseudoVSSE16_V_MF2: 855 case RISCV::PseudoVSSE16_V_MF2_MASK: 856 case RISCV::PseudoVSSE16_V_MF4: 857 case RISCV::PseudoVSSE16_V_MF4_MASK: 858 EEW = 16; 859 break; 860 case RISCV::PseudoVLE32_V_M1: 861 case RISCV::PseudoVLE32_V_M1_MASK: 862 case RISCV::PseudoVLE32_V_M2: 863 case RISCV::PseudoVLE32_V_M2_MASK: 864 case RISCV::PseudoVLE32_V_M4: 865 case RISCV::PseudoVLE32_V_M4_MASK: 866 case RISCV::PseudoVLE32_V_M8: 867 case RISCV::PseudoVLE32_V_M8_MASK: 868 case RISCV::PseudoVLE32_V_MF2: 869 case RISCV::PseudoVLE32_V_MF2_MASK: 870 case RISCV::PseudoVLSE32_V_M1: 871 case RISCV::PseudoVLSE32_V_M1_MASK: 872 case RISCV::PseudoVLSE32_V_M2: 873 case RISCV::PseudoVLSE32_V_M2_MASK: 874 case RISCV::PseudoVLSE32_V_M4: 875 case RISCV::PseudoVLSE32_V_M4_MASK: 876 case RISCV::PseudoVLSE32_V_M8: 877 case RISCV::PseudoVLSE32_V_M8_MASK: 878 case RISCV::PseudoVLSE32_V_MF2: 879 case RISCV::PseudoVLSE32_V_MF2_MASK: 880 case RISCV::PseudoVSE32_V_M1: 881 case RISCV::PseudoVSE32_V_M1_MASK: 882 case RISCV::PseudoVSE32_V_M2: 883 case RISCV::PseudoVSE32_V_M2_MASK: 884 case RISCV::PseudoVSE32_V_M4: 885 case RISCV::PseudoVSE32_V_M4_MASK: 886 case RISCV::PseudoVSE32_V_M8: 887 case RISCV::PseudoVSE32_V_M8_MASK: 888 case RISCV::PseudoVSE32_V_MF2: 889 case RISCV::PseudoVSE32_V_MF2_MASK: 890 case RISCV::PseudoVSSE32_V_M1: 891 case RISCV::PseudoVSSE32_V_M1_MASK: 892 case RISCV::PseudoVSSE32_V_M2: 893 case RISCV::PseudoVSSE32_V_M2_MASK: 894 case RISCV::PseudoVSSE32_V_M4: 895 case RISCV::PseudoVSSE32_V_M4_MASK: 896 case RISCV::PseudoVSSE32_V_M8: 897 case RISCV::PseudoVSSE32_V_M8_MASK: 898 case RISCV::PseudoVSSE32_V_MF2: 899 case RISCV::PseudoVSSE32_V_MF2_MASK: 900 EEW = 32; 901 break; 902 case RISCV::PseudoVLE64_V_M1: 903 case RISCV::PseudoVLE64_V_M1_MASK: 904 case RISCV::PseudoVLE64_V_M2: 905 case RISCV::PseudoVLE64_V_M2_MASK: 906 case RISCV::PseudoVLE64_V_M4: 907 case RISCV::PseudoVLE64_V_M4_MASK: 908 case RISCV::PseudoVLE64_V_M8: 909 case RISCV::PseudoVLE64_V_M8_MASK: 910 case RISCV::PseudoVLSE64_V_M1: 911 case RISCV::PseudoVLSE64_V_M1_MASK: 912 case RISCV::PseudoVLSE64_V_M2: 913 case RISCV::PseudoVLSE64_V_M2_MASK: 914 case RISCV::PseudoVLSE64_V_M4: 915 case RISCV::PseudoVLSE64_V_M4_MASK: 916 case RISCV::PseudoVLSE64_V_M8: 917 case RISCV::PseudoVLSE64_V_M8_MASK: 918 case RISCV::PseudoVSE64_V_M1: 919 case RISCV::PseudoVSE64_V_M1_MASK: 920 case RISCV::PseudoVSE64_V_M2: 921 case RISCV::PseudoVSE64_V_M2_MASK: 922 case RISCV::PseudoVSE64_V_M4: 923 case RISCV::PseudoVSE64_V_M4_MASK: 924 case RISCV::PseudoVSE64_V_M8: 925 case RISCV::PseudoVSE64_V_M8_MASK: 926 case RISCV::PseudoVSSE64_V_M1: 927 case RISCV::PseudoVSSE64_V_M1_MASK: 928 case RISCV::PseudoVSSE64_V_M2: 929 case RISCV::PseudoVSSE64_V_M2_MASK: 930 case RISCV::PseudoVSSE64_V_M4: 931 case RISCV::PseudoVSSE64_V_M4_MASK: 932 case RISCV::PseudoVSSE64_V_M8: 933 case RISCV::PseudoVSSE64_V_M8_MASK: 934 EEW = 64; 935 break; 936 } 937 938 return CurInfo.isCompatibleWithLoadStoreEEW(EEW, Require); 939 } 940 941 bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI, const VSETVLIInfo &Require, 942 const VSETVLIInfo &CurInfo) const { 943 if (!needVSETVLI(Require, CurInfo)) 944 return false; 945 // If this is a unit-stride or strided load/store, we may be able to use the 946 // EMUL=(EEW/SEW)*LMUL relationship to avoid changing VTYPE. 947 return !canSkipVSETVLIForLoadStore(MI, Require, CurInfo); 948 } 949 950 bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB) { 951 bool HadVectorOp = false; 952 953 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 954 BBInfo.Change = BBInfo.Pred; 955 for (const MachineInstr &MI : MBB) { 956 // If this is an explicit VSETVLI or VSETIVLI, update our state. 957 if (isVectorConfigInstr(MI)) { 958 HadVectorOp = true; 959 BBInfo.Change = getInfoForVSETVLI(MI); 960 continue; 961 } 962 963 uint64_t TSFlags = MI.getDesc().TSFlags; 964 if (RISCVII::hasSEWOp(TSFlags)) { 965 HadVectorOp = true; 966 967 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 968 969 if (!BBInfo.Change.isValid()) { 970 BBInfo.Change = NewInfo; 971 } else { 972 // If this instruction isn't compatible with the previous VL/VTYPE 973 // we need to insert a VSETVLI. 974 // NOTE: We only do this if the vtype we're comparing against was 975 // created in this block. We need the first and third phase to treat 976 // the store the same way. 977 if (needVSETVLI(MI, NewInfo, BBInfo.Change)) 978 BBInfo.Change = NewInfo; 979 } 980 } 981 982 // If this is something that updates VL/VTYPE that we don't know about, set 983 // the state to unknown. 984 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 985 MI.modifiesRegister(RISCV::VTYPE)) 986 BBInfo.Change = VSETVLIInfo::getUnknown(); 987 } 988 989 return HadVectorOp; 990 } 991 992 void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) { 993 994 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 995 996 BBInfo.InQueue = false; 997 998 VSETVLIInfo InInfo; 999 if (MBB.pred_empty()) { 1000 // There are no predecessors, so use the default starting status. 1001 InInfo.setUnknown(); 1002 } else { 1003 for (MachineBasicBlock *P : MBB.predecessors()) 1004 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit); 1005 } 1006 1007 // If we don't have any valid predecessor value, wait until we do. 1008 if (!InInfo.isValid()) 1009 return; 1010 1011 // If no change, no need to rerun block 1012 if (InInfo == BBInfo.Pred) 1013 return; 1014 1015 BBInfo.Pred = InInfo; 1016 LLVM_DEBUG(dbgs() << "Entry state of " << printMBBReference(MBB) 1017 << " changed to " << BBInfo.Pred << "\n"); 1018 1019 // Note: It's tempting to cache the state changes here, but due to the 1020 // compatibility checks performed a blocks output state can change based on 1021 // the input state. To cache, we'd have to add logic for finding 1022 // never-compatible state changes. 1023 computeVLVTYPEChanges(MBB); 1024 VSETVLIInfo TmpStatus = BBInfo.Change; 1025 1026 // If the new exit value matches the old exit value, we don't need to revisit 1027 // any blocks. 1028 if (BBInfo.Exit == TmpStatus) 1029 return; 1030 1031 BBInfo.Exit = TmpStatus; 1032 LLVM_DEBUG(dbgs() << "Exit state of " << printMBBReference(MBB) 1033 << " changed to " << BBInfo.Exit << "\n"); 1034 1035 // Add the successors to the work list so we can propagate the changed exit 1036 // status. 1037 for (MachineBasicBlock *S : MBB.successors()) 1038 if (!BlockInfo[S->getNumber()].InQueue) 1039 WorkList.push(S); 1040 } 1041 1042 // If we weren't able to prove a vsetvli was directly unneeded, it might still 1043 // be unneeded if the AVL is a phi node where all incoming values are VL 1044 // outputs from the last VSETVLI in their respective basic blocks. 1045 bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, 1046 const MachineBasicBlock &MBB) const { 1047 if (DisableInsertVSETVLPHIOpt) 1048 return true; 1049 1050 if (!Require.hasAVLReg()) 1051 return true; 1052 1053 Register AVLReg = Require.getAVLReg(); 1054 if (!AVLReg.isVirtual()) 1055 return true; 1056 1057 // We need the AVL to be produce by a PHI node in this basic block. 1058 MachineInstr *PHI = MRI->getVRegDef(AVLReg); 1059 if (!PHI || PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB) 1060 return true; 1061 1062 for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps; 1063 PHIOp += 2) { 1064 Register InReg = PHI->getOperand(PHIOp).getReg(); 1065 MachineBasicBlock *PBB = PHI->getOperand(PHIOp + 1).getMBB(); 1066 const BlockData &PBBInfo = BlockInfo[PBB->getNumber()]; 1067 // If the exit from the predecessor has the VTYPE we are looking for 1068 // we might be able to avoid a VSETVLI. 1069 if (PBBInfo.Exit.isUnknown() || !PBBInfo.Exit.hasCompatibleVTYPE(Require)) 1070 return true; 1071 1072 // We need the PHI input to the be the output of a VSET(I)VLI. 1073 MachineInstr *DefMI = MRI->getVRegDef(InReg); 1074 if (!DefMI || !isVectorConfigInstr(*DefMI)) 1075 return true; 1076 1077 // We found a VSET(I)VLI make sure it matches the output of the 1078 // predecessor block. 1079 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 1080 if (!DefInfo.hasSameAVL(PBBInfo.Exit) || 1081 !DefInfo.hasSameVTYPE(PBBInfo.Exit)) 1082 return true; 1083 } 1084 1085 // If all the incoming values to the PHI checked out, we don't need 1086 // to insert a VSETVLI. 1087 return false; 1088 } 1089 1090 void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { 1091 VSETVLIInfo CurInfo; 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 continue; 1103 } 1104 1105 uint64_t TSFlags = MI.getDesc().TSFlags; 1106 if (RISCVII::hasSEWOp(TSFlags)) { 1107 VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 1108 if (RISCVII::hasVLOp(TSFlags)) { 1109 MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); 1110 if (VLOp.isReg()) { 1111 // Erase the AVL operand from the instruction. 1112 VLOp.setReg(RISCV::NoRegister); 1113 VLOp.setIsKill(false); 1114 } 1115 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false, 1116 /*isImp*/ true)); 1117 } 1118 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false, 1119 /*isImp*/ true)); 1120 1121 if (!CurInfo.isValid()) { 1122 // We haven't found any vector instructions or VL/VTYPE changes yet, 1123 // use the predecessor information. 1124 CurInfo = BlockInfo[MBB.getNumber()].Pred; 1125 assert(CurInfo.isValid() && "Expected a valid predecessor state."); 1126 if (needVSETVLI(NewInfo, CurInfo)) { 1127 // If this is the first implicit state change, and the state change 1128 // requested can be proven to produce the same register contents, we 1129 // can skip emitting the actual state change and continue as if we 1130 // had since we know the GPR result of the implicit state change 1131 // wouldn't be used and VL/VTYPE registers are correct. Note that 1132 // we *do* need to model the state as if it changed as while the 1133 // register contents are unchanged, the abstract model can change. 1134 if (needVSETVLIPHI(NewInfo, MBB)) 1135 insertVSETVLI(MBB, MI, NewInfo, CurInfo); 1136 CurInfo = NewInfo; 1137 } 1138 } else { 1139 // If this instruction isn't compatible with the previous VL/VTYPE 1140 // we need to insert a VSETVLI. 1141 // NOTE: We can't use predecessor information for the store. We must 1142 // treat it the same as the first phase so that we produce the correct 1143 // vl/vtype for succesor blocks. 1144 if (needVSETVLI(MI, NewInfo, CurInfo)) { 1145 insertVSETVLI(MBB, MI, NewInfo, CurInfo); 1146 CurInfo = NewInfo; 1147 } 1148 } 1149 } 1150 1151 // If this is something that updates VL/VTYPE that we don't know about, set 1152 // the state to unknown. 1153 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 1154 MI.modifiesRegister(RISCV::VTYPE)) { 1155 CurInfo = VSETVLIInfo::getUnknown(); 1156 } 1157 } 1158 1159 // If we reach the end of the block and our current info doesn't match the 1160 // expected info, insert a vsetvli to correct. 1161 if (!UseStrictAsserts) { 1162 const VSETVLIInfo &ExitInfo = BlockInfo[MBB.getNumber()].Exit; 1163 if (CurInfo.isValid() && ExitInfo.isValid() && !ExitInfo.isUnknown() && 1164 CurInfo != ExitInfo) { 1165 // Note there's an implicit assumption here that terminators never use 1166 // or modify VL or VTYPE. Also, fallthrough will return end(). 1167 auto InsertPt = MBB.getFirstInstrTerminator(); 1168 insertVSETVLI(MBB, InsertPt, MBB.findDebugLoc(InsertPt), ExitInfo, CurInfo); 1169 CurInfo = ExitInfo; 1170 } 1171 } 1172 1173 if (UseStrictAsserts && CurInfo.isValid()) { 1174 const auto &Info = BlockInfo[MBB.getNumber()]; 1175 if (CurInfo != Info.Exit) { 1176 LLVM_DEBUG(dbgs() << "in block " << printMBBReference(MBB) << "\n"); 1177 LLVM_DEBUG(dbgs() << " begin state: " << Info.Pred << "\n"); 1178 LLVM_DEBUG(dbgs() << " expected end state: " << Info.Exit << "\n"); 1179 LLVM_DEBUG(dbgs() << " actual end state: " << CurInfo << "\n"); 1180 } 1181 assert(CurInfo == Info.Exit && 1182 "InsertVSETVLI dataflow invariant violated"); 1183 } 1184 } 1185 1186 void RISCVInsertVSETVLI::doLocalPrepass(MachineBasicBlock &MBB) { 1187 VSETVLIInfo CurInfo = VSETVLIInfo::getUnknown(); 1188 for (MachineInstr &MI : MBB) { 1189 // If this is an explicit VSETVLI or VSETIVLI, update our state. 1190 if (isVectorConfigInstr(MI)) { 1191 CurInfo = getInfoForVSETVLI(MI); 1192 continue; 1193 } 1194 1195 const uint64_t TSFlags = MI.getDesc().TSFlags; 1196 if (isScalarMoveInstr(MI)) { 1197 assert(RISCVII::hasSEWOp(TSFlags) && RISCVII::hasVLOp(TSFlags)); 1198 const VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); 1199 1200 // For vmv.s.x and vfmv.s.f, there are only two behaviors, VL = 0 and 1201 // VL > 0. We can discard the user requested AVL and just use the last 1202 // one if we can prove it equally zero. This removes a vsetvli entirely 1203 // if the types match or allows use of cheaper avl preserving variant 1204 // if VLMAX doesn't change. If VLMAX might change, we couldn't use 1205 // the 'vsetvli x0, x0, vtype" variant, so we avoid the transform to 1206 // prevent extending live range of an avl register operand. 1207 // TODO: We can probably relax this for immediates. 1208 if (((CurInfo.hasNonZeroAVL() && NewInfo.hasNonZeroAVL()) || 1209 (CurInfo.hasZeroAVL() && NewInfo.hasZeroAVL())) && 1210 NewInfo.hasSameVLMAX(CurInfo)) { 1211 MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); 1212 if (CurInfo.hasAVLImm()) 1213 VLOp.ChangeToImmediate(CurInfo.getAVLImm()); 1214 else 1215 VLOp.ChangeToRegister(CurInfo.getAVLReg(), /*IsDef*/ false); 1216 CurInfo = computeInfoForInstr(MI, TSFlags, MRI); 1217 continue; 1218 } 1219 } 1220 1221 if (RISCVII::hasSEWOp(TSFlags)) { 1222 if (RISCVII::hasVLOp(TSFlags)) { 1223 const auto Require = computeInfoForInstr(MI, TSFlags, MRI); 1224 // If the AVL is the result of a previous vsetvli which has the 1225 // same AVL and VLMAX as our current state, we can reuse the AVL 1226 // from the current state for the new one. This allows us to 1227 // generate 'vsetvli x0, x0, vtype" or possible skip the transition 1228 // entirely. 1229 if (!CurInfo.isUnknown() && Require.hasAVLReg() && 1230 Require.getAVLReg().isVirtual()) { 1231 if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { 1232 if (isVectorConfigInstr(*DefMI)) { 1233 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 1234 if (DefInfo.hasSameAVL(CurInfo) && 1235 DefInfo.hasSameVLMAX(CurInfo)) { 1236 MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); 1237 if (CurInfo.hasAVLImm()) 1238 VLOp.ChangeToImmediate(CurInfo.getAVLImm()); 1239 else { 1240 MRI->clearKillFlags(CurInfo.getAVLReg()); 1241 VLOp.ChangeToRegister(CurInfo.getAVLReg(), /*IsDef*/ false); 1242 } 1243 CurInfo = computeInfoForInstr(MI, TSFlags, MRI); 1244 continue; 1245 } 1246 } 1247 } 1248 } 1249 1250 // If AVL is defined by a vsetvli with the same VLMAX, we can 1251 // replace the AVL operand with the AVL of the defining vsetvli. 1252 // We avoid general register AVLs to avoid extending live ranges 1253 // without being sure we can kill the original source reg entirely. 1254 // TODO: We can ignore policy bits here, we only need VL to be the same. 1255 if (Require.hasAVLReg() && Require.getAVLReg().isVirtual()) { 1256 if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { 1257 if (isVectorConfigInstr(*DefMI)) { 1258 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); 1259 if (DefInfo.hasSameVLMAX(Require) && 1260 (DefInfo.hasAVLImm() || DefInfo.getAVLReg() == RISCV::X0)) { 1261 MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); 1262 if (DefInfo.hasAVLImm()) 1263 VLOp.ChangeToImmediate(DefInfo.getAVLImm()); 1264 else 1265 VLOp.ChangeToRegister(DefInfo.getAVLReg(), /*IsDef*/ false); 1266 CurInfo = computeInfoForInstr(MI, TSFlags, MRI); 1267 continue; 1268 } 1269 } 1270 } 1271 } 1272 } 1273 CurInfo = computeInfoForInstr(MI, TSFlags, MRI); 1274 continue; 1275 } 1276 1277 // If this is something that updates VL/VTYPE that we don't know about, 1278 // set the state to unknown. 1279 if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || 1280 MI.modifiesRegister(RISCV::VTYPE)) 1281 CurInfo = VSETVLIInfo::getUnknown(); 1282 } 1283 } 1284 1285 /// Return true if the VL value configured must be equal to the requested one. 1286 static bool hasFixedResult(const VSETVLIInfo &Info, const RISCVSubtarget &ST) { 1287 if (!Info.hasAVLImm()) 1288 // VLMAX is always the same value. 1289 // TODO: Could extend to other registers by looking at the associated vreg 1290 // def placement. 1291 return RISCV::X0 == Info.getAVLReg(); 1292 1293 unsigned AVL = Info.getAVLImm(); 1294 unsigned SEW = Info.getSEW(); 1295 unsigned AVLInBits = AVL * SEW; 1296 1297 unsigned LMul; 1298 bool Fractional; 1299 std::tie(LMul, Fractional) = RISCVVType::decodeVLMUL(Info.getVLMUL()); 1300 1301 if (Fractional) 1302 return ST.getRealMinVLen() / LMul >= AVLInBits; 1303 return ST.getRealMinVLen() * LMul >= AVLInBits; 1304 } 1305 1306 /// Perform simple partial redundancy elimination of the VSETVLI instructions 1307 /// we're about to insert by looking for cases where we can PRE from the 1308 /// beginning of one block to the end of one of its predecessors. Specifically, 1309 /// this is geared to catch the common case of a fixed length vsetvl in a single 1310 /// block loop when it could execute once in the preheader instead. 1311 void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) { 1312 const MachineFunction &MF = *MBB.getParent(); 1313 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 1314 1315 if (!BlockInfo[MBB.getNumber()].Pred.isUnknown()) 1316 return; 1317 1318 MachineBasicBlock *UnavailablePred = nullptr; 1319 VSETVLIInfo AvailableInfo; 1320 for (MachineBasicBlock *P : MBB.predecessors()) { 1321 const VSETVLIInfo &PredInfo = BlockInfo[P->getNumber()].Exit; 1322 if (PredInfo.isUnknown()) { 1323 if (UnavailablePred) 1324 return; 1325 UnavailablePred = P; 1326 } else if (!AvailableInfo.isValid()) { 1327 AvailableInfo = PredInfo; 1328 } else if (AvailableInfo != PredInfo) { 1329 return; 1330 } 1331 } 1332 1333 // Unreachable, single pred, or full redundancy. Note that FRE is handled by 1334 // phase 3. 1335 if (!UnavailablePred || !AvailableInfo.isValid()) 1336 return; 1337 1338 // Critical edge - TODO: consider splitting? 1339 if (UnavailablePred->succ_size() != 1) 1340 return; 1341 1342 // If VL can be less than AVL, then we can't reduce the frequency of exec. 1343 if (!hasFixedResult(AvailableInfo, ST)) 1344 return; 1345 1346 // Does it actually let us remove an implicit transition in MBB? 1347 bool Found = false; 1348 for (auto &MI : MBB) { 1349 if (isVectorConfigInstr(MI)) 1350 return; 1351 1352 const uint64_t TSFlags = MI.getDesc().TSFlags; 1353 if (RISCVII::hasSEWOp(TSFlags)) { 1354 if (AvailableInfo != computeInfoForInstr(MI, TSFlags, MRI)) 1355 return; 1356 Found = true; 1357 break; 1358 } 1359 } 1360 if (!Found) 1361 return; 1362 1363 // Finally, update both data flow state and insert the actual vsetvli. 1364 // Doing both keeps the code in sync with the dataflow results, which 1365 // is critical for correctness of phase 3. 1366 auto OldInfo = BlockInfo[UnavailablePred->getNumber()].Exit; 1367 LLVM_DEBUG(dbgs() << "PRE VSETVLI from " << MBB.getName() << " to " 1368 << UnavailablePred->getName() << " with state " 1369 << AvailableInfo << "\n"); 1370 BlockInfo[UnavailablePred->getNumber()].Exit = AvailableInfo; 1371 BlockInfo[MBB.getNumber()].Pred = AvailableInfo; 1372 1373 // Note there's an implicit assumption here that terminators never use 1374 // or modify VL or VTYPE. Also, fallthrough will return end(). 1375 auto InsertPt = UnavailablePred->getFirstInstrTerminator(); 1376 insertVSETVLI(*UnavailablePred, InsertPt, 1377 UnavailablePred->findDebugLoc(InsertPt), 1378 AvailableInfo, OldInfo); 1379 } 1380 1381 void RISCVInsertVSETVLI::doLocalPostpass(MachineBasicBlock &MBB) { 1382 MachineInstr *PrevMI = nullptr; 1383 bool UsedVL = false, UsedVTYPE = false; 1384 SmallVector<MachineInstr*> ToDelete; 1385 for (MachineInstr &MI : MBB) { 1386 // Note: Must be *before* vsetvli handling to account for config cases 1387 // which only change some subfields. 1388 if (MI.isCall() || MI.isInlineAsm() || MI.readsRegister(RISCV::VL)) 1389 UsedVL = true; 1390 if (MI.isCall() || MI.isInlineAsm() || MI.readsRegister(RISCV::VTYPE)) 1391 UsedVTYPE = true; 1392 1393 if (!isVectorConfigInstr(MI)) 1394 continue; 1395 1396 if (PrevMI) { 1397 if (!UsedVL && !UsedVTYPE) { 1398 ToDelete.push_back(PrevMI); 1399 // fallthrough 1400 } else if (!UsedVTYPE && isVLPreservingConfig(MI)) { 1401 // Note: `vsetvli x0, x0, vtype' is the canonical instruction 1402 // for this case. If you find yourself wanting to add other forms 1403 // to this "unused VTYPE" case, we're probably missing a 1404 // canonicalization earlier. 1405 // Note: We don't need to explicitly check vtype compatibility 1406 // here because this form is only legal (per ISA) when not 1407 // changing VL. 1408 PrevMI->getOperand(2).setImm(MI.getOperand(2).getImm()); 1409 ToDelete.push_back(&MI); 1410 // Leave PrevMI unchanged 1411 continue; 1412 } 1413 } 1414 PrevMI = &MI; 1415 UsedVL = false; 1416 UsedVTYPE = false; 1417 Register VRegDef = MI.getOperand(0).getReg(); 1418 if (VRegDef != RISCV::X0 && 1419 !(VRegDef.isVirtual() && MRI->use_nodbg_empty(VRegDef))) 1420 UsedVL = true; 1421 } 1422 1423 for (auto *MI : ToDelete) 1424 MI->eraseFromParent(); 1425 } 1426 1427 bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { 1428 // Skip if the vector extension is not enabled. 1429 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>(); 1430 if (!ST.hasVInstructions()) 1431 return false; 1432 1433 LLVM_DEBUG(dbgs() << "Entering InsertVSETVLI for " << MF.getName() << "\n"); 1434 1435 TII = ST.getInstrInfo(); 1436 MRI = &MF.getRegInfo(); 1437 1438 assert(BlockInfo.empty() && "Expect empty block infos"); 1439 BlockInfo.resize(MF.getNumBlockIDs()); 1440 1441 // Scan the block locally for cases where we can mutate the operands 1442 // of the instructions to reduce state transitions. Critically, this 1443 // must be done before we start propagating data flow states as these 1444 // transforms are allowed to change the contents of VTYPE and VL so 1445 // long as the semantics of the program stays the same. 1446 for (MachineBasicBlock &MBB : MF) 1447 doLocalPrepass(MBB); 1448 1449 bool HaveVectorOp = false; 1450 1451 // Phase 1 - determine how VL/VTYPE are affected by the each block. 1452 for (const MachineBasicBlock &MBB : MF) { 1453 HaveVectorOp |= computeVLVTYPEChanges(MBB); 1454 // Initial exit state is whatever change we found in the block. 1455 BlockData &BBInfo = BlockInfo[MBB.getNumber()]; 1456 BBInfo.Exit = BBInfo.Change; 1457 LLVM_DEBUG(dbgs() << "Initial exit state of " << printMBBReference(MBB) 1458 << " is " << BBInfo.Exit << "\n"); 1459 1460 } 1461 1462 // If we didn't find any instructions that need VSETVLI, we're done. 1463 if (!HaveVectorOp) { 1464 BlockInfo.clear(); 1465 return false; 1466 } 1467 1468 // Phase 2 - determine the exit VL/VTYPE from each block. We add all 1469 // blocks to the list here, but will also add any that need to be revisited 1470 // during Phase 2 processing. 1471 for (const MachineBasicBlock &MBB : MF) { 1472 WorkList.push(&MBB); 1473 BlockInfo[MBB.getNumber()].InQueue = true; 1474 } 1475 while (!WorkList.empty()) { 1476 const MachineBasicBlock &MBB = *WorkList.front(); 1477 WorkList.pop(); 1478 computeIncomingVLVTYPE(MBB); 1479 } 1480 1481 // Perform partial redundancy elimination of vsetvli transitions. 1482 for (MachineBasicBlock &MBB : MF) 1483 doPRE(MBB); 1484 1485 // Phase 3 - add any vsetvli instructions needed in the block. Use the 1486 // Phase 2 information to avoid adding vsetvlis before the first vector 1487 // instruction in the block if the VL/VTYPE is satisfied by its 1488 // predecessors. 1489 for (MachineBasicBlock &MBB : MF) 1490 emitVSETVLIs(MBB); 1491 1492 // Now that all vsetvlis are explicit, go through and do block local 1493 // DSE and peephole based demanded fields based transforms. Note that 1494 // this *must* be done outside the main dataflow so long as we allow 1495 // any cross block analysis within the dataflow. We can't have both 1496 // demanded fields based mutation and non-local analysis in the 1497 // dataflow at the same time without introducing inconsistencies. 1498 for (MachineBasicBlock &MBB : MF) 1499 doLocalPostpass(MBB); 1500 1501 // Once we're fully done rewriting all the instructions, do a final pass 1502 // through to check for VSETVLIs which write to an unused destination. 1503 // For the non X0, X0 variant, we can replace the destination register 1504 // with X0 to reduce register pressure. This is really a generic 1505 // optimization which can be applied to any dead def (TODO: generalize). 1506 for (MachineBasicBlock &MBB : MF) { 1507 for (MachineInstr &MI : MBB) { 1508 if (MI.getOpcode() == RISCV::PseudoVSETVLI || 1509 MI.getOpcode() == RISCV::PseudoVSETIVLI) { 1510 Register VRegDef = MI.getOperand(0).getReg(); 1511 if (VRegDef != RISCV::X0 && MRI->use_nodbg_empty(VRegDef)) 1512 MI.getOperand(0).setReg(RISCV::X0); 1513 } 1514 } 1515 } 1516 1517 BlockInfo.clear(); 1518 return HaveVectorOp; 1519 } 1520 1521 /// Returns an instance of the Insert VSETVLI pass. 1522 FunctionPass *llvm::createRISCVInsertVSETVLIPass() { 1523 return new RISCVInsertVSETVLI(); 1524 } 1525