LLVM 22.0.0git
RISCVInsertVSETVLI.cpp
Go to the documentation of this file.
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 and expands the vl outputs of VLEFF/VLSEGFF to PseudoReadVL
11// instructions.
12//
13// This pass consists of 3 phases:
14//
15// Phase 1 collects how each basic block affects VL/VTYPE.
16//
17// Phase 2 uses the information from phase 1 to do a data flow analysis to
18// propagate the VL/VTYPE changes through the function. This gives us the
19// VL/VTYPE at the start of each basic block.
20//
21// Phase 3 inserts VSETVLI instructions in each basic block. Information from
22// phase 2 is used to prevent inserting a VSETVLI before the first vector
23// instruction in the block if possible.
24//
25//===----------------------------------------------------------------------===//
26
27#include "RISCV.h"
28#include "RISCVSubtarget.h"
30#include "llvm/ADT/Statistic.h"
35#include <queue>
36using namespace llvm;
37
38#define DEBUG_TYPE "riscv-insert-vsetvli"
39#define RISCV_INSERT_VSETVLI_NAME "RISC-V Insert VSETVLI pass"
40
41STATISTIC(NumInsertedVSETVL, "Number of VSETVL inst inserted");
42STATISTIC(NumCoalescedVSETVL, "Number of VSETVL inst coalesced");
43
45 DEBUG_TYPE "-whole-vector-register-move-valid-vtype", cl::Hidden,
46 cl::desc("Insert vsetvlis before vmvNr.vs to ensure vtype is valid and "
47 "vill is cleared"),
48 cl::init(true));
49
50namespace {
51
52/// Given a virtual register \p Reg, return the corresponding VNInfo for it.
53/// This will return nullptr if the virtual register is an implicit_def or
54/// if LiveIntervals is not available.
55static VNInfo *getVNInfoFromReg(Register Reg, const MachineInstr &MI,
56 const LiveIntervals *LIS) {
57 assert(Reg.isVirtual());
58 if (!LIS)
59 return nullptr;
60 auto &LI = LIS->getInterval(Reg);
62 return LI.getVNInfoBefore(SI);
63}
64
65static unsigned getVLOpNum(const MachineInstr &MI) {
66 return RISCVII::getVLOpNum(MI.getDesc());
67}
68
69static unsigned getSEWOpNum(const MachineInstr &MI) {
70 return RISCVII::getSEWOpNum(MI.getDesc());
71}
72
73static unsigned getVecPolicyOpNum(const MachineInstr &MI) {
74 return RISCVII::getVecPolicyOpNum(MI.getDesc());
75}
76
77/// Get the EEW for a load or store instruction. Return std::nullopt if MI is
78/// not a load or store which ignores SEW.
79static std::optional<unsigned> getEEWForLoadStore(const MachineInstr &MI) {
80 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
81 default:
82 return std::nullopt;
83 case RISCV::VLE8_V:
84 case RISCV::VLSE8_V:
85 case RISCV::VSE8_V:
86 case RISCV::VSSE8_V:
87 return 8;
88 case RISCV::VLE16_V:
89 case RISCV::VLSE16_V:
90 case RISCV::VSE16_V:
91 case RISCV::VSSE16_V:
92 return 16;
93 case RISCV::VLE32_V:
94 case RISCV::VLSE32_V:
95 case RISCV::VSE32_V:
96 case RISCV::VSSE32_V:
97 return 32;
98 case RISCV::VLE64_V:
99 case RISCV::VLSE64_V:
100 case RISCV::VSE64_V:
101 case RISCV::VSSE64_V:
102 return 64;
103 }
104}
105
106/// Return true if this is an operation on mask registers. Note that
107/// this includes both arithmetic/logical ops and load/store (vlm/vsm).
108static bool isMaskRegOp(const MachineInstr &MI) {
109 if (!RISCVII::hasSEWOp(MI.getDesc().TSFlags))
110 return false;
111 const unsigned Log2SEW = MI.getOperand(getSEWOpNum(MI)).getImm();
112 // A Log2SEW of 0 is an operation on mask registers only.
113 return Log2SEW == 0;
114}
115
116/// Return true if the inactive elements in the result are entirely undefined.
117/// Note that this is different from "agnostic" as defined by the vector
118/// specification. Agnostic requires each lane to either be undisturbed, or
119/// take the value -1; no other value is allowed.
120static bool hasUndefinedPassthru(const MachineInstr &MI) {
121
122 unsigned UseOpIdx;
123 if (!MI.isRegTiedToUseOperand(0, &UseOpIdx))
124 // If there is no passthrough operand, then the pass through
125 // lanes are undefined.
126 return true;
127
128 // All undefined passthrus should be $noreg: see
129 // RISCVDAGToDAGISel::doPeepholeNoRegPassThru
130 const MachineOperand &UseMO = MI.getOperand(UseOpIdx);
131 return !UseMO.getReg().isValid() || UseMO.isUndef();
132}
133
134/// Return true if \p MI is a copy that will be lowered to one or more vmvNr.vs.
135static bool isVectorCopy(const TargetRegisterInfo *TRI,
136 const MachineInstr &MI) {
137 return MI.isCopy() && MI.getOperand(0).getReg().isPhysical() &&
139 TRI->getMinimalPhysRegClass(MI.getOperand(0).getReg()));
140}
141
142/// Which subfields of VL or VTYPE have values we need to preserve?
143struct DemandedFields {
144 // Some unknown property of VL is used. If demanded, must preserve entire
145 // value.
146 bool VLAny = false;
147 // Only zero vs non-zero is used. If demanded, can change non-zero values.
148 bool VLZeroness = false;
149 // What properties of SEW we need to preserve.
150 enum : uint8_t {
151 SEWEqual = 3, // The exact value of SEW needs to be preserved.
152 SEWGreaterThanOrEqualAndLessThan64 =
153 2, // SEW can be changed as long as it's greater
154 // than or equal to the original value, but must be less
155 // than 64.
156 SEWGreaterThanOrEqual = 1, // SEW can be changed as long as it's greater
157 // than or equal to the original value.
158 SEWNone = 0 // We don't need to preserve SEW at all.
159 } SEW = SEWNone;
160 enum : uint8_t {
161 LMULEqual = 2, // The exact value of LMUL needs to be preserved.
162 LMULLessThanOrEqualToM1 = 1, // We can use any LMUL <= M1.
163 LMULNone = 0 // We don't need to preserve LMUL at all.
164 } LMUL = LMULNone;
165 bool SEWLMULRatio = false;
166 bool TailPolicy = false;
167 bool MaskPolicy = false;
168 // If this is true, we demand that VTYPE is set to some legal state, i.e. that
169 // vill is unset.
170 bool VILL = false;
171 bool TWiden = false;
172 bool AltFmt = false;
173
174 // Return true if any part of VTYPE was used
175 bool usedVTYPE() const {
176 return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL ||
177 TWiden || AltFmt;
178 }
179
180 // Return true if any property of VL was used
181 bool usedVL() {
182 return VLAny || VLZeroness;
183 }
184
185 // Mark all VTYPE subfields and properties as demanded
186 void demandVTYPE() {
187 SEW = SEWEqual;
188 LMUL = LMULEqual;
189 SEWLMULRatio = true;
190 TailPolicy = true;
191 MaskPolicy = true;
192 VILL = true;
193 TWiden = true;
194 AltFmt = true;
195 }
196
197 // Mark all VL properties as demanded
198 void demandVL() {
199 VLAny = true;
200 VLZeroness = true;
201 }
202
203 static DemandedFields all() {
204 DemandedFields DF;
205 DF.demandVTYPE();
206 DF.demandVL();
207 return DF;
208 }
209
210 // Make this the result of demanding both the fields in this and B.
211 void doUnion(const DemandedFields &B) {
212 VLAny |= B.VLAny;
213 VLZeroness |= B.VLZeroness;
214 SEW = std::max(SEW, B.SEW);
215 LMUL = std::max(LMUL, B.LMUL);
216 SEWLMULRatio |= B.SEWLMULRatio;
217 TailPolicy |= B.TailPolicy;
218 MaskPolicy |= B.MaskPolicy;
219 VILL |= B.VILL;
220 AltFmt |= B.AltFmt;
221 TWiden |= B.TWiden;
222 }
223
224#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
225 /// Support for debugging, callable in GDB: V->dump()
226 LLVM_DUMP_METHOD void dump() const {
227 print(dbgs());
228 dbgs() << "\n";
229 }
230
231 /// Implement operator<<.
232 void print(raw_ostream &OS) const {
233 OS << "{";
234 OS << "VLAny=" << VLAny << ", ";
235 OS << "VLZeroness=" << VLZeroness << ", ";
236 OS << "SEW=";
237 switch (SEW) {
238 case SEWEqual:
239 OS << "SEWEqual";
240 break;
241 case SEWGreaterThanOrEqual:
242 OS << "SEWGreaterThanOrEqual";
243 break;
244 case SEWGreaterThanOrEqualAndLessThan64:
245 OS << "SEWGreaterThanOrEqualAndLessThan64";
246 break;
247 case SEWNone:
248 OS << "SEWNone";
249 break;
250 };
251 OS << ", ";
252 OS << "LMUL=";
253 switch (LMUL) {
254 case LMULEqual:
255 OS << "LMULEqual";
256 break;
257 case LMULLessThanOrEqualToM1:
258 OS << "LMULLessThanOrEqualToM1";
259 break;
260 case LMULNone:
261 OS << "LMULNone";
262 break;
263 };
264 OS << ", ";
265 OS << "SEWLMULRatio=" << SEWLMULRatio << ", ";
266 OS << "TailPolicy=" << TailPolicy << ", ";
267 OS << "MaskPolicy=" << MaskPolicy << ", ";
268 OS << "VILL=" << VILL << ", ";
269 OS << "AltFmt=" << AltFmt << ", ";
270 OS << "TWiden=" << TWiden;
271 OS << "}";
272 }
273#endif
274};
275
276#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
278inline raw_ostream &operator<<(raw_ostream &OS, const DemandedFields &DF) {
279 DF.print(OS);
280 return OS;
281}
282#endif
283
284static bool isLMUL1OrSmaller(RISCVVType::VLMUL LMUL) {
285 auto [LMul, Fractional] = RISCVVType::decodeVLMUL(LMUL);
286 return Fractional || LMul == 1;
287}
288
289/// Return true if moving from CurVType to NewVType is
290/// indistinguishable from the perspective of an instruction (or set
291/// of instructions) which use only the Used subfields and properties.
292static bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType,
293 const DemandedFields &Used) {
294 switch (Used.SEW) {
295 case DemandedFields::SEWNone:
296 break;
297 case DemandedFields::SEWEqual:
298 if (RISCVVType::getSEW(CurVType) != RISCVVType::getSEW(NewVType))
299 return false;
300 break;
301 case DemandedFields::SEWGreaterThanOrEqual:
302 if (RISCVVType::getSEW(NewVType) < RISCVVType::getSEW(CurVType))
303 return false;
304 break;
305 case DemandedFields::SEWGreaterThanOrEqualAndLessThan64:
306 if (RISCVVType::getSEW(NewVType) < RISCVVType::getSEW(CurVType) ||
307 RISCVVType::getSEW(NewVType) >= 64)
308 return false;
309 break;
310 }
311
312 switch (Used.LMUL) {
313 case DemandedFields::LMULNone:
314 break;
315 case DemandedFields::LMULEqual:
316 if (RISCVVType::getVLMUL(CurVType) != RISCVVType::getVLMUL(NewVType))
317 return false;
318 break;
319 case DemandedFields::LMULLessThanOrEqualToM1:
320 if (!isLMUL1OrSmaller(RISCVVType::getVLMUL(NewVType)))
321 return false;
322 break;
323 }
324
325 if (Used.SEWLMULRatio) {
326 auto Ratio1 = RISCVVType::getSEWLMULRatio(RISCVVType::getSEW(CurVType),
327 RISCVVType::getVLMUL(CurVType));
328 auto Ratio2 = RISCVVType::getSEWLMULRatio(RISCVVType::getSEW(NewVType),
329 RISCVVType::getVLMUL(NewVType));
330 if (Ratio1 != Ratio2)
331 return false;
332 }
333
334 if (Used.TailPolicy && RISCVVType::isTailAgnostic(CurVType) !=
336 return false;
337 if (Used.MaskPolicy && RISCVVType::isMaskAgnostic(CurVType) !=
339 return false;
340 if (Used.TWiden && (RISCVVType::hasXSfmmWiden(CurVType) !=
341 RISCVVType::hasXSfmmWiden(NewVType) ||
342 (RISCVVType::hasXSfmmWiden(CurVType) &&
343 RISCVVType::getXSfmmWiden(CurVType) !=
344 RISCVVType::getXSfmmWiden(NewVType))))
345 return false;
346 if (Used.AltFmt &&
347 RISCVVType::isAltFmt(CurVType) != RISCVVType::isAltFmt(NewVType))
348 return false;
349 return true;
350}
351
352/// Return the fields and properties demanded by the provided instruction.
353DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
354 // This function works in coalesceVSETVLI too. We can still use the value of a
355 // SEW, VL, or Policy operand even though it might not be the exact value in
356 // the VL or VTYPE, since we only care about what the instruction originally
357 // demanded.
358
359 // Most instructions don't use any of these subfeilds.
360 DemandedFields Res;
361 // Start conservative if registers are used
362 if (MI.isCall() || MI.isInlineAsm() ||
363 MI.readsRegister(RISCV::VL, /*TRI=*/nullptr))
364 Res.demandVL();
365 if (MI.isCall() || MI.isInlineAsm() ||
366 MI.readsRegister(RISCV::VTYPE, /*TRI=*/nullptr))
367 Res.demandVTYPE();
368 // Start conservative on the unlowered form too
369 uint64_t TSFlags = MI.getDesc().TSFlags;
370 if (RISCVII::hasSEWOp(TSFlags)) {
371 Res.demandVTYPE();
372 if (RISCVII::hasVLOp(TSFlags))
373 if (const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
374 !VLOp.isReg() || !VLOp.isUndef())
375 Res.demandVL();
376
377 // Behavior is independent of mask policy.
378 if (!RISCVII::usesMaskPolicy(TSFlags))
379 Res.MaskPolicy = false;
380 }
381
382 // Loads and stores with implicit EEW do not demand SEW or LMUL directly.
383 // They instead demand the ratio of the two which is used in computing
384 // EMUL, but which allows us the flexibility to change SEW and LMUL
385 // provided we don't change the ratio.
386 // Note: We assume that the instructions initial SEW is the EEW encoded
387 // in the opcode. This is asserted when constructing the VSETVLIInfo.
388 if (getEEWForLoadStore(MI)) {
389 Res.SEW = DemandedFields::SEWNone;
390 Res.LMUL = DemandedFields::LMULNone;
391 }
392
393 // Store instructions don't use the policy fields.
394 if (RISCVII::hasSEWOp(TSFlags) && MI.getNumExplicitDefs() == 0) {
395 Res.TailPolicy = false;
396 Res.MaskPolicy = false;
397 }
398
399 // If this is a mask reg operation, it only cares about VLMAX.
400 // TODO: Possible extensions to this logic
401 // * Probably ok if available VLMax is larger than demanded
402 // * The policy bits can probably be ignored..
403 if (isMaskRegOp(MI)) {
404 Res.SEW = DemandedFields::SEWNone;
405 Res.LMUL = DemandedFields::LMULNone;
406 }
407
408 // For vmv.s.x and vfmv.s.f, there are only two behaviors, VL = 0 and VL > 0.
409 if (RISCVInstrInfo::isScalarInsertInstr(MI)) {
410 Res.LMUL = DemandedFields::LMULNone;
411 Res.SEWLMULRatio = false;
412 Res.VLAny = false;
413 // For vmv.s.x and vfmv.s.f, if the passthru is *undefined*, we don't
414 // need to preserve any other bits and are thus compatible with any larger,
415 // etype and can disregard policy bits. Warning: It's tempting to try doing
416 // this for any tail agnostic operation, but we can't as TA requires
417 // tail lanes to either be the original value or -1. We are writing
418 // unknown bits to the lanes here.
419 if (hasUndefinedPassthru(MI)) {
420 if (RISCVInstrInfo::isFloatScalarMoveOrScalarSplatInstr(MI) &&
421 !ST->hasVInstructionsF64())
422 Res.SEW = DemandedFields::SEWGreaterThanOrEqualAndLessThan64;
423 else
424 Res.SEW = DemandedFields::SEWGreaterThanOrEqual;
425 Res.TailPolicy = false;
426 }
427 }
428
429 // vmv.x.s, and vfmv.f.s are unconditional and ignore everything except SEW.
430 if (RISCVInstrInfo::isScalarExtractInstr(MI)) {
431 assert(!RISCVII::hasVLOp(TSFlags));
432 Res.LMUL = DemandedFields::LMULNone;
433 Res.SEWLMULRatio = false;
434 Res.TailPolicy = false;
435 Res.MaskPolicy = false;
436 }
437
438 if (RISCVII::hasVLOp(MI.getDesc().TSFlags)) {
439 const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
440 // A slidedown/slideup with an *undefined* passthru can freely clobber
441 // elements not copied from the source vector (e.g. masked off, tail, or
442 // slideup's prefix). Notes:
443 // * We can't modify SEW here since the slide amount is in units of SEW.
444 // * VL=1 is special only because we have existing support for zero vs
445 // non-zero VL. We could generalize this if we had a VL > C predicate.
446 // * The LMUL1 restriction is for machines whose latency may depend on LMUL.
447 // * As above, this is only legal for tail "undefined" not "agnostic".
448 // * We avoid increasing vl if the subtarget has +vl-dependent-latency
449 if (RISCVInstrInfo::isVSlideInstr(MI) && VLOp.isImm() &&
450 VLOp.getImm() == 1 && hasUndefinedPassthru(MI) &&
451 !ST->hasVLDependentLatency()) {
452 Res.VLAny = false;
453 Res.VLZeroness = true;
454 Res.LMUL = DemandedFields::LMULLessThanOrEqualToM1;
455 Res.TailPolicy = false;
456 }
457
458 // A tail undefined vmv.v.i/x or vfmv.v.f with VL=1 can be treated in the
459 // same semantically as vmv.s.x. This is particularly useful since we don't
460 // have an immediate form of vmv.s.x, and thus frequently use vmv.v.i in
461 // it's place. Since a splat is non-constant time in LMUL, we do need to be
462 // careful to not increase the number of active vector registers (unlike for
463 // vmv.s.x.)
464 if (RISCVInstrInfo::isScalarSplatInstr(MI) && VLOp.isImm() &&
465 VLOp.getImm() == 1 && hasUndefinedPassthru(MI) &&
466 !ST->hasVLDependentLatency()) {
467 Res.LMUL = DemandedFields::LMULLessThanOrEqualToM1;
468 Res.SEWLMULRatio = false;
469 Res.VLAny = false;
470 if (RISCVInstrInfo::isFloatScalarMoveOrScalarSplatInstr(MI) &&
471 !ST->hasVInstructionsF64())
472 Res.SEW = DemandedFields::SEWGreaterThanOrEqualAndLessThan64;
473 else
474 Res.SEW = DemandedFields::SEWGreaterThanOrEqual;
475 Res.TailPolicy = false;
476 }
477 }
478
479 // In §32.16.6, whole vector register moves have a dependency on SEW. At the
480 // MIR level though we don't encode the element type, and it gives the same
481 // result whatever the SEW may be.
482 //
483 // However it does need valid SEW, i.e. vill must be cleared. The entry to a
484 // function, calls and inline assembly may all set it, so make sure we clear
485 // it for whole register copies. Do this by leaving VILL demanded.
486 if (isVectorCopy(ST->getRegisterInfo(), MI)) {
487 Res.LMUL = DemandedFields::LMULNone;
488 Res.SEW = DemandedFields::SEWNone;
489 Res.SEWLMULRatio = false;
490 Res.TailPolicy = false;
491 Res.MaskPolicy = false;
492 }
493
494 if (RISCVInstrInfo::isVExtractInstr(MI)) {
495 assert(!RISCVII::hasVLOp(TSFlags));
496 // TODO: LMUL can be any larger value (without cost)
497 Res.TailPolicy = false;
498 }
499
500 Res.AltFmt = RISCVII::getAltFmtType(MI.getDesc().TSFlags) !=
502 Res.TWiden = RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
503 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI);
504
505 return Res;
506}
507
508/// Defines the abstract state with which the forward dataflow models the
509/// values of the VL and VTYPE registers after insertion.
510class VSETVLIInfo {
511 struct AVLDef {
512 // Every AVLDef should have a VNInfo, unless we're running without
513 // LiveIntervals in which case this will be nullptr.
514 const VNInfo *ValNo;
515 Register DefReg;
516 };
517 union {
518 AVLDef AVLRegDef;
519 unsigned AVLImm;
520 };
521
522 enum class AVLState : uint8_t {
524 AVLIsReg,
525 AVLIsImm,
526 AVLIsVLMAX,
527 Unknown, // AVL and VTYPE are fully unknown
528 } State = AVLState::Uninitialized;
529
530 // Fields from VTYPE.
532 uint8_t SEW = 0;
533 uint8_t TailAgnostic : 1;
534 uint8_t MaskAgnostic : 1;
535 uint8_t SEWLMULRatioOnly : 1;
536 uint8_t AltFmt : 1;
537 uint8_t TWiden : 3;
538
539public:
540 VSETVLIInfo()
541 : AVLImm(0), TailAgnostic(false), MaskAgnostic(false),
542 SEWLMULRatioOnly(false), AltFmt(false), TWiden(0) {}
543
544 static VSETVLIInfo getUnknown() {
545 VSETVLIInfo Info;
546 Info.setUnknown();
547 return Info;
548 }
549
550 bool isValid() const { return State != AVLState::Uninitialized; }
551 void setUnknown() { State = AVLState::Unknown; }
552 bool isUnknown() const { return State == AVLState::Unknown; }
553
554 void setAVLRegDef(const VNInfo *VNInfo, Register AVLReg) {
555 assert(AVLReg.isVirtual());
556 AVLRegDef.ValNo = VNInfo;
557 AVLRegDef.DefReg = AVLReg;
558 State = AVLState::AVLIsReg;
559 }
560
561 void setAVLImm(unsigned Imm) {
562 AVLImm = Imm;
563 State = AVLState::AVLIsImm;
564 }
565
566 void setAVLVLMAX() { State = AVLState::AVLIsVLMAX; }
567
568 bool hasAVLImm() const { return State == AVLState::AVLIsImm; }
569 bool hasAVLReg() const { return State == AVLState::AVLIsReg; }
570 bool hasAVLVLMAX() const { return State == AVLState::AVLIsVLMAX; }
571 Register getAVLReg() const {
572 assert(hasAVLReg() && AVLRegDef.DefReg.isVirtual());
573 return AVLRegDef.DefReg;
574 }
575 unsigned getAVLImm() const {
576 assert(hasAVLImm());
577 return AVLImm;
578 }
579 const VNInfo *getAVLVNInfo() const {
580 assert(hasAVLReg());
581 return AVLRegDef.ValNo;
582 }
583 // Most AVLIsReg infos will have a single defining MachineInstr, unless it was
584 // a PHI node. In that case getAVLVNInfo()->def will point to the block
585 // boundary slot and this will return nullptr. If LiveIntervals isn't
586 // available, nullptr is also returned.
587 const MachineInstr *getAVLDefMI(const LiveIntervals *LIS) const {
588 assert(hasAVLReg());
589 if (!LIS || getAVLVNInfo()->isPHIDef())
590 return nullptr;
591 auto *MI = LIS->getInstructionFromIndex(getAVLVNInfo()->def);
592 assert(MI);
593 return MI;
594 }
595
596 void setAVL(const VSETVLIInfo &Info) {
597 assert(Info.isValid());
598 if (Info.isUnknown())
599 setUnknown();
600 else if (Info.hasAVLReg())
601 setAVLRegDef(Info.getAVLVNInfo(), Info.getAVLReg());
602 else if (Info.hasAVLVLMAX())
603 setAVLVLMAX();
604 else {
605 assert(Info.hasAVLImm());
606 setAVLImm(Info.getAVLImm());
607 }
608 }
609
610 unsigned getSEW() const {
611 assert(isValid() && !isUnknown() &&
612 "Can't use VTYPE for uninitialized or unknown");
613 return SEW;
614 }
615 RISCVVType::VLMUL getVLMUL() const {
616 assert(isValid() && !isUnknown() &&
617 "Can't use VTYPE for uninitialized or unknown");
618 return VLMul;
619 }
620 bool getTailAgnostic() const {
621 assert(isValid() && !isUnknown() &&
622 "Can't use VTYPE for uninitialized or unknown");
623 return TailAgnostic;
624 }
625 bool getMaskAgnostic() const {
626 assert(isValid() && !isUnknown() &&
627 "Can't use VTYPE for uninitialized or unknown");
628 return MaskAgnostic;
629 }
630 bool getAltFmt() const {
631 assert(isValid() && !isUnknown() &&
632 "Can't use VTYPE for uninitialized or unknown");
633 return AltFmt;
634 }
635 unsigned getTWiden() const {
636 assert(isValid() && !isUnknown() &&
637 "Can't use VTYPE for uninitialized or unknown");
638 return TWiden;
639 }
640
641 bool hasNonZeroAVL(const LiveIntervals *LIS) const {
642 if (hasAVLImm())
643 return getAVLImm() > 0;
644 if (hasAVLReg()) {
645 if (auto *DefMI = getAVLDefMI(LIS))
646 return RISCVInstrInfo::isNonZeroLoadImmediate(*DefMI);
647 }
648 if (hasAVLVLMAX())
649 return true;
650 return false;
651 }
652
653 bool hasEquallyZeroAVL(const VSETVLIInfo &Other,
654 const LiveIntervals *LIS) const {
655 if (hasSameAVL(Other))
656 return true;
657 return (hasNonZeroAVL(LIS) && Other.hasNonZeroAVL(LIS));
658 }
659
660 bool hasSameAVLLatticeValue(const VSETVLIInfo &Other) const {
661 if (hasAVLReg() && Other.hasAVLReg()) {
662 assert(!getAVLVNInfo() == !Other.getAVLVNInfo() &&
663 "we either have intervals or we don't");
664 if (!getAVLVNInfo())
665 return getAVLReg() == Other.getAVLReg();
666 return getAVLVNInfo()->id == Other.getAVLVNInfo()->id &&
667 getAVLReg() == Other.getAVLReg();
668 }
669
670 if (hasAVLImm() && Other.hasAVLImm())
671 return getAVLImm() == Other.getAVLImm();
672
673 if (hasAVLVLMAX())
674 return Other.hasAVLVLMAX() && hasSameVLMAX(Other);
675
676 return false;
677 }
678
679 // Return true if the two lattice values are guaranteed to have
680 // the same AVL value at runtime.
681 bool hasSameAVL(const VSETVLIInfo &Other) const {
682 // Without LiveIntervals, we don't know which instruction defines a
683 // register. Since a register may be redefined, this means all AVLIsReg
684 // states must be treated as possibly distinct.
685 if (hasAVLReg() && Other.hasAVLReg()) {
686 assert(!getAVLVNInfo() == !Other.getAVLVNInfo() &&
687 "we either have intervals or we don't");
688 if (!getAVLVNInfo())
689 return false;
690 }
691 return hasSameAVLLatticeValue(Other);
692 }
693
694 void setVTYPE(unsigned VType) {
695 assert(isValid() && !isUnknown() &&
696 "Can't set VTYPE for uninitialized or unknown");
697 VLMul = RISCVVType::getVLMUL(VType);
698 SEW = RISCVVType::getSEW(VType);
699 TailAgnostic = RISCVVType::isTailAgnostic(VType);
700 MaskAgnostic = RISCVVType::isMaskAgnostic(VType);
701 AltFmt = RISCVVType::isAltFmt(VType);
702 TWiden =
704 }
705 void setVTYPE(RISCVVType::VLMUL L, unsigned S, bool TA, bool MA, bool Altfmt,
706 unsigned W) {
707 assert(isValid() && !isUnknown() &&
708 "Can't set VTYPE for uninitialized or unknown");
709 VLMul = L;
710 SEW = S;
711 TailAgnostic = TA;
712 MaskAgnostic = MA;
713 AltFmt = Altfmt;
714 TWiden = W;
715 }
716
717 void setAltFmt(bool AF) { AltFmt = AF; }
718
719 void setVLMul(RISCVVType::VLMUL VLMul) { this->VLMul = VLMul; }
720
721 unsigned encodeVTYPE() const {
722 assert(isValid() && !isUnknown() && !SEWLMULRatioOnly &&
723 "Can't encode VTYPE for uninitialized or unknown");
724 if (TWiden != 0)
725 return RISCVVType::encodeXSfmmVType(SEW, TWiden, AltFmt);
726 return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic,
727 AltFmt);
728 }
729
730 bool hasSEWLMULRatioOnly() const { return SEWLMULRatioOnly; }
731
732 bool hasSameVTYPE(const VSETVLIInfo &Other) const {
733 assert(isValid() && Other.isValid() &&
734 "Can't compare invalid VSETVLIInfos");
735 assert(!isUnknown() && !Other.isUnknown() &&
736 "Can't compare VTYPE in unknown state");
737 assert(!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly &&
738 "Can't compare when only LMUL/SEW ratio is valid.");
739 return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden) ==
740 std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic,
741 Other.MaskAgnostic, Other.AltFmt, Other.TWiden);
742 }
743
744 unsigned getSEWLMULRatio() const {
745 assert(isValid() && !isUnknown() &&
746 "Can't use VTYPE for uninitialized or unknown");
747 return RISCVVType::getSEWLMULRatio(SEW, VLMul);
748 }
749
750 // Check if the VTYPE for these two VSETVLIInfos produce the same VLMAX.
751 // Note that having the same VLMAX ensures that both share the same
752 // function from AVL to VL; that is, they must produce the same VL value
753 // for any given AVL value.
754 bool hasSameVLMAX(const VSETVLIInfo &Other) const {
755 assert(isValid() && Other.isValid() &&
756 "Can't compare invalid VSETVLIInfos");
757 assert(!isUnknown() && !Other.isUnknown() &&
758 "Can't compare VTYPE in unknown state");
759 return getSEWLMULRatio() == Other.getSEWLMULRatio();
760 }
761
762 bool hasCompatibleVTYPE(const DemandedFields &Used,
763 const VSETVLIInfo &Require) const {
764 return areCompatibleVTYPEs(Require.encodeVTYPE(), encodeVTYPE(), Used);
765 }
766
767 // Determine whether the vector instructions requirements represented by
768 // Require are compatible with the previous vsetvli instruction represented
769 // by this. MI is the instruction whose requirements we're considering.
770 bool isCompatible(const DemandedFields &Used, const VSETVLIInfo &Require,
771 const LiveIntervals *LIS) const {
772 assert(isValid() && Require.isValid() &&
773 "Can't compare invalid VSETVLIInfos");
774 // Nothing is compatible with Unknown.
775 if (isUnknown() || Require.isUnknown())
776 return false;
777
778 // If only our VLMAX ratio is valid, then this isn't compatible.
779 if (SEWLMULRatioOnly || Require.SEWLMULRatioOnly)
780 return false;
781
782 if (Used.VLAny && !(hasSameAVL(Require) && hasSameVLMAX(Require)))
783 return false;
784
785 if (Used.VLZeroness && !hasEquallyZeroAVL(Require, LIS))
786 return false;
787
788 return hasCompatibleVTYPE(Used, Require);
789 }
790
791 bool operator==(const VSETVLIInfo &Other) const {
792 // Uninitialized is only equal to another Uninitialized.
793 if (!isValid())
794 return !Other.isValid();
795 if (!Other.isValid())
796 return !isValid();
797
798 // Unknown is only equal to another Unknown.
799 if (isUnknown())
800 return Other.isUnknown();
801 if (Other.isUnknown())
802 return isUnknown();
803
804 if (!hasSameAVLLatticeValue(Other))
805 return false;
806
807 // If the SEWLMULRatioOnly bits are different, then they aren't equal.
808 if (SEWLMULRatioOnly != Other.SEWLMULRatioOnly)
809 return false;
810
811 // If only the VLMAX is valid, check that it is the same.
812 if (SEWLMULRatioOnly)
813 return hasSameVLMAX(Other);
814
815 // If the full VTYPE is valid, check that it is the same.
816 return hasSameVTYPE(Other);
817 }
818
819 bool operator!=(const VSETVLIInfo &Other) const {
820 return !(*this == Other);
821 }
822
823 // Calculate the VSETVLIInfo visible to a block assuming this and Other are
824 // both predecessors.
825 VSETVLIInfo intersect(const VSETVLIInfo &Other) const {
826 // If the new value isn't valid, ignore it.
827 if (!Other.isValid())
828 return *this;
829
830 // If this value isn't valid, this must be the first predecessor, use it.
831 if (!isValid())
832 return Other;
833
834 // If either is unknown, the result is unknown.
835 if (isUnknown() || Other.isUnknown())
836 return VSETVLIInfo::getUnknown();
837
838 // If we have an exact, match return this.
839 if (*this == Other)
840 return *this;
841
842 // Not an exact match, but maybe the AVL and VLMAX are the same. If so,
843 // return an SEW/LMUL ratio only value.
844 if (hasSameAVL(Other) && hasSameVLMAX(Other)) {
845 VSETVLIInfo MergeInfo = *this;
846 MergeInfo.SEWLMULRatioOnly = true;
847 return MergeInfo;
848 }
849
850 // Otherwise the result is unknown.
851 return VSETVLIInfo::getUnknown();
852 }
853
854#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
855 /// Support for debugging, callable in GDB: V->dump()
856 LLVM_DUMP_METHOD void dump() const {
857 print(dbgs());
858 dbgs() << "\n";
859 }
860
861 /// Implement operator<<.
862 /// @{
863 void print(raw_ostream &OS) const {
864 OS << '{';
865 switch (State) {
866 case AVLState::Uninitialized:
867 OS << "Uninitialized";
868 break;
869 case AVLState::Unknown:
870 OS << "unknown";
871 break;
872 case AVLState::AVLIsReg:
873 OS << "AVLReg=" << llvm::printReg(getAVLReg());
874 break;
875 case AVLState::AVLIsImm:
876 OS << "AVLImm=" << (unsigned)AVLImm;
877 break;
878 case AVLState::AVLIsVLMAX:
879 OS << "AVLVLMAX";
880 break;
881 }
882 if (isValid() && !isUnknown()) {
883 OS << ", ";
884
885 unsigned LMul;
886 bool Fractional;
887 std::tie(LMul, Fractional) = decodeVLMUL(VLMul);
888
889 OS << "VLMul=m";
890 if (Fractional)
891 OS << 'f';
892 OS << LMul << ", "
893 << "SEW=e" << (unsigned)SEW << ", "
894 << "TailAgnostic=" << (bool)TailAgnostic << ", "
895 << "MaskAgnostic=" << (bool)MaskAgnostic << ", "
896 << "SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly << ", "
897 << "TWiden=" << (unsigned)TWiden << ", "
898 << "AltFmt=" << (bool)AltFmt;
899 }
900
901 OS << '}';
902 }
903#endif
904};
905
906#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
908inline raw_ostream &operator<<(raw_ostream &OS, const VSETVLIInfo &V) {
909 V.print(OS);
910 return OS;
911}
912#endif
913
914struct BlockData {
915 // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this
916 // block. Calculated in Phase 2.
917 VSETVLIInfo Exit;
918
919 // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor
920 // blocks. Calculated in Phase 2, and used by Phase 3.
921 VSETVLIInfo Pred;
922
923 // Keeps track of whether the block is already in the queue.
924 bool InQueue = false;
925
926 BlockData() = default;
927};
928
929enum TKTMMode {
930 VSETTK = 0,
931 VSETTM = 1,
932};
933
934class RISCVInsertVSETVLI : public MachineFunctionPass {
935 const RISCVSubtarget *ST;
936 const TargetInstrInfo *TII;
937 MachineRegisterInfo *MRI;
938 // Possibly null!
939 LiveIntervals *LIS;
940
941 std::vector<BlockData> BlockInfo;
942 std::queue<const MachineBasicBlock *> WorkList;
943
944public:
945 static char ID;
946
947 RISCVInsertVSETVLI() : MachineFunctionPass(ID) {}
948 bool runOnMachineFunction(MachineFunction &MF) override;
949
950 void getAnalysisUsage(AnalysisUsage &AU) const override {
951 AU.setPreservesCFG();
952
953 AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
954 AU.addPreserved<LiveIntervalsWrapperPass>();
955 AU.addPreserved<SlotIndexesWrapperPass>();
956 AU.addPreserved<LiveDebugVariablesWrapperLegacy>();
957 AU.addPreserved<LiveStacksWrapperLegacy>();
958
960 }
961
962 StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; }
963
964private:
965 bool needVSETVLI(const DemandedFields &Used, const VSETVLIInfo &Require,
966 const VSETVLIInfo &CurInfo) const;
967 bool needVSETVLIPHI(const VSETVLIInfo &Require,
968 const MachineBasicBlock &MBB) const;
969 void insertVSETVLI(MachineBasicBlock &MBB,
971 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo);
972
973 void transferBefore(VSETVLIInfo &Info, const MachineInstr &MI) const;
974 void transferAfter(VSETVLIInfo &Info, const MachineInstr &MI) const;
975 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB,
976 VSETVLIInfo &Info) const;
977 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB);
978 void emitVSETVLIs(MachineBasicBlock &MBB);
979 void doPRE(MachineBasicBlock &MBB);
980 void insertReadVL(MachineBasicBlock &MBB);
981
982 bool canMutatePriorConfig(const MachineInstr &PrevMI, const MachineInstr &MI,
983 const DemandedFields &Used) const;
984 void coalesceVSETVLIs(MachineBasicBlock &MBB) const;
985
986 VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) const;
987 VSETVLIInfo computeInfoForInstr(const MachineInstr &MI) const;
988 void forwardVSETVLIAVL(VSETVLIInfo &Info) const;
989 bool insertVSETMTK(MachineBasicBlock &MBB, TKTMMode Mode) const;
990};
991
992} // end anonymous namespace
993
994char RISCVInsertVSETVLI::ID = 0;
995char &llvm::RISCVInsertVSETVLIID = RISCVInsertVSETVLI::ID;
996
998 false, false)
999
1000// If the AVL is defined by a vsetvli's output vl with the same VLMAX, we can
1001// replace the AVL operand with the AVL of the defining vsetvli. E.g.
1002//
1003// %vl = PseudoVSETVLI %avl:gpr, SEW=32, LMUL=M1
1004// $x0 = PseudoVSETVLI %vl:gpr, SEW=32, LMUL=M1
1005// ->
1006// %vl = PseudoVSETVLI %avl:gpr, SEW=32, LMUL=M1
1007// $x0 = PseudoVSETVLI %avl:gpr, SEW=32, LMUL=M1
1008void RISCVInsertVSETVLI::forwardVSETVLIAVL(VSETVLIInfo &Info) const {
1009 if (!Info.hasAVLReg())
1010 return;
1011 const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
1012 if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
1013 return;
1014 VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
1015 if (!DefInstrInfo.hasSameVLMAX(Info))
1016 return;
1017 Info.setAVL(DefInstrInfo);
1018}
1019
1020// Return a VSETVLIInfo representing the changes made by this VSETVLI or
1021// VSETIVLI instruction.
1022VSETVLIInfo
1023RISCVInsertVSETVLI::getInfoForVSETVLI(const MachineInstr &MI) const {
1024 VSETVLIInfo NewInfo;
1025 if (MI.getOpcode() == RISCV::PseudoVSETIVLI) {
1026 NewInfo.setAVLImm(MI.getOperand(1).getImm());
1027 } else if (RISCVInstrInfo::isXSfmmVectorConfigTNInstr(MI)) {
1028 assert(MI.getOpcode() == RISCV::PseudoSF_VSETTNT ||
1029 MI.getOpcode() == RISCV::PseudoSF_VSETTNTX0);
1030 switch (MI.getOpcode()) {
1031 case RISCV::PseudoSF_VSETTNTX0:
1032 NewInfo.setAVLVLMAX();
1033 break;
1034 case RISCV::PseudoSF_VSETTNT:
1035 Register ATNReg = MI.getOperand(1).getReg();
1036 NewInfo.setAVLRegDef(getVNInfoFromReg(ATNReg, MI, LIS), ATNReg);
1037 break;
1038 }
1039 } else {
1040 assert(MI.getOpcode() == RISCV::PseudoVSETVLI ||
1041 MI.getOpcode() == RISCV::PseudoVSETVLIX0);
1042 if (MI.getOpcode() == RISCV::PseudoVSETVLIX0)
1043 NewInfo.setAVLVLMAX();
1044 else if (MI.getOperand(1).isUndef())
1045 // Otherwise use an AVL of 1 to avoid depending on previous vl.
1046 NewInfo.setAVLImm(1);
1047 else {
1048 Register AVLReg = MI.getOperand(1).getReg();
1049 VNInfo *VNI = getVNInfoFromReg(AVLReg, MI, LIS);
1050 NewInfo.setAVLRegDef(VNI, AVLReg);
1051 }
1052 }
1053 NewInfo.setVTYPE(MI.getOperand(2).getImm());
1054
1055 forwardVSETVLIAVL(NewInfo);
1056
1057 return NewInfo;
1058}
1059
1060static unsigned computeVLMAX(unsigned VLEN, unsigned SEW,
1061 RISCVVType::VLMUL VLMul) {
1062 auto [LMul, Fractional] = RISCVVType::decodeVLMUL(VLMul);
1063 if (Fractional)
1064 VLEN = VLEN / LMul;
1065 else
1066 VLEN = VLEN * LMul;
1067 return VLEN/SEW;
1068}
1069
1070VSETVLIInfo
1071RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const {
1072 VSETVLIInfo InstrInfo;
1073 const uint64_t TSFlags = MI.getDesc().TSFlags;
1074
1075 bool TailAgnostic = true;
1076 bool MaskAgnostic = true;
1077 if (!hasUndefinedPassthru(MI)) {
1078 // Start with undisturbed.
1079 TailAgnostic = false;
1080 MaskAgnostic = false;
1081
1082 // If there is a policy operand, use it.
1083 if (RISCVII::hasVecPolicyOp(TSFlags)) {
1084 const MachineOperand &Op = MI.getOperand(getVecPolicyOpNum(MI));
1085 uint64_t Policy = Op.getImm();
1086 assert(Policy <=
1088 "Invalid Policy Value");
1089 TailAgnostic = Policy & RISCVVType::TAIL_AGNOSTIC;
1090 MaskAgnostic = Policy & RISCVVType::MASK_AGNOSTIC;
1091 }
1092
1093 if (!RISCVII::usesMaskPolicy(TSFlags))
1094 MaskAgnostic = true;
1095 }
1096
1097 RISCVVType::VLMUL VLMul = RISCVII::getLMul(TSFlags);
1098
1099 bool AltFmt = RISCVII::getAltFmtType(TSFlags) == RISCVII::AltFmtType::AltFmt;
1100 InstrInfo.setAltFmt(AltFmt);
1101
1102 unsigned Log2SEW = MI.getOperand(getSEWOpNum(MI)).getImm();
1103 // A Log2SEW of 0 is an operation on mask registers only.
1104 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
1105 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
1106
1107 if (RISCVII::hasTWidenOp(TSFlags)) {
1108 const MachineOperand &TWidenOp =
1109 MI.getOperand(MI.getNumExplicitOperands() - 1);
1110 unsigned TWiden = TWidenOp.getImm();
1111
1112 InstrInfo.setAVLVLMAX();
1113 if (RISCVII::hasVLOp(TSFlags)) {
1114 const MachineOperand &TNOp =
1115 MI.getOperand(RISCVII::getTNOpNum(MI.getDesc()));
1116
1117 if (TNOp.getReg().isVirtual())
1118 InstrInfo.setAVLRegDef(getVNInfoFromReg(TNOp.getReg(), MI, LIS),
1119 TNOp.getReg());
1120 }
1121
1122 InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden);
1123
1124 return InstrInfo;
1125 }
1126
1127 if (RISCVII::hasVLOp(TSFlags)) {
1128 const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
1129 if (VLOp.isImm()) {
1130 int64_t Imm = VLOp.getImm();
1131 // Convert the VLMax sentintel to X0 register.
1132 if (Imm == RISCV::VLMaxSentinel) {
1133 // If we know the exact VLEN, see if we can use the constant encoding
1134 // for the VLMAX instead. This reduces register pressure slightly.
1135 const unsigned VLMAX = computeVLMAX(ST->getRealMaxVLen(), SEW, VLMul);
1136 if (ST->getRealMinVLen() == ST->getRealMaxVLen() && VLMAX <= 31)
1137 InstrInfo.setAVLImm(VLMAX);
1138 else
1139 InstrInfo.setAVLVLMAX();
1140 }
1141 else
1142 InstrInfo.setAVLImm(Imm);
1143 } else if (VLOp.isUndef()) {
1144 // Otherwise use an AVL of 1 to avoid depending on previous vl.
1145 InstrInfo.setAVLImm(1);
1146 } else {
1147 VNInfo *VNI = getVNInfoFromReg(VLOp.getReg(), MI, LIS);
1148 InstrInfo.setAVLRegDef(VNI, VLOp.getReg());
1149 }
1150 } else {
1151 assert(RISCVInstrInfo::isScalarExtractInstr(MI) ||
1152 RISCVInstrInfo::isVExtractInstr(MI));
1153 // Pick a random value for state tracking purposes, will be ignored via
1154 // the demanded fields mechanism
1155 InstrInfo.setAVLImm(1);
1156 }
1157#ifndef NDEBUG
1158 if (std::optional<unsigned> EEW = getEEWForLoadStore(MI)) {
1159 assert(SEW == EEW && "Initial SEW doesn't match expected EEW");
1160 }
1161#endif
1162 // TODO: Propagate the twiden from previous vtype for potential reuse.
1163 InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt,
1164 /*TWiden*/ 0);
1165
1166 forwardVSETVLIAVL(InstrInfo);
1167
1168 return InstrInfo;
1169}
1170
1171void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1173 DebugLoc DL, const VSETVLIInfo &Info,
1174 const VSETVLIInfo &PrevInfo) {
1175 ++NumInsertedVSETVL;
1176
1177 if (Info.getTWiden()) {
1178 if (Info.hasAVLVLMAX()) {
1179 Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
1180 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNTX0))
1182 .addReg(RISCV::X0, RegState::Kill)
1183 .addImm(Info.encodeVTYPE());
1184 if (LIS) {
1186 LIS->createAndComputeVirtRegInterval(DestReg);
1187 }
1188 } else {
1189 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNT))
1191 .addReg(Info.getAVLReg())
1192 .addImm(Info.encodeVTYPE());
1193 if (LIS)
1195 }
1196 return;
1197 }
1198
1199 if (PrevInfo.isValid() && !PrevInfo.isUnknown()) {
1200 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same
1201 // VLMAX.
1202 if (Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) {
1203 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0X0))
1205 .addReg(RISCV::X0, RegState::Kill)
1206 .addImm(Info.encodeVTYPE())
1207 .addReg(RISCV::VL, RegState::Implicit);
1208 if (LIS)
1210 return;
1211 }
1212
1213 // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
1214 // it has the same VLMAX we want and the last VL/VTYPE we observed is the
1215 // same, we can use the X0, X0 form.
1216 if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
1217 if (const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
1218 DefMI && RISCVInstrInfo::isVectorConfigInstr(*DefMI)) {
1219 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
1220 if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
1221 auto MI =
1222 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0X0))
1224 .addReg(RISCV::X0, RegState::Kill)
1225 .addImm(Info.encodeVTYPE())
1226 .addReg(RISCV::VL, RegState::Implicit);
1227 if (LIS)
1229 return;
1230 }
1231 }
1232 }
1233 }
1234
1235 if (Info.hasAVLImm()) {
1236 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
1238 .addImm(Info.getAVLImm())
1239 .addImm(Info.encodeVTYPE());
1240 if (LIS)
1242 return;
1243 }
1244
1245 if (Info.hasAVLVLMAX()) {
1246 Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
1247 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0))
1249 .addReg(RISCV::X0, RegState::Kill)
1250 .addImm(Info.encodeVTYPE());
1251 if (LIS) {
1253 LIS->createAndComputeVirtRegInterval(DestReg);
1254 }
1255 return;
1256 }
1257
1258 Register AVLReg = Info.getAVLReg();
1259 MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass);
1260 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLI))
1262 .addReg(AVLReg)
1263 .addImm(Info.encodeVTYPE());
1264 if (LIS) {
1266 LiveInterval &LI = LIS->getInterval(AVLReg);
1267 SlotIndex SI = LIS->getInstructionIndex(*MI).getRegSlot();
1268 const VNInfo *CurVNI = Info.getAVLVNInfo();
1269 // If the AVL value isn't live at MI, do a quick check to see if it's easily
1270 // extendable. Otherwise, we need to copy it.
1271 if (LI.getVNInfoBefore(SI) != CurVNI) {
1272 if (!LI.liveAt(SI) && LI.containsOneValue())
1273 LIS->extendToIndices(LI, SI);
1274 else {
1275 Register AVLCopyReg =
1276 MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
1277 MachineBasicBlock *MBB = LIS->getMBBFromIndex(CurVNI->def);
1279 if (CurVNI->isPHIDef())
1280 II = MBB->getFirstNonPHI();
1281 else {
1282 II = LIS->getInstructionFromIndex(CurVNI->def);
1283 II = std::next(II);
1284 }
1285 assert(II.isValid());
1286 auto AVLCopy = BuildMI(*MBB, II, DL, TII->get(RISCV::COPY), AVLCopyReg)
1287 .addReg(AVLReg);
1288 LIS->InsertMachineInstrInMaps(*AVLCopy);
1289 MI->getOperand(1).setReg(AVLCopyReg);
1290 LIS->createAndComputeVirtRegInterval(AVLCopyReg);
1291 }
1292 }
1293 }
1294}
1295
1296/// Return true if a VSETVLI is required to transition from CurInfo to Require
1297/// given a set of DemandedFields \p Used.
1298bool RISCVInsertVSETVLI::needVSETVLI(const DemandedFields &Used,
1299 const VSETVLIInfo &Require,
1300 const VSETVLIInfo &CurInfo) const {
1301 if (!CurInfo.isValid() || CurInfo.isUnknown() || CurInfo.hasSEWLMULRatioOnly())
1302 return true;
1303
1304 if (CurInfo.isCompatible(Used, Require, LIS))
1305 return false;
1306
1307 return true;
1308}
1309
1310// If we don't use LMUL or the SEW/LMUL ratio, then adjust LMUL so that we
1311// maintain the SEW/LMUL ratio. This allows us to eliminate VL toggles in more
1312// places.
1313static VSETVLIInfo adjustIncoming(const VSETVLIInfo &PrevInfo,
1314 const VSETVLIInfo &NewInfo,
1315 DemandedFields &Demanded) {
1316 VSETVLIInfo Info = NewInfo;
1317
1318 if (!Demanded.LMUL && !Demanded.SEWLMULRatio && PrevInfo.isValid() &&
1319 !PrevInfo.isUnknown()) {
1320 if (auto NewVLMul = RISCVVType::getSameRatioLMUL(
1321 PrevInfo.getSEW(), PrevInfo.getVLMUL(), Info.getSEW()))
1322 Info.setVLMul(*NewVLMul);
1323 Demanded.LMUL = DemandedFields::LMULEqual;
1324 }
1325
1326 return Info;
1327}
1328
1329// Given an incoming state reaching MI, minimally modifies that state so that it
1330// is compatible with MI. The resulting state is guaranteed to be semantically
1331// legal for MI, but may not be the state requested by MI.
1332void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
1333 const MachineInstr &MI) const {
1334 if (isVectorCopy(ST->getRegisterInfo(), MI) &&
1335 (Info.isUnknown() || !Info.isValid() || Info.hasSEWLMULRatioOnly())) {
1336 // Use an arbitrary but valid AVL and VTYPE so vill will be cleared. It may
1337 // be coalesced into another vsetvli since we won't demand any fields.
1338 VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly
1339 NewInfo.setAVLImm(1);
1340 NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true,
1341 /*AltFmt*/ false, /*W*/ 0);
1342 Info = NewInfo;
1343 return;
1344 }
1345
1346 if (!RISCVII::hasSEWOp(MI.getDesc().TSFlags))
1347 return;
1348
1349 DemandedFields Demanded = getDemanded(MI, ST);
1350
1351 const VSETVLIInfo NewInfo = computeInfoForInstr(MI);
1352 assert(NewInfo.isValid() && !NewInfo.isUnknown());
1353 if (Info.isValid() && !needVSETVLI(Demanded, NewInfo, Info))
1354 return;
1355
1356 const VSETVLIInfo PrevInfo = Info;
1357 if (!Info.isValid() || Info.isUnknown())
1358 Info = NewInfo;
1359
1360 const VSETVLIInfo IncomingInfo = adjustIncoming(PrevInfo, NewInfo, Demanded);
1361
1362 // If MI only demands that VL has the same zeroness, we only need to set the
1363 // AVL if the zeroness differs. This removes a vsetvli entirely if the types
1364 // match or allows use of cheaper avl preserving variant if VLMAX doesn't
1365 // change. If VLMAX might change, we couldn't use the 'vsetvli x0, x0, vtype"
1366 // variant, so we avoid the transform to prevent extending live range of an
1367 // avl register operand.
1368 // TODO: We can probably relax this for immediates.
1369 bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo, LIS) &&
1370 IncomingInfo.hasSameVLMAX(PrevInfo);
1371 if (Demanded.VLAny || (Demanded.VLZeroness && !EquallyZero))
1372 Info.setAVL(IncomingInfo);
1373
1374 Info.setVTYPE(
1375 ((Demanded.LMUL || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
1376 .getVLMUL(),
1377 ((Demanded.SEW || Demanded.SEWLMULRatio) ? IncomingInfo : Info).getSEW(),
1378 // Prefer tail/mask agnostic since it can be relaxed to undisturbed later
1379 // if needed.
1380 (Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() ||
1381 IncomingInfo.getTailAgnostic(),
1382 (Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
1383 IncomingInfo.getMaskAgnostic(),
1384 (Demanded.AltFmt ? IncomingInfo : Info).getAltFmt(),
1385 Demanded.TWiden ? IncomingInfo.getTWiden() : 0);
1386
1387 // If we only knew the sew/lmul ratio previously, replace the VTYPE but keep
1388 // the AVL.
1389 if (Info.hasSEWLMULRatioOnly()) {
1390 VSETVLIInfo RatiolessInfo = IncomingInfo;
1391 RatiolessInfo.setAVL(Info);
1392 Info = RatiolessInfo;
1393 }
1394}
1395
1396// Given a state with which we evaluated MI (see transferBefore above for why
1397// this might be different that the state MI requested), modify the state to
1398// reflect the changes MI might make.
1399void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
1400 const MachineInstr &MI) const {
1401 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
1402 Info = getInfoForVSETVLI(MI);
1403 return;
1404 }
1405
1406 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
1407 // Update AVL to vl-output of the fault first load.
1408 assert(MI.getOperand(1).getReg().isVirtual());
1409 if (LIS) {
1410 auto &LI = LIS->getInterval(MI.getOperand(1).getReg());
1411 SlotIndex SI =
1413 VNInfo *VNI = LI.getVNInfoAt(SI);
1414 Info.setAVLRegDef(VNI, MI.getOperand(1).getReg());
1415 } else
1416 Info.setAVLRegDef(nullptr, MI.getOperand(1).getReg());
1417 return;
1418 }
1419
1420 // If this is something that updates VL/VTYPE that we don't know about, set
1421 // the state to unknown.
1422 if (MI.isCall() || MI.isInlineAsm() ||
1423 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
1424 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
1425 Info = VSETVLIInfo::getUnknown();
1426}
1427
1428bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
1429 VSETVLIInfo &Info) const {
1430 bool HadVectorOp = false;
1431
1432 Info = BlockInfo[MBB.getNumber()].Pred;
1433 for (const MachineInstr &MI : MBB) {
1434 transferBefore(Info, MI);
1435
1436 if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
1437 RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
1438 isVectorCopy(ST->getRegisterInfo(), MI) ||
1439 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI))
1440 HadVectorOp = true;
1441
1442 transferAfter(Info, MI);
1443 }
1444
1445 return HadVectorOp;
1446}
1447
1448void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) {
1449
1450 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
1451
1452 BBInfo.InQueue = false;
1453
1454 // Start with the previous entry so that we keep the most conservative state
1455 // we have ever found.
1456 VSETVLIInfo InInfo = BBInfo.Pred;
1457 if (MBB.pred_empty()) {
1458 // There are no predecessors, so use the default starting status.
1459 InInfo.setUnknown();
1460 } else {
1461 for (MachineBasicBlock *P : MBB.predecessors())
1462 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit);
1463 }
1464
1465 // If we don't have any valid predecessor value, wait until we do.
1466 if (!InInfo.isValid())
1467 return;
1468
1469 // If no change, no need to rerun block
1470 if (InInfo == BBInfo.Pred)
1471 return;
1472
1473 BBInfo.Pred = InInfo;
1474 LLVM_DEBUG(dbgs() << "Entry state of " << printMBBReference(MBB)
1475 << " changed to " << BBInfo.Pred << "\n");
1476
1477 // Note: It's tempting to cache the state changes here, but due to the
1478 // compatibility checks performed a blocks output state can change based on
1479 // the input state. To cache, we'd have to add logic for finding
1480 // never-compatible state changes.
1481 VSETVLIInfo TmpStatus;
1482 computeVLVTYPEChanges(MBB, TmpStatus);
1483
1484 // If the new exit value matches the old exit value, we don't need to revisit
1485 // any blocks.
1486 if (BBInfo.Exit == TmpStatus)
1487 return;
1488
1489 BBInfo.Exit = TmpStatus;
1490 LLVM_DEBUG(dbgs() << "Exit state of " << printMBBReference(MBB)
1491 << " changed to " << BBInfo.Exit << "\n");
1492
1493 // Add the successors to the work list so we can propagate the changed exit
1494 // status.
1495 for (MachineBasicBlock *S : MBB.successors())
1496 if (!BlockInfo[S->getNumber()].InQueue) {
1497 BlockInfo[S->getNumber()].InQueue = true;
1498 WorkList.push(S);
1499 }
1500}
1501
1502// If we weren't able to prove a vsetvli was directly unneeded, it might still
1503// be unneeded if the AVL was a phi node where all incoming values are VL
1504// outputs from the last VSETVLI in their respective basic blocks.
1505bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
1506 const MachineBasicBlock &MBB) const {
1507 if (!Require.hasAVLReg())
1508 return true;
1509
1510 if (!LIS)
1511 return true;
1512
1513 // We need the AVL to have been produced by a PHI node in this basic block.
1514 const VNInfo *Valno = Require.getAVLVNInfo();
1515 if (!Valno->isPHIDef() || LIS->getMBBFromIndex(Valno->def) != &MBB)
1516 return true;
1517
1518 const LiveRange &LR = LIS->getInterval(Require.getAVLReg());
1519
1520 for (auto *PBB : MBB.predecessors()) {
1521 const VSETVLIInfo &PBBExit = BlockInfo[PBB->getNumber()].Exit;
1522
1523 // We need the PHI input to the be the output of a VSET(I)VLI.
1524 const VNInfo *Value = LR.getVNInfoBefore(LIS->getMBBEndIdx(PBB));
1525 if (!Value)
1526 return true;
1527 MachineInstr *DefMI = LIS->getInstructionFromIndex(Value->def);
1528 if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
1529 return true;
1530
1531 // We found a VSET(I)VLI make sure it matches the output of the
1532 // predecessor block.
1533 VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
1534 if (DefInfo != PBBExit)
1535 return true;
1536
1537 // Require has the same VL as PBBExit, so if the exit from the
1538 // predecessor has the VTYPE we are looking for we might be able
1539 // to avoid a VSETVLI.
1540 if (PBBExit.isUnknown() || !PBBExit.hasSameVTYPE(Require))
1541 return true;
1542 }
1543
1544 // If all the incoming values to the PHI checked out, we don't need
1545 // to insert a VSETVLI.
1546 return false;
1547}
1548
1549void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
1550 VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred;
1551 // Track whether the prefix of the block we've scanned is transparent
1552 // (meaning has not yet changed the abstract state).
1553 bool PrefixTransparent = true;
1554 for (MachineInstr &MI : MBB) {
1555 const VSETVLIInfo PrevInfo = CurInfo;
1556 transferBefore(CurInfo, MI);
1557
1558 // If this is an explicit VSETVLI or VSETIVLI, update our state.
1559 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
1560 // Conservatively, mark the VL and VTYPE as live.
1561 assert(MI.getOperand(3).getReg() == RISCV::VL &&
1562 MI.getOperand(4).getReg() == RISCV::VTYPE &&
1563 "Unexpected operands where VL and VTYPE should be");
1564 MI.getOperand(3).setIsDead(false);
1565 MI.getOperand(4).setIsDead(false);
1566 PrefixTransparent = false;
1567 }
1568
1570 isVectorCopy(ST->getRegisterInfo(), MI)) {
1571 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
1572 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
1573 PrefixTransparent = false;
1574 }
1575 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
1576 /*isImp*/ true));
1577 }
1578
1579 uint64_t TSFlags = MI.getDesc().TSFlags;
1580 if (RISCVII::hasSEWOp(TSFlags)) {
1581 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
1582 // If this is the first implicit state change, and the state change
1583 // requested can be proven to produce the same register contents, we
1584 // can skip emitting the actual state change and continue as if we
1585 // had since we know the GPR result of the implicit state change
1586 // wouldn't be used and VL/VTYPE registers are correct. Note that
1587 // we *do* need to model the state as if it changed as while the
1588 // register contents are unchanged, the abstract model can change.
1589 if (!PrefixTransparent || needVSETVLIPHI(CurInfo, MBB))
1590 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
1591 PrefixTransparent = false;
1592 }
1593
1594 if (RISCVII::hasVLOp(TSFlags)) {
1595 MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI));
1596 if (VLOp.isReg()) {
1597 Register Reg = VLOp.getReg();
1598
1599 // Erase the AVL operand from the instruction.
1600 VLOp.setReg(Register());
1601 VLOp.setIsKill(false);
1602 if (LIS) {
1603 LiveInterval &LI = LIS->getInterval(Reg);
1605 LIS->shrinkToUses(&LI, &DeadMIs);
1606 // We might have separate components that need split due to
1607 // needVSETVLIPHI causing us to skip inserting a new VL def.
1609 LIS->splitSeparateComponents(LI, SplitLIs);
1610
1611 // If the AVL was an immediate > 31, then it would have been emitted
1612 // as an ADDI. However, the ADDI might not have been used in the
1613 // vsetvli, or a vsetvli might not have been emitted, so it may be
1614 // dead now.
1615 for (MachineInstr *DeadMI : DeadMIs) {
1616 if (!TII->isAddImmediate(*DeadMI, Reg))
1617 continue;
1618 LIS->RemoveMachineInstrFromMaps(*DeadMI);
1619 Register AddReg = DeadMI->getOperand(1).getReg();
1620 DeadMI->eraseFromParent();
1621 if (AddReg.isVirtual())
1622 LIS->shrinkToUses(&LIS->getInterval(AddReg));
1623 }
1624 }
1625 }
1626 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false,
1627 /*isImp*/ true));
1628 }
1629 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
1630 /*isImp*/ true));
1631 }
1632
1633 if (MI.isInlineAsm()) {
1634 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ true,
1635 /*isImp*/ true));
1636 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ true,
1637 /*isImp*/ true));
1638 }
1639
1640 if (MI.isCall() || MI.isInlineAsm() ||
1641 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
1642 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
1643 PrefixTransparent = false;
1644
1645 transferAfter(CurInfo, MI);
1646 }
1647
1648 const auto &Info = BlockInfo[MBB.getNumber()];
1649 if (CurInfo != Info.Exit) {
1650 LLVM_DEBUG(dbgs() << "in block " << printMBBReference(MBB) << "\n");
1651 LLVM_DEBUG(dbgs() << " begin state: " << Info.Pred << "\n");
1652 LLVM_DEBUG(dbgs() << " expected end state: " << Info.Exit << "\n");
1653 LLVM_DEBUG(dbgs() << " actual end state: " << CurInfo << "\n");
1654 }
1655 assert(CurInfo == Info.Exit && "InsertVSETVLI dataflow invariant violated");
1656}
1657
1658/// Perform simple partial redundancy elimination of the VSETVLI instructions
1659/// we're about to insert by looking for cases where we can PRE from the
1660/// beginning of one block to the end of one of its predecessors. Specifically,
1661/// this is geared to catch the common case of a fixed length vsetvl in a single
1662/// block loop when it could execute once in the preheader instead.
1663void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
1664 if (!BlockInfo[MBB.getNumber()].Pred.isUnknown())
1665 return;
1666
1667 MachineBasicBlock *UnavailablePred = nullptr;
1668 VSETVLIInfo AvailableInfo;
1669 for (MachineBasicBlock *P : MBB.predecessors()) {
1670 const VSETVLIInfo &PredInfo = BlockInfo[P->getNumber()].Exit;
1671 if (PredInfo.isUnknown()) {
1672 if (UnavailablePred)
1673 return;
1674 UnavailablePred = P;
1675 } else if (!AvailableInfo.isValid()) {
1676 AvailableInfo = PredInfo;
1677 } else if (AvailableInfo != PredInfo) {
1678 return;
1679 }
1680 }
1681
1682 // Unreachable, single pred, or full redundancy. Note that FRE is handled by
1683 // phase 3.
1684 if (!UnavailablePred || !AvailableInfo.isValid())
1685 return;
1686
1687 if (!LIS)
1688 return;
1689
1690 // If we don't know the exact VTYPE, we can't copy the vsetvli to the exit of
1691 // the unavailable pred.
1692 if (AvailableInfo.hasSEWLMULRatioOnly())
1693 return;
1694
1695 // Critical edge - TODO: consider splitting?
1696 if (UnavailablePred->succ_size() != 1)
1697 return;
1698
1699 // If the AVL value is a register (other than our VLMAX sentinel),
1700 // we need to prove the value is available at the point we're going
1701 // to insert the vsetvli at.
1702 if (AvailableInfo.hasAVLReg()) {
1703 SlotIndex SI = AvailableInfo.getAVLVNInfo()->def;
1704 // This is an inline dominance check which covers the case of
1705 // UnavailablePred being the preheader of a loop.
1706 if (LIS->getMBBFromIndex(SI) != UnavailablePred)
1707 return;
1708 if (!UnavailablePred->terminators().empty() &&
1709 SI >= LIS->getInstructionIndex(*UnavailablePred->getFirstTerminator()))
1710 return;
1711 }
1712
1713 // Model the effect of changing the input state of the block MBB to
1714 // AvailableInfo. We're looking for two issues here; one legality,
1715 // one profitability.
1716 // 1) If the block doesn't use some of the fields from VL or VTYPE, we
1717 // may hit the end of the block with a different end state. We can
1718 // not make this change without reflowing later blocks as well.
1719 // 2) If we don't actually remove a transition, inserting a vsetvli
1720 // into the predecessor block would be correct, but unprofitable.
1721 VSETVLIInfo OldInfo = BlockInfo[MBB.getNumber()].Pred;
1722 VSETVLIInfo CurInfo = AvailableInfo;
1723 int TransitionsRemoved = 0;
1724 for (const MachineInstr &MI : MBB) {
1725 const VSETVLIInfo LastInfo = CurInfo;
1726 const VSETVLIInfo LastOldInfo = OldInfo;
1727 transferBefore(CurInfo, MI);
1728 transferBefore(OldInfo, MI);
1729 if (CurInfo == LastInfo)
1730 TransitionsRemoved++;
1731 if (LastOldInfo == OldInfo)
1732 TransitionsRemoved--;
1733 transferAfter(CurInfo, MI);
1734 transferAfter(OldInfo, MI);
1735 if (CurInfo == OldInfo)
1736 // Convergence. All transitions after this must match by construction.
1737 break;
1738 }
1739 if (CurInfo != OldInfo || TransitionsRemoved <= 0)
1740 // Issues 1 and 2 above
1741 return;
1742
1743 // Finally, update both data flow state and insert the actual vsetvli.
1744 // Doing both keeps the code in sync with the dataflow results, which
1745 // is critical for correctness of phase 3.
1746 auto OldExit = BlockInfo[UnavailablePred->getNumber()].Exit;
1747 LLVM_DEBUG(dbgs() << "PRE VSETVLI from " << MBB.getName() << " to "
1748 << UnavailablePred->getName() << " with state "
1749 << AvailableInfo << "\n");
1750 BlockInfo[UnavailablePred->getNumber()].Exit = AvailableInfo;
1751 BlockInfo[MBB.getNumber()].Pred = AvailableInfo;
1752
1753 // Note there's an implicit assumption here that terminators never use
1754 // or modify VL or VTYPE. Also, fallthrough will return end().
1755 auto InsertPt = UnavailablePred->getFirstInstrTerminator();
1756 insertVSETVLI(*UnavailablePred, InsertPt,
1757 UnavailablePred->findDebugLoc(InsertPt),
1758 AvailableInfo, OldExit);
1759}
1760
1761// Return true if we can mutate PrevMI to match MI without changing any the
1762// fields which would be observed.
1763bool RISCVInsertVSETVLI::canMutatePriorConfig(
1764 const MachineInstr &PrevMI, const MachineInstr &MI,
1765 const DemandedFields &Used) const {
1766 // If the VL values aren't equal, return false if either a) the former is
1767 // demanded, or b) we can't rewrite the former to be the later for
1768 // implementation reasons.
1769 if (!RISCVInstrInfo::isVLPreservingConfig(MI)) {
1770 if (Used.VLAny)
1771 return false;
1772
1773 if (Used.VLZeroness) {
1774 if (RISCVInstrInfo::isVLPreservingConfig(PrevMI))
1775 return false;
1776 if (!getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(getInfoForVSETVLI(MI),
1777 LIS))
1778 return false;
1779 }
1780
1781 auto &AVL = MI.getOperand(1);
1782
1783 // If the AVL is a register, we need to make sure its definition is the same
1784 // at PrevMI as it was at MI.
1785 if (AVL.isReg() && AVL.getReg() != RISCV::X0) {
1786 VNInfo *VNI = getVNInfoFromReg(AVL.getReg(), MI, LIS);
1787 VNInfo *PrevVNI = getVNInfoFromReg(AVL.getReg(), PrevMI, LIS);
1788 if (!VNI || !PrevVNI || VNI != PrevVNI)
1789 return false;
1790 }
1791
1792 // If we define VL and need to move the definition up, check we can extend
1793 // the live interval upwards from MI to PrevMI.
1794 Register VL = MI.getOperand(0).getReg();
1795 if (VL.isVirtual() && LIS &&
1796 LIS->getInterval(VL).overlaps(LIS->getInstructionIndex(PrevMI),
1797 LIS->getInstructionIndex(MI)))
1798 return false;
1799 }
1800
1801 assert(PrevMI.getOperand(2).isImm() && MI.getOperand(2).isImm());
1802 auto PriorVType = PrevMI.getOperand(2).getImm();
1803 auto VType = MI.getOperand(2).getImm();
1804 return areCompatibleVTYPEs(PriorVType, VType, Used);
1805}
1806
1807void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
1808 MachineInstr *NextMI = nullptr;
1809 // We can have arbitrary code in successors, so VL and VTYPE
1810 // must be considered demanded.
1811 DemandedFields Used;
1812 Used.demandVL();
1813 Used.demandVTYPE();
1815
1816 auto dropAVLUse = [&](MachineOperand &MO) {
1817 if (!MO.isReg() || !MO.getReg().isVirtual())
1818 return;
1819 Register OldVLReg = MO.getReg();
1820 MO.setReg(Register());
1821
1822 if (LIS)
1823 LIS->shrinkToUses(&LIS->getInterval(OldVLReg));
1824
1825 MachineInstr *VLOpDef = MRI->getUniqueVRegDef(OldVLReg);
1826 if (VLOpDef && TII->isAddImmediate(*VLOpDef, OldVLReg) &&
1827 MRI->use_nodbg_empty(OldVLReg))
1828 ToDelete.push_back(VLOpDef);
1829 };
1830
1831 for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
1832 // TODO: Support XSfmm.
1833 if (RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
1834 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) {
1835 NextMI = nullptr;
1836 continue;
1837 }
1838
1839 if (!RISCVInstrInfo::isVectorConfigInstr(MI)) {
1840 Used.doUnion(getDemanded(MI, ST));
1841 if (MI.isCall() || MI.isInlineAsm() ||
1842 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
1843 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
1844 NextMI = nullptr;
1845 continue;
1846 }
1847
1848 if (!MI.getOperand(0).isDead())
1849 Used.demandVL();
1850
1851 if (NextMI) {
1852 if (!Used.usedVL() && !Used.usedVTYPE()) {
1853 dropAVLUse(MI.getOperand(1));
1854 if (LIS)
1856 MI.eraseFromParent();
1857 NumCoalescedVSETVL++;
1858 // Leave NextMI unchanged
1859 continue;
1860 }
1861
1862 if (canMutatePriorConfig(MI, *NextMI, Used)) {
1863 if (!RISCVInstrInfo::isVLPreservingConfig(*NextMI)) {
1864 Register DefReg = NextMI->getOperand(0).getReg();
1865
1866 MI.getOperand(0).setReg(DefReg);
1867 MI.getOperand(0).setIsDead(false);
1868
1869 // Move the AVL from NextMI to MI
1870 dropAVLUse(MI.getOperand(1));
1871 if (NextMI->getOperand(1).isImm())
1872 MI.getOperand(1).ChangeToImmediate(NextMI->getOperand(1).getImm());
1873 else
1874 MI.getOperand(1).ChangeToRegister(NextMI->getOperand(1).getReg(),
1875 false);
1876 dropAVLUse(NextMI->getOperand(1));
1877
1878 // The def of DefReg moved to MI, so extend the LiveInterval up to
1879 // it.
1880 if (DefReg.isVirtual() && LIS) {
1881 LiveInterval &DefLI = LIS->getInterval(DefReg);
1882 SlotIndex MISlot = LIS->getInstructionIndex(MI).getRegSlot();
1883 SlotIndex NextMISlot =
1884 LIS->getInstructionIndex(*NextMI).getRegSlot();
1885 VNInfo *DefVNI = DefLI.getVNInfoAt(NextMISlot);
1886 LiveInterval::Segment S(MISlot, NextMISlot, DefVNI);
1887 DefLI.addSegment(S);
1888 DefVNI->def = MISlot;
1889 // Mark DefLI as spillable if it was previously unspillable
1890 DefLI.setWeight(0);
1891
1892 // DefReg may have had no uses, in which case we need to shrink
1893 // the LiveInterval up to MI.
1894 LIS->shrinkToUses(&DefLI);
1895 }
1896
1897 MI.setDesc(NextMI->getDesc());
1898 }
1899 MI.getOperand(2).setImm(NextMI->getOperand(2).getImm());
1900
1901 dropAVLUse(NextMI->getOperand(1));
1902 if (LIS)
1903 LIS->RemoveMachineInstrFromMaps(*NextMI);
1904 NextMI->eraseFromParent();
1905 NumCoalescedVSETVL++;
1906 // fallthrough
1907 }
1908 }
1909 NextMI = &MI;
1910 Used = getDemanded(MI, ST);
1911 }
1912
1913 // Loop over the dead AVL values, and delete them now. This has
1914 // to be outside the above loop to avoid invalidating iterators.
1915 for (auto *MI : ToDelete) {
1916 assert(MI->getOpcode() == RISCV::ADDI);
1917 Register AddReg = MI->getOperand(1).getReg();
1918 if (LIS) {
1919 LIS->removeInterval(MI->getOperand(0).getReg());
1921 }
1922 MI->eraseFromParent();
1923 if (LIS && AddReg.isVirtual())
1924 LIS->shrinkToUses(&LIS->getInterval(AddReg));
1925 }
1926}
1927
1928void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) {
1929 for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
1930 MachineInstr &MI = *I++;
1931 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
1932 Register VLOutput = MI.getOperand(1).getReg();
1933 assert(VLOutput.isVirtual());
1934 if (!MI.getOperand(1).isDead()) {
1935 auto ReadVLMI = BuildMI(MBB, I, MI.getDebugLoc(),
1936 TII->get(RISCV::PseudoReadVL), VLOutput);
1937 // Move the LiveInterval's definition down to PseudoReadVL.
1938 if (LIS) {
1939 SlotIndex NewDefSI =
1940 LIS->InsertMachineInstrInMaps(*ReadVLMI).getRegSlot();
1941 LiveInterval &DefLI = LIS->getInterval(VLOutput);
1942 LiveRange::Segment *DefSeg = DefLI.getSegmentContaining(NewDefSI);
1943 VNInfo *DefVNI = DefLI.getVNInfoAt(DefSeg->start);
1944 DefLI.removeSegment(DefSeg->start, NewDefSI);
1945 DefVNI->def = NewDefSI;
1946 }
1947 }
1948 // We don't use the vl output of the VLEFF/VLSEGFF anymore.
1949 MI.getOperand(1).setReg(RISCV::X0);
1950 MI.addRegisterDefined(RISCV::VL, MRI->getTargetRegisterInfo());
1951 }
1952 }
1953}
1954
1955bool RISCVInsertVSETVLI::insertVSETMTK(MachineBasicBlock &MBB,
1956 TKTMMode Mode) const {
1957
1958 bool Changed = false;
1959 for (auto &MI : MBB) {
1960 uint64_t TSFlags = MI.getDesc().TSFlags;
1961 if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI) ||
1962 !RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasTWidenOp(TSFlags))
1963 continue;
1964
1965 VSETVLIInfo CurrInfo = computeInfoForInstr(MI);
1966
1967 if (Mode == VSETTK && !RISCVII::hasTKOp(TSFlags))
1968 continue;
1969
1970 if (Mode == VSETTM && !RISCVII::hasTMOp(TSFlags))
1971 continue;
1972
1973 unsigned OpNum = 0;
1974 unsigned Opcode = 0;
1975 switch (Mode) {
1976 case VSETTK:
1977 OpNum = RISCVII::getTKOpNum(MI.getDesc());
1978 Opcode = RISCV::PseudoSF_VSETTK;
1979 break;
1980 case VSETTM:
1981 OpNum = RISCVII::getTMOpNum(MI.getDesc());
1982 Opcode = RISCV::PseudoSF_VSETTM;
1983 break;
1984 }
1985
1986 assert(OpNum && Opcode && "Invalid OpNum or Opcode");
1987
1988 MachineOperand &Op = MI.getOperand(OpNum);
1989
1990 auto TmpMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(Opcode))
1992 .addReg(Op.getReg())
1993 .addImm(Log2_32(CurrInfo.getSEW()))
1994 .addImm(Log2_32(CurrInfo.getTWiden()) + 1);
1995
1996 Changed = true;
1997 Register Reg = Op.getReg();
1998 Op.setReg(Register());
1999 Op.setIsKill(false);
2000 if (LIS) {
2001 LIS->InsertMachineInstrInMaps(*TmpMI);
2002 LiveInterval &LI = LIS->getInterval(Reg);
2003
2004 // Erase the AVL operand from the instruction.
2005 LIS->shrinkToUses(&LI);
2006 // TODO: Enable this once needVSETVLIPHI is supported.
2007 // SmallVector<LiveInterval *> SplitLIs;
2008 // LIS->splitSeparateComponents(LI, SplitLIs);
2009 }
2010 }
2011 return Changed;
2012}
2013
2014bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
2015 // Skip if the vector extension is not enabled.
2016 ST = &MF.getSubtarget<RISCVSubtarget>();
2017 if (!ST->hasVInstructions())
2018 return false;
2019
2020 LLVM_DEBUG(dbgs() << "Entering InsertVSETVLI for " << MF.getName() << "\n");
2021
2022 TII = ST->getInstrInfo();
2023 MRI = &MF.getRegInfo();
2024 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
2025 LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
2026
2027 assert(BlockInfo.empty() && "Expect empty block infos");
2028 BlockInfo.resize(MF.getNumBlockIDs());
2029
2030 bool HaveVectorOp = false;
2031
2032 // Phase 1 - determine how VL/VTYPE are affected by the each block.
2033 for (const MachineBasicBlock &MBB : MF) {
2034 VSETVLIInfo TmpStatus;
2035 HaveVectorOp |= computeVLVTYPEChanges(MBB, TmpStatus);
2036 // Initial exit state is whatever change we found in the block.
2037 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
2038 BBInfo.Exit = TmpStatus;
2039 LLVM_DEBUG(dbgs() << "Initial exit state of " << printMBBReference(MBB)
2040 << " is " << BBInfo.Exit << "\n");
2041
2042 }
2043
2044 // If we didn't find any instructions that need VSETVLI, we're done.
2045 if (!HaveVectorOp) {
2046 BlockInfo.clear();
2047 return false;
2048 }
2049
2050 // Phase 2 - determine the exit VL/VTYPE from each block. We add all
2051 // blocks to the list here, but will also add any that need to be revisited
2052 // during Phase 2 processing.
2053 for (const MachineBasicBlock &MBB : MF) {
2054 WorkList.push(&MBB);
2055 BlockInfo[MBB.getNumber()].InQueue = true;
2056 }
2057 while (!WorkList.empty()) {
2058 const MachineBasicBlock &MBB = *WorkList.front();
2059 WorkList.pop();
2060 computeIncomingVLVTYPE(MBB);
2061 }
2062
2063 // Perform partial redundancy elimination of vsetvli transitions.
2064 for (MachineBasicBlock &MBB : MF)
2065 doPRE(MBB);
2066
2067 // Phase 3 - add any vsetvli instructions needed in the block. Use the
2068 // Phase 2 information to avoid adding vsetvlis before the first vector
2069 // instruction in the block if the VL/VTYPE is satisfied by its
2070 // predecessors.
2071 for (MachineBasicBlock &MBB : MF)
2072 emitVSETVLIs(MBB);
2073
2074 // Now that all vsetvlis are explicit, go through and do block local
2075 // DSE and peephole based demanded fields based transforms. Note that
2076 // this *must* be done outside the main dataflow so long as we allow
2077 // any cross block analysis within the dataflow. We can't have both
2078 // demanded fields based mutation and non-local analysis in the
2079 // dataflow at the same time without introducing inconsistencies.
2080 // We're visiting blocks from the bottom up because a VSETVLI in the
2081 // earlier block might become dead when its uses in later blocks are
2082 // optimized away.
2083 for (MachineBasicBlock *MBB : post_order(&MF))
2084 coalesceVSETVLIs(*MBB);
2085
2086 // Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
2087 // of VLEFF/VLSEGFF.
2088 for (MachineBasicBlock &MBB : MF)
2089 insertReadVL(MBB);
2090
2091 for (MachineBasicBlock &MBB : MF) {
2092 insertVSETMTK(MBB, VSETTM);
2093 insertVSETMTK(MBB, VSETTK);
2094 }
2095
2096 BlockInfo.clear();
2097 return HaveVectorOp;
2098}
2099
2100/// Returns an instance of the Insert VSETVLI pass.
2102 return new RISCVInsertVSETVLI();
2103}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
Definition CSEInfo.cpp:27
#define LLVM_ATTRIBUTE_USED
Definition Compiler.h:236
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:638
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
static Interval intersect(const Interval &I1, const Interval &I2)
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static cl::opt< bool > EnsureWholeVectorRegisterMoveValidVTYPE(DEBUG_TYPE "-whole-vector-register-move-valid-vtype", cl::Hidden, cl::desc("Insert vsetvlis before vmvNr.vs to ensure vtype is valid and " "vill is cleared"), cl::init(true))
static VSETVLIInfo adjustIncoming(const VSETVLIInfo &PrevInfo, const VSETVLIInfo &NewInfo, DemandedFields &Demanded)
#define RISCV_INSERT_VSETVLI_NAME
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
SI Optimize VGPR LiveRange
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
BlockData()=default
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:270
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
void setWeight(float Value)
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
bool liveAt(SlotIndex index) const
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
bool containsOneValue() const
LLVM_ABI void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
void push_back(const T &Elt)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static unsigned getTMOpNum(const MCInstrDesc &Desc)
static bool usesMaskPolicy(uint64_t TSFlags)
static bool hasTWidenOp(uint64_t TSFlags)
static RISCVVType::VLMUL getLMul(uint64_t TSFlags)
static unsigned getTKOpNum(const MCInstrDesc &Desc)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static AltFmtType getAltFmtType(uint64_t TSFlags)
static bool hasTKOp(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasTMOp(uint64_t TSFlags)
static unsigned getTNOpNum(const MCInstrDesc &Desc)
static bool hasVecPolicyOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isTailAgnostic(unsigned VType)
LLVM_ABI std::optional< VLMUL > getSameRatioLMUL(unsigned SEW, VLMUL VLMUL, unsigned EEW)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static unsigned getXSfmmWiden(unsigned VType)
static bool isMaskAgnostic(unsigned VType)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static bool hasXSfmmWiden(unsigned VType)
LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
static bool isAltFmt(unsigned VType)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
static constexpr int64_t VLMaxSentinel
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Define
Register definition.
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Uninitialized
Definition Threading.h:60
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2114
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:632
iterator_range< po_iterator< T > > post_order(const T &G)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
FunctionPass * createRISCVInsertVSETVLIPass()
Returns an instance of the Insert VSETVLI pass.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Other
Any other memory.
Definition ModRef.h:68
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
char & RISCVInsertVSETVLIID
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
static bool isRVVRegClass(const TargetRegisterClass *RC)