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