34 #define DEBUG_TYPE "riscv-insert-vsetvli"
35 #define RISCV_INSERT_VSETVLI_NAME "RISCV Insert VSETVLI pass"
39 cl::desc(
"Disable looking through phis when inserting vsetvlis."));
43 cl::desc(
"Enable strict assertion checking for the dataflow algorithm"));
56 switch (
MI.getOpcode()) {
59 case RISCV::PseudoVMV_S_X_M1:
60 case RISCV::PseudoVMV_S_X_M2:
61 case RISCV::PseudoVMV_S_X_M4:
62 case RISCV::PseudoVMV_S_X_M8:
63 case RISCV::PseudoVMV_S_X_MF2:
64 case RISCV::PseudoVMV_S_X_MF4:
65 case RISCV::PseudoVMV_S_X_MF8:
66 case RISCV::PseudoVFMV_S_F16_M1:
67 case RISCV::PseudoVFMV_S_F16_M2:
68 case RISCV::PseudoVFMV_S_F16_M4:
69 case RISCV::PseudoVFMV_S_F16_M8:
70 case RISCV::PseudoVFMV_S_F16_MF2:
71 case RISCV::PseudoVFMV_S_F16_MF4:
72 case RISCV::PseudoVFMV_S_F32_M1:
73 case RISCV::PseudoVFMV_S_F32_M2:
74 case RISCV::PseudoVFMV_S_F32_M4:
75 case RISCV::PseudoVFMV_S_F32_M8:
76 case RISCV::PseudoVFMV_S_F32_MF2:
77 case RISCV::PseudoVFMV_S_F64_M1:
78 case RISCV::PseudoVFMV_S_F64_M2:
79 case RISCV::PseudoVFMV_S_F64_M4:
80 case RISCV::PseudoVFMV_S_F64_M8:
88 switch (
MI.getOpcode()) {
91 case RISCV::PseudoVLE8_V_M1:
92 case RISCV::PseudoVLE8_V_M1_MASK:
93 case RISCV::PseudoVLE8_V_M2:
94 case RISCV::PseudoVLE8_V_M2_MASK:
95 case RISCV::PseudoVLE8_V_M4:
96 case RISCV::PseudoVLE8_V_M4_MASK:
97 case RISCV::PseudoVLE8_V_M8:
98 case RISCV::PseudoVLE8_V_M8_MASK:
99 case RISCV::PseudoVLE8_V_MF2:
100 case RISCV::PseudoVLE8_V_MF2_MASK:
101 case RISCV::PseudoVLE8_V_MF4:
102 case RISCV::PseudoVLE8_V_MF4_MASK:
103 case RISCV::PseudoVLE8_V_MF8:
104 case RISCV::PseudoVLE8_V_MF8_MASK:
105 case RISCV::PseudoVLSE8_V_M1:
106 case RISCV::PseudoVLSE8_V_M1_MASK:
107 case RISCV::PseudoVLSE8_V_M2:
108 case RISCV::PseudoVLSE8_V_M2_MASK:
109 case RISCV::PseudoVLSE8_V_M4:
110 case RISCV::PseudoVLSE8_V_M4_MASK:
111 case RISCV::PseudoVLSE8_V_M8:
112 case RISCV::PseudoVLSE8_V_M8_MASK:
113 case RISCV::PseudoVLSE8_V_MF2:
114 case RISCV::PseudoVLSE8_V_MF2_MASK:
115 case RISCV::PseudoVLSE8_V_MF4:
116 case RISCV::PseudoVLSE8_V_MF4_MASK:
117 case RISCV::PseudoVLSE8_V_MF8:
118 case RISCV::PseudoVLSE8_V_MF8_MASK:
119 case RISCV::PseudoVSE8_V_M1:
120 case RISCV::PseudoVSE8_V_M1_MASK:
121 case RISCV::PseudoVSE8_V_M2:
122 case RISCV::PseudoVSE8_V_M2_MASK:
123 case RISCV::PseudoVSE8_V_M4:
124 case RISCV::PseudoVSE8_V_M4_MASK:
125 case RISCV::PseudoVSE8_V_M8:
126 case RISCV::PseudoVSE8_V_M8_MASK:
127 case RISCV::PseudoVSE8_V_MF2:
128 case RISCV::PseudoVSE8_V_MF2_MASK:
129 case RISCV::PseudoVSE8_V_MF4:
130 case RISCV::PseudoVSE8_V_MF4_MASK:
131 case RISCV::PseudoVSE8_V_MF8:
132 case RISCV::PseudoVSE8_V_MF8_MASK:
133 case RISCV::PseudoVSSE8_V_M1:
134 case RISCV::PseudoVSSE8_V_M1_MASK:
135 case RISCV::PseudoVSSE8_V_M2:
136 case RISCV::PseudoVSSE8_V_M2_MASK:
137 case RISCV::PseudoVSSE8_V_M4:
138 case RISCV::PseudoVSSE8_V_M4_MASK:
139 case RISCV::PseudoVSSE8_V_M8:
140 case RISCV::PseudoVSSE8_V_M8_MASK:
141 case RISCV::PseudoVSSE8_V_MF2:
142 case RISCV::PseudoVSSE8_V_MF2_MASK:
143 case RISCV::PseudoVSSE8_V_MF4:
144 case RISCV::PseudoVSSE8_V_MF4_MASK:
145 case RISCV::PseudoVSSE8_V_MF8:
146 case RISCV::PseudoVSSE8_V_MF8_MASK:
148 case RISCV::PseudoVLE16_V_M1:
149 case RISCV::PseudoVLE16_V_M1_MASK:
150 case RISCV::PseudoVLE16_V_M2:
151 case RISCV::PseudoVLE16_V_M2_MASK:
152 case RISCV::PseudoVLE16_V_M4:
153 case RISCV::PseudoVLE16_V_M4_MASK:
154 case RISCV::PseudoVLE16_V_M8:
155 case RISCV::PseudoVLE16_V_M8_MASK:
156 case RISCV::PseudoVLE16_V_MF2:
157 case RISCV::PseudoVLE16_V_MF2_MASK:
158 case RISCV::PseudoVLE16_V_MF4:
159 case RISCV::PseudoVLE16_V_MF4_MASK:
160 case RISCV::PseudoVLSE16_V_M1:
161 case RISCV::PseudoVLSE16_V_M1_MASK:
162 case RISCV::PseudoVLSE16_V_M2:
163 case RISCV::PseudoVLSE16_V_M2_MASK:
164 case RISCV::PseudoVLSE16_V_M4:
165 case RISCV::PseudoVLSE16_V_M4_MASK:
166 case RISCV::PseudoVLSE16_V_M8:
167 case RISCV::PseudoVLSE16_V_M8_MASK:
168 case RISCV::PseudoVLSE16_V_MF2:
169 case RISCV::PseudoVLSE16_V_MF2_MASK:
170 case RISCV::PseudoVLSE16_V_MF4:
171 case RISCV::PseudoVLSE16_V_MF4_MASK:
172 case RISCV::PseudoVSE16_V_M1:
173 case RISCV::PseudoVSE16_V_M1_MASK:
174 case RISCV::PseudoVSE16_V_M2:
175 case RISCV::PseudoVSE16_V_M2_MASK:
176 case RISCV::PseudoVSE16_V_M4:
177 case RISCV::PseudoVSE16_V_M4_MASK:
178 case RISCV::PseudoVSE16_V_M8:
179 case RISCV::PseudoVSE16_V_M8_MASK:
180 case RISCV::PseudoVSE16_V_MF2:
181 case RISCV::PseudoVSE16_V_MF2_MASK:
182 case RISCV::PseudoVSE16_V_MF4:
183 case RISCV::PseudoVSE16_V_MF4_MASK:
184 case RISCV::PseudoVSSE16_V_M1:
185 case RISCV::PseudoVSSE16_V_M1_MASK:
186 case RISCV::PseudoVSSE16_V_M2:
187 case RISCV::PseudoVSSE16_V_M2_MASK:
188 case RISCV::PseudoVSSE16_V_M4:
189 case RISCV::PseudoVSSE16_V_M4_MASK:
190 case RISCV::PseudoVSSE16_V_M8:
191 case RISCV::PseudoVSSE16_V_M8_MASK:
192 case RISCV::PseudoVSSE16_V_MF2:
193 case RISCV::PseudoVSSE16_V_MF2_MASK:
194 case RISCV::PseudoVSSE16_V_MF4:
195 case RISCV::PseudoVSSE16_V_MF4_MASK:
197 case RISCV::PseudoVLE32_V_M1:
198 case RISCV::PseudoVLE32_V_M1_MASK:
199 case RISCV::PseudoVLE32_V_M2:
200 case RISCV::PseudoVLE32_V_M2_MASK:
201 case RISCV::PseudoVLE32_V_M4:
202 case RISCV::PseudoVLE32_V_M4_MASK:
203 case RISCV::PseudoVLE32_V_M8:
204 case RISCV::PseudoVLE32_V_M8_MASK:
205 case RISCV::PseudoVLE32_V_MF2:
206 case RISCV::PseudoVLE32_V_MF2_MASK:
207 case RISCV::PseudoVLSE32_V_M1:
208 case RISCV::PseudoVLSE32_V_M1_MASK:
209 case RISCV::PseudoVLSE32_V_M2:
210 case RISCV::PseudoVLSE32_V_M2_MASK:
211 case RISCV::PseudoVLSE32_V_M4:
212 case RISCV::PseudoVLSE32_V_M4_MASK:
213 case RISCV::PseudoVLSE32_V_M8:
214 case RISCV::PseudoVLSE32_V_M8_MASK:
215 case RISCV::PseudoVLSE32_V_MF2:
216 case RISCV::PseudoVLSE32_V_MF2_MASK:
217 case RISCV::PseudoVSE32_V_M1:
218 case RISCV::PseudoVSE32_V_M1_MASK:
219 case RISCV::PseudoVSE32_V_M2:
220 case RISCV::PseudoVSE32_V_M2_MASK:
221 case RISCV::PseudoVSE32_V_M4:
222 case RISCV::PseudoVSE32_V_M4_MASK:
223 case RISCV::PseudoVSE32_V_M8:
224 case RISCV::PseudoVSE32_V_M8_MASK:
225 case RISCV::PseudoVSE32_V_MF2:
226 case RISCV::PseudoVSE32_V_MF2_MASK:
227 case RISCV::PseudoVSSE32_V_M1:
228 case RISCV::PseudoVSSE32_V_M1_MASK:
229 case RISCV::PseudoVSSE32_V_M2:
230 case RISCV::PseudoVSSE32_V_M2_MASK:
231 case RISCV::PseudoVSSE32_V_M4:
232 case RISCV::PseudoVSSE32_V_M4_MASK:
233 case RISCV::PseudoVSSE32_V_M8:
234 case RISCV::PseudoVSSE32_V_M8_MASK:
235 case RISCV::PseudoVSSE32_V_MF2:
236 case RISCV::PseudoVSSE32_V_MF2_MASK:
238 case RISCV::PseudoVLE64_V_M1:
239 case RISCV::PseudoVLE64_V_M1_MASK:
240 case RISCV::PseudoVLE64_V_M2:
241 case RISCV::PseudoVLE64_V_M2_MASK:
242 case RISCV::PseudoVLE64_V_M4:
243 case RISCV::PseudoVLE64_V_M4_MASK:
244 case RISCV::PseudoVLE64_V_M8:
245 case RISCV::PseudoVLE64_V_M8_MASK:
246 case RISCV::PseudoVLSE64_V_M1:
247 case RISCV::PseudoVLSE64_V_M1_MASK:
248 case RISCV::PseudoVLSE64_V_M2:
249 case RISCV::PseudoVLSE64_V_M2_MASK:
250 case RISCV::PseudoVLSE64_V_M4:
251 case RISCV::PseudoVLSE64_V_M4_MASK:
252 case RISCV::PseudoVLSE64_V_M8:
253 case RISCV::PseudoVLSE64_V_M8_MASK:
254 case RISCV::PseudoVSE64_V_M1:
255 case RISCV::PseudoVSE64_V_M1_MASK:
256 case RISCV::PseudoVSE64_V_M2:
257 case RISCV::PseudoVSE64_V_M2_MASK:
258 case RISCV::PseudoVSE64_V_M4:
259 case RISCV::PseudoVSE64_V_M4_MASK:
260 case RISCV::PseudoVSE64_V_M8:
261 case RISCV::PseudoVSE64_V_M8_MASK:
262 case RISCV::PseudoVSSE64_V_M1:
263 case RISCV::PseudoVSSE64_V_M1_MASK:
264 case RISCV::PseudoVSSE64_V_M2:
265 case RISCV::PseudoVSSE64_V_M2_MASK:
266 case RISCV::PseudoVSSE64_V_M4:
267 case RISCV::PseudoVSSE64_V_M4_MASK:
268 case RISCV::PseudoVSSE64_V_M8:
269 case RISCV::PseudoVSSE64_V_M8_MASK:
285 static unsigned getSEWLMULRatio(
unsigned SEW,
RISCVII::VLMUL VLMul) {
291 LMul = Fractional ? (8 / LMul) : (LMul * 8);
293 assert(SEW >= 8 &&
"Unexpected SEW value");
294 return (SEW * 8) / LMul;
298 struct DemandedFields {
302 bool SEWLMULRatio =
false;
303 bool TailPolicy =
false;
304 bool MaskPolicy =
false;
308 return SEW ||
LMUL || SEWLMULRatio || TailPolicy || MaskPolicy;
324 static bool areCompatibleVTYPEs(
uint64_t VType1,
326 const DemandedFields &Used) {
335 if (
Used.SEWLMULRatio) {
340 if (Ratio1 != Ratio2)
344 if (
Used.TailPolicy &&
347 if (
Used.MaskPolicy &&
363 if (
MI.isCall() ||
MI.isInlineAsm() ||
MI.readsRegister(RISCV::VL))
365 if (
MI.isCall() ||
MI.isInlineAsm() ||
MI.readsRegister(RISCV::VTYPE))
381 if (getEEWForLoadStore(
MI)) {
388 Res.TailPolicy =
false;
389 Res.MaskPolicy =
false;
396 if (isMaskRegOp(
MI)) {
422 uint8_t TailAgnostic : 1;
423 uint8_t MaskAgnostic : 1;
424 uint8_t SEWLMULRatioOnly : 1;
428 : AVLImm(0), TailAgnostic(
false), MaskAgnostic(
false),
429 SEWLMULRatioOnly(
false) {}
431 static VSETVLIInfo getUnknown() {
438 void setUnknown() { State =
Unknown; }
439 bool isUnknown()
const {
return State ==
Unknown; }
446 void setAVLImm(
unsigned Imm) {
451 bool hasAVLImm()
const {
return State == AVLIsImm; }
452 bool hasAVLReg()
const {
return State == AVLIsReg; }
457 unsigned getAVLImm()
const {
462 unsigned getSEW()
const {
return SEW; }
465 bool hasNonZeroAVL()
const {
467 return getAVLImm() > 0;
469 return getAVLReg() == RISCV::X0;
473 bool hasSameAVL(
const VSETVLIInfo &Other)
const {
475 "Can't compare invalid VSETVLIInfos");
477 "Can't compare AVL in unknown state");
478 if (hasAVLReg() &&
Other.hasAVLReg())
479 return getAVLReg() ==
Other.getAVLReg();
481 if (hasAVLImm() &&
Other.hasAVLImm())
482 return getAVLImm() ==
Other.getAVLImm();
487 void setVTYPE(
unsigned VType) {
489 "Can't set VTYPE for uninitialized or unknown");
497 "Can't set VTYPE for uninitialized or unknown");
506 "Can't encode VTYPE for uninitialized or unknown");
510 bool hasSEWLMULRatioOnly()
const {
return SEWLMULRatioOnly; }
512 bool hasSameSEW(
const VSETVLIInfo &Other)
const {
514 "Can't compare invalid VSETVLIInfos");
516 "Can't compare VTYPE in unknown state");
517 assert(!SEWLMULRatioOnly && !
Other.SEWLMULRatioOnly &&
518 "Can't compare when only LMUL/SEW ratio is valid.");
519 return SEW ==
Other.SEW;
522 bool hasSameVTYPE(
const VSETVLIInfo &Other)
const {
524 "Can't compare invalid VSETVLIInfos");
526 "Can't compare VTYPE in unknown state");
527 assert(!SEWLMULRatioOnly && !
Other.SEWLMULRatioOnly &&
528 "Can't compare when only LMUL/SEW ratio is valid.");
529 return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) ==
534 unsigned getSEWLMULRatio()
const {
536 "Can't use VTYPE for uninitialized or unknown");
537 return ::getSEWLMULRatio(SEW, VLMul);
544 bool hasSameVLMAX(
const VSETVLIInfo &Other)
const {
546 "Can't compare invalid VSETVLIInfos");
548 "Can't compare VTYPE in unknown state");
549 return getSEWLMULRatio() ==
Other.getSEWLMULRatio();
552 bool hasSamePolicy(
const VSETVLIInfo &Other)
const {
554 "Can't compare invalid VSETVLIInfos");
556 "Can't compare VTYPE in unknown state");
557 return TailAgnostic ==
Other.TailAgnostic &&
558 MaskAgnostic ==
Other.MaskAgnostic;
562 const VSETVLIInfo &Require)
const {
563 const DemandedFields
Used = getDemanded(
MI);
564 return areCompatibleVTYPEs(
encodeVTYPE(), Require.encodeVTYPE(), Used);
570 bool isCompatible(
const MachineInstr &
MI,
const VSETVLIInfo &Require)
const {
572 "Can't compare invalid VSETVLIInfos");
573 assert(!Require.SEWLMULRatioOnly &&
574 "Expected a valid VTYPE for instruction!");
576 if (isUnknown() || Require.isUnknown())
580 if (SEWLMULRatioOnly)
585 if (Require.hasAVLReg() && Require.AVLReg == RISCV::NoRegister)
586 if (SEW == Require.SEW)
589 return hasSameAVL(Require) && hasCompatibleVTYPE(
MI, Require);
592 bool operator==(
const VSETVLIInfo &Other)
const {
595 return !
Other.isValid();
596 if (!
Other.isValid())
601 return Other.isUnknown();
602 if (
Other.isUnknown())
605 if (!hasSameAVL(Other))
609 if (SEWLMULRatioOnly !=
Other.SEWLMULRatioOnly)
613 if (SEWLMULRatioOnly)
614 return hasSameVLMAX(Other);
617 return hasSameVTYPE(Other);
620 bool operator!=(
const VSETVLIInfo &Other)
const {
621 return !(*
this ==
Other);
626 VSETVLIInfo
intersect(
const VSETVLIInfo &Other)
const {
628 if (!
Other.isValid())
636 if (isUnknown() ||
Other.isUnknown())
637 return VSETVLIInfo::getUnknown();
645 if (hasSameAVL(Other) && hasSameVLMAX(Other)) {
646 VSETVLIInfo MergeInfo = *
this;
647 MergeInfo.SEWLMULRatioOnly =
true;
652 return VSETVLIInfo::getUnknown();
655 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
667 OS <<
"Uninitialized";
671 OS <<
"AVLReg=" << (unsigned)AVLReg;
673 OS <<
"AVLImm=" << (
unsigned)AVLImm;
675 <<
"VLMul=" << (unsigned)VLMul <<
", "
676 <<
"SEW=" << (
unsigned)SEW <<
", "
677 <<
"TailAgnostic=" << (bool)TailAgnostic <<
", "
678 <<
"MaskAgnostic=" << (
bool)MaskAgnostic <<
", "
679 <<
"SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly <<
"}";
684 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
706 bool InQueue =
false;
708 BlockData() =
default;
715 std::vector<BlockData> BlockInfo;
716 std::queue<const MachineBasicBlock *> WorkList;
734 bool needVSETVLI(
const MachineInstr &
MI,
const VSETVLIInfo &Require,
735 const VSETVLIInfo &CurInfo)
const;
736 bool needVSETVLIPHI(
const VSETVLIInfo &Require,
739 const VSETVLIInfo &
Info,
const VSETVLIInfo &PrevInfo);
742 const VSETVLIInfo &
Info,
const VSETVLIInfo &PrevInfo);
762 return MI.getOpcode() == RISCV::PseudoVSETVLI ||
763 MI.getOpcode() == RISCV::PseudoVSETVLIX0 ||
764 MI.getOpcode() == RISCV::PseudoVSETIVLI;
770 if (
MI.getOpcode() != RISCV::PseudoVSETVLIX0)
772 assert(RISCV::X0 ==
MI.getOperand(1).getReg());
773 return RISCV::X0 ==
MI.getOperand(0).getReg();
778 VSETVLIInfo InstrInfo;
784 bool TailAgnostic =
true;
791 bool MaskAgnostic = UsesMaskPolicy;
797 "Invalid Policy Value");
804 }
else if (
MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
805 TailAgnostic =
false;
807 MaskAgnostic =
false;
826 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
835 InstrInfo.setAVLReg(RISCV::X0);
837 InstrInfo.setAVLImm(
Imm);
839 InstrInfo.setAVLReg(VLOp.
getReg());
842 InstrInfo.setAVLReg(RISCV::NoRegister);
846 assert(SEW == EEW &&
"Initial SEW doesn't match expected EEW");
849 InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic);
855 const VSETVLIInfo &
Info,
856 const VSETVLIInfo &PrevInfo) {
863 const VSETVLIInfo &
Info,
const VSETVLIInfo &PrevInfo) {
867 if (PrevInfo.isValid() && !PrevInfo.isUnknown() &&
868 Info.hasSameAVL(PrevInfo) &&
Info.hasSameVLMAX(PrevInfo)) {
877 if (
Info.hasAVLImm()) {
886 if (AVLReg == RISCV::NoRegister) {
889 if (PrevInfo.isValid() && !PrevInfo.isUnknown() &&
890 Info.hasSameVLMAX(PrevInfo)) {
913 unsigned Opcode = RISCV::PseudoVSETVLI;
914 if (AVLReg == RISCV::X0) {
916 Opcode = RISCV::PseudoVSETVLIX0;
928 if (
MI.getOpcode() == RISCV::PseudoVSETIVLI) {
929 NewInfo.setAVLImm(
MI.getOperand(1).getImm());
931 assert(
MI.getOpcode() == RISCV::PseudoVSETVLI ||
932 MI.getOpcode() == RISCV::PseudoVSETVLIX0);
934 assert((AVLReg != RISCV::X0 ||
MI.getOperand(0).getReg() != RISCV::X0) &&
935 "Can't handle X0, X0 vsetvli yet");
936 NewInfo.setAVLReg(AVLReg);
938 NewInfo.setVTYPE(
MI.getOperand(2).getImm());
946 const VSETVLIInfo &Require,
947 const VSETVLIInfo &CurInfo)
const {
950 if (CurInfo.isCompatible(
MI, Require))
953 if (!CurInfo.isValid() || CurInfo.isUnknown() || CurInfo.hasSEWLMULRatioOnly())
961 if (isScalarMoveInstr(
MI) &&
962 CurInfo.hasNonZeroAVL() && Require.hasNonZeroAVL()) {
964 if (VRegDef && VRegDef->isImplicitDef() &&
965 CurInfo.getSEW() >= Require.getSEW())
967 if (CurInfo.hasSameSEW(Require) && CurInfo.hasSamePolicy(Require))
975 if (Require.hasAVLReg() && Require.getAVLReg().isVirtual() &&
976 CurInfo.hasCompatibleVTYPE(
MI, Require)) {
978 if (isVectorConfigInstr(*
DefMI)) {
980 if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
998 if (
Info.isValid() && !needVSETVLI(
MI, NewInfo,
Info))
1001 const VSETVLIInfo PrevInfo =
Info;
1015 if (isScalarMoveInstr(
MI) && PrevInfo.isValid() &&
1016 PrevInfo.hasNonZeroAVL() &&
Info.hasNonZeroAVL() &&
1017 Info.hasSameVLMAX(PrevInfo)) {
1018 if (PrevInfo.hasAVLImm())
1019 Info.setAVLImm(PrevInfo.getAVLImm());
1021 Info.setAVLReg(PrevInfo.getAVLReg());
1035 if (!
Info.hasAVLReg() || !
Info.getAVLReg().isVirtual())
1043 if (PrevInfo.isValid() && !PrevInfo.isUnknown() &&
1044 DefInfo.hasSameAVL(PrevInfo) &&
1045 DefInfo.hasSameVLMAX(PrevInfo)) {
1046 if (PrevInfo.hasAVLImm())
1047 Info.setAVLImm(PrevInfo.getAVLImm());
1049 Info.setAVLReg(PrevInfo.getAVLReg());
1053 if (DefInfo.hasSameVLMAX(
Info) &&
1054 (DefInfo.hasAVLImm() || DefInfo.getAVLReg() == RISCV::X0)) {
1055 if (DefInfo.hasAVLImm())
1056 Info.setAVLImm(DefInfo.getAVLImm());
1058 Info.setAVLReg(DefInfo.getAVLReg());
1067 if (isVectorConfigInstr(
MI)) {
1074 Info.setAVLReg(
MI.getOperand(1).getReg());
1080 if (
MI.isCall() ||
MI.isInlineAsm() ||
MI.modifiesRegister(RISCV::VL) ||
1081 MI.modifiesRegister(RISCV::VTYPE))
1082 Info = VSETVLIInfo::getUnknown();
1086 bool HadVectorOp =
false;
1089 BBInfo.Change = BBInfo.Pred;
1091 transferBefore(BBInfo.Change,
MI);
1096 transferAfter(BBInfo.Change,
MI);
1106 BBInfo.InQueue =
false;
1111 InInfo.setUnknown();
1114 InInfo = InInfo.intersect(BlockInfo[
P->getNumber()].Exit);
1118 if (!InInfo.isValid())
1122 if (InInfo == BBInfo.Pred)
1125 BBInfo.Pred = InInfo;
1127 <<
" changed to " << BBInfo.Pred <<
"\n");
1133 computeVLVTYPEChanges(
MBB);
1134 VSETVLIInfo TmpStatus = BBInfo.Change;
1138 if (BBInfo.Exit == TmpStatus)
1141 BBInfo.Exit = TmpStatus;
1143 <<
" changed to " << BBInfo.Exit <<
"\n");
1148 if (!BlockInfo[
S->getNumber()].InQueue)
1155 bool RISCVInsertVSETVLI::needVSETVLIPHI(
const VSETVLIInfo &Require,
1160 if (!Require.hasAVLReg())
1163 Register AVLReg = Require.getAVLReg();
1172 for (
unsigned PHIOp = 1, NumOps = PHI->
getNumOperands(); PHIOp != NumOps;
1176 const BlockData &PBBInfo = BlockInfo[PBB->
getNumber()];
1179 if (PBBInfo.Exit.isUnknown() || !PBBInfo.Exit.hasSameVTYPE(Require))
1190 if (!DefInfo.hasSameAVL(PBBInfo.Exit) ||
1191 !DefInfo.hasSameVTYPE(PBBInfo.Exit))
1204 bool PrefixTransparent =
true;
1206 const VSETVLIInfo PrevInfo = CurInfo;
1207 transferBefore(CurInfo,
MI);
1210 if (isVectorConfigInstr(
MI)) {
1212 assert(
MI.getOperand(3).getReg() == RISCV::VL &&
1213 MI.getOperand(4).getReg() == RISCV::VTYPE &&
1214 "Unexpected operands where VL and VTYPE should be");
1215 MI.getOperand(3).setIsDead(
false);
1216 MI.getOperand(4).setIsDead(
false);
1217 PrefixTransparent =
false;
1222 if (PrevInfo != CurInfo) {
1230 if (!PrefixTransparent || needVSETVLIPHI(CurInfo,
MBB))
1231 insertVSETVLI(
MBB,
MI, CurInfo, PrevInfo);
1232 PrefixTransparent =
false;
1239 VLOp.
setReg(RISCV::NoRegister);
1249 if (
MI.isCall() ||
MI.isInlineAsm() ||
MI.modifiesRegister(RISCV::VL) ||
1250 MI.modifiesRegister(RISCV::VTYPE))
1251 PrefixTransparent =
false;
1253 transferAfter(CurInfo,
MI);
1259 const VSETVLIInfo &ExitInfo = BlockInfo[
MBB.
getNumber()].Exit;
1260 if (CurInfo.isValid() && ExitInfo.isValid() && !ExitInfo.isUnknown() &&
1261 CurInfo != ExitInfo) {
1273 if (CurInfo !=
Info.Exit) {
1280 "InsertVSETVLI dataflow invariant violated");
1286 if (!
Info.hasAVLImm())
1290 return RISCV::X0 ==
Info.getAVLReg();
1292 unsigned AVL =
Info.getAVLImm();
1293 unsigned SEW =
Info.getSEW();
1294 unsigned AVLInBits = AVL * SEW;
1301 return ST.getRealMinVLen() / LMul >= AVLInBits;
1302 return ST.getRealMinVLen() * LMul >= AVLInBits;
1318 VSETVLIInfo AvailableInfo;
1320 const VSETVLIInfo &PredInfo = BlockInfo[
P->getNumber()].Exit;
1321 if (PredInfo.isUnknown()) {
1322 if (UnavailablePred)
1324 UnavailablePred =
P;
1325 }
else if (!AvailableInfo.isValid()) {
1326 AvailableInfo = PredInfo;
1327 }
else if (AvailableInfo != PredInfo) {
1334 if (!UnavailablePred || !AvailableInfo.isValid())
1347 for (
auto &
MI :
MBB) {
1348 if (isVectorConfigInstr(
MI))
1351 const uint64_t TSFlags =
MI.getDesc().TSFlags;
1365 auto OldInfo = BlockInfo[UnavailablePred->
getNumber()].Exit;
1367 << UnavailablePred->
getName() <<
" with state "
1368 << AvailableInfo <<
"\n");
1369 BlockInfo[UnavailablePred->
getNumber()].Exit = AvailableInfo;
1375 insertVSETVLI(*UnavailablePred, InsertPt,
1377 AvailableInfo, OldInfo);
1380 static void doUnion(DemandedFields &A, DemandedFields
B) {
1384 A.SEWLMULRatio |=
B.SEWLMULRatio;
1385 A.TailPolicy |=
B.TailPolicy;
1386 A.MaskPolicy |=
B.MaskPolicy;
1395 const DemandedFields &Used) {
1409 auto VType =
MI.getOperand(2).getImm();
1410 return areCompatibleVTYPEs(PriorVType, VType, Used);
1415 DemandedFields
Used;
1422 if (!isVectorConfigInstr(
MI))
1426 if (!
Used.VL && !
Used.usedVTYPE()) {
1427 ToDelete.push_back(PrevMI);
1431 ToDelete.push_back(&
MI);
1438 Register VRegDef =
MI.getOperand(0).getReg();
1439 if (VRegDef != RISCV::X0 &&
1444 for (
auto *
MI : ToDelete)
1445 MI->eraseFromParent();
1452 Register VLOutput =
MI.getOperand(1).getReg();
1457 MI.getOperand(1).setReg(RISCV::X0);
1465 if (!
ST.hasVInstructions())
1470 TII =
ST.getInstrInfo();
1473 assert(BlockInfo.empty() &&
"Expect empty block infos");
1476 bool HaveVectorOp =
false;
1480 HaveVectorOp |= computeVLVTYPEChanges(
MBB);
1483 BBInfo.Exit = BBInfo.Change;
1485 <<
" is " << BBInfo.Exit <<
"\n");
1490 if (!HaveVectorOp) {
1499 WorkList.push(&
MBB);
1502 while (!WorkList.empty()) {
1505 computeIncomingVLVTYPE(
MBB);
1526 doLocalPostpass(
MBB);
1535 if (
MI.getOpcode() == RISCV::PseudoVSETVLI ||
1536 MI.getOpcode() == RISCV::PseudoVSETIVLI) {
1537 Register VRegDef =
MI.getOperand(0).getReg();
1539 MI.getOperand(0).setReg(RISCV::X0);
1550 return HaveVectorOp;
1555 return new RISCVInsertVSETVLI();