@@ -452,6 +452,8 @@ class VSETVLIInfo {
452
452
Uninitialized,
453
453
AVLIsReg,
454
454
AVLIsImm,
455
+ AVLIsVLMAX,
456
+ AVLIsIgnored,
455
457
Unknown,
456
458
} State = Uninitialized;
457
459
@@ -478,7 +480,7 @@ class VSETVLIInfo {
478
480
bool isUnknown () const { return State == Unknown; }
479
481
480
482
void setAVLReg (Register Reg) {
481
- assert (Reg.isVirtual () || Reg == RISCV::X0 || Reg == RISCV::NoRegister );
483
+ assert (Reg.isVirtual ());
482
484
AVLReg = Reg;
483
485
State = AVLIsReg;
484
486
}
@@ -488,8 +490,14 @@ class VSETVLIInfo {
488
490
State = AVLIsImm;
489
491
}
490
492
493
+ void setAVLVLMAX () { State = AVLIsVLMAX; }
494
+
495
+ void setAVLIgnored () { State = AVLIsIgnored; }
496
+
491
497
bool hasAVLImm () const { return State == AVLIsImm; }
492
498
bool hasAVLReg () const { return State == AVLIsReg; }
499
+ bool hasAVLVLMAX () const { return State == AVLIsVLMAX; }
500
+ bool hasAVLIgnored () const { return State == AVLIsIgnored; }
493
501
Register getAVLReg () const {
494
502
assert (hasAVLReg ());
495
503
return AVLReg;
@@ -505,6 +513,10 @@ class VSETVLIInfo {
505
513
setUnknown ();
506
514
else if (Info.hasAVLReg ())
507
515
setAVLReg (Info.getAVLReg ());
516
+ else if (Info.hasAVLVLMAX ())
517
+ setAVLVLMAX ();
518
+ else if (Info.hasAVLIgnored ())
519
+ setAVLIgnored ();
508
520
else {
509
521
assert (Info.hasAVLImm ());
510
522
setAVLImm (Info.getAVLImm ());
@@ -520,13 +532,14 @@ class VSETVLIInfo {
520
532
if (hasAVLImm ())
521
533
return getAVLImm () > 0 ;
522
534
if (hasAVLReg ()) {
523
- if (getAVLReg () == RISCV::X0)
524
- return true ;
525
- if (MachineInstr *MI = MRI.getVRegDef (getAVLReg ());
526
- MI && isNonZeroLoadImmediate (*MI))
527
- return true ;
528
- return false ;
535
+ MachineInstr *MI = MRI.getUniqueVRegDef (getAVLReg ());
536
+ assert (MI);
537
+ return isNonZeroLoadImmediate (*MI);
529
538
}
539
+ if (hasAVLVLMAX ())
540
+ return true ;
541
+ if (hasAVLIgnored ())
542
+ return false ;
530
543
return false ;
531
544
}
532
545
@@ -544,6 +557,12 @@ class VSETVLIInfo {
544
557
if (hasAVLImm () && Other.hasAVLImm ())
545
558
return getAVLImm () == Other.getAVLImm ();
546
559
560
+ if (hasAVLVLMAX ())
561
+ return Other.hasAVLVLMAX () && hasSameVLMAX (Other);
562
+
563
+ if (hasAVLIgnored ())
564
+ return Other.hasAVLIgnored ();
565
+
547
566
return false ;
548
567
}
549
568
@@ -717,6 +736,10 @@ class VSETVLIInfo {
717
736
OS << " AVLReg=" << (unsigned )AVLReg;
718
737
if (hasAVLImm ())
719
738
OS << " AVLImm=" << (unsigned )AVLImm;
739
+ if (hasAVLVLMAX ())
740
+ OS << " AVLVLMAX" ;
741
+ if (hasAVLIgnored ())
742
+ OS << " AVLIgnored" ;
720
743
OS << " , "
721
744
<< " VLMul=" << (unsigned )VLMul << " , "
722
745
<< " SEW=" << (unsigned )SEW << " , "
@@ -846,7 +869,10 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
846
869
Register AVLReg = MI.getOperand (1 ).getReg ();
847
870
assert ((AVLReg != RISCV::X0 || MI.getOperand (0 ).getReg () != RISCV::X0) &&
848
871
" Can't handle X0, X0 vsetvli yet" );
849
- NewInfo.setAVLReg (AVLReg);
872
+ if (AVLReg == RISCV::X0)
873
+ NewInfo.setAVLVLMAX ();
874
+ else
875
+ NewInfo.setAVLReg (AVLReg);
850
876
}
851
877
NewInfo.setVTYPE (MI.getOperand (2 ).getImm ());
852
878
@@ -913,7 +939,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
913
939
if (ST.getRealMinVLen () == ST.getRealMaxVLen () && VLMAX <= 31 )
914
940
InstrInfo.setAVLImm (VLMAX);
915
941
else
916
- InstrInfo.setAVLReg (RISCV::X0 );
942
+ InstrInfo.setAVLVLMAX ( );
917
943
}
918
944
else
919
945
InstrInfo.setAVLImm (Imm);
@@ -922,7 +948,10 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
922
948
}
923
949
} else {
924
950
assert (isScalarExtractInstr (MI));
925
- InstrInfo.setAVLReg (RISCV::NoRegister);
951
+ // TODO: If we are more clever about x0,x0 insertion then we should be able
952
+ // to deduce that the VL is ignored based off of DemandedFields, and remove
953
+ // the AVLIsIgnored state. Then we can just use an arbitrary immediate AVL.
954
+ InstrInfo.setAVLIgnored ();
926
955
}
927
956
#ifndef NDEBUG
928
957
if (std::optional<unsigned > EEW = getEEWForLoadStore (MI)) {
@@ -935,14 +964,14 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
935
964
// AVL operand with the AVL of the defining vsetvli. We avoid general
936
965
// register AVLs to avoid extending live ranges without being sure we can
937
966
// kill the original source reg entirely.
938
- if (InstrInfo.hasAVLReg () && InstrInfo.getAVLReg ().isVirtual ()) {
939
- MachineInstr *DefMI = MRI->getVRegDef (InstrInfo.getAVLReg ());
940
- if (DefMI && isVectorConfigInstr (*DefMI)) {
967
+ if (InstrInfo.hasAVLReg ()) {
968
+ MachineInstr *DefMI = MRI->getUniqueVRegDef (InstrInfo.getAVLReg ());
969
+ assert (DefMI);
970
+ if (isVectorConfigInstr (*DefMI)) {
941
971
VSETVLIInfo DefInstrInfo = getInfoForVSETVLI (*DefMI);
942
972
if (DefInstrInfo.hasSameVLMAX (InstrInfo) &&
943
- (DefInstrInfo.hasAVLImm () || DefInstrInfo.getAVLReg () == RISCV::X0)) {
973
+ (DefInstrInfo.hasAVLImm () || DefInstrInfo.hasAVLVLMAX ()))
944
974
InstrInfo.setAVL (DefInstrInfo);
945
- }
946
975
}
947
976
}
948
977
@@ -976,19 +1005,18 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
976
1005
// If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
977
1006
// it has the same VLMAX we want and the last VL/VTYPE we observed is the
978
1007
// same, we can use the X0, X0 form.
979
- if (Info.hasSameVLMAX (PrevInfo) && Info.hasAVLReg () &&
980
- Info.getAVLReg ().isVirtual ()) {
981
- if (MachineInstr *DefMI = MRI->getVRegDef (Info.getAVLReg ())) {
982
- if (isVectorConfigInstr (*DefMI)) {
983
- VSETVLIInfo DefInfo = getInfoForVSETVLI (*DefMI);
984
- if (DefInfo.hasSameAVL (PrevInfo) && DefInfo.hasSameVLMAX (PrevInfo)) {
985
- BuildMI (MBB, InsertPt, DL, TII->get (RISCV::PseudoVSETVLIX0))
986
- .addReg (RISCV::X0, RegState::Define | RegState::Dead)
987
- .addReg (RISCV::X0, RegState::Kill)
988
- .addImm (Info.encodeVTYPE ())
989
- .addReg (RISCV::VL, RegState::Implicit);
990
- return ;
991
- }
1008
+ if (Info.hasSameVLMAX (PrevInfo) && Info.hasAVLReg ()) {
1009
+ MachineInstr *DefMI = MRI->getUniqueVRegDef (Info.getAVLReg ());
1010
+ assert (DefMI);
1011
+ if (isVectorConfigInstr (*DefMI)) {
1012
+ VSETVLIInfo DefInfo = getInfoForVSETVLI (*DefMI);
1013
+ if (DefInfo.hasSameAVL (PrevInfo) && DefInfo.hasSameVLMAX (PrevInfo)) {
1014
+ BuildMI (MBB, InsertPt, DL, TII->get (RISCV::PseudoVSETVLIX0))
1015
+ .addReg (RISCV::X0, RegState::Define | RegState::Dead)
1016
+ .addReg (RISCV::X0, RegState::Kill)
1017
+ .addImm (Info.encodeVTYPE ())
1018
+ .addReg (RISCV::VL, RegState::Implicit);
1019
+ return ;
992
1020
}
993
1021
}
994
1022
}
@@ -1002,8 +1030,7 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1002
1030
return ;
1003
1031
}
1004
1032
1005
- Register AVLReg = Info.getAVLReg ();
1006
- if (AVLReg == RISCV::NoRegister) {
1033
+ if (Info.hasAVLIgnored ()) {
1007
1034
// We can only use x0, x0 if there's no chance of the vtype change causing
1008
1035
// the previous vl to become invalid.
1009
1036
if (PrevInfo.isValid () && !PrevInfo.isUnknown () &&
@@ -1023,20 +1050,19 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1023
1050
return ;
1024
1051
}
1025
1052
1026
- if (AVLReg.isVirtual ())
1027
- MRI->constrainRegClass (AVLReg, &RISCV::GPRNoX0RegClass);
1028
-
1029
- // Use X0 as the DestReg unless AVLReg is X0. We also need to change the
1030
- // opcode if the AVLReg is X0 as they have different register classes for
1031
- // the AVL operand.
1032
- Register DestReg = RISCV::X0;
1033
- unsigned Opcode = RISCV::PseudoVSETVLI;
1034
- if (AVLReg == RISCV::X0) {
1035
- DestReg = MRI->createVirtualRegister (&RISCV::GPRRegClass);
1036
- Opcode = RISCV::PseudoVSETVLIX0;
1053
+ if (Info.hasAVLVLMAX ()) {
1054
+ Register DestReg = MRI->createVirtualRegister (&RISCV::GPRRegClass);
1055
+ BuildMI (MBB, InsertPt, DL, TII->get (RISCV::PseudoVSETVLIX0))
1056
+ .addReg (DestReg, RegState::Define | RegState::Dead)
1057
+ .addReg (RISCV::X0, RegState::Kill)
1058
+ .addImm (Info.encodeVTYPE ());
1059
+ return ;
1037
1060
}
1038
- BuildMI (MBB, InsertPt, DL, TII->get (Opcode))
1039
- .addReg (DestReg, RegState::Define | RegState::Dead)
1061
+
1062
+ Register AVLReg = Info.getAVLReg ();
1063
+ MRI->constrainRegClass (AVLReg, &RISCV::GPRNoX0RegClass);
1064
+ BuildMI (MBB, InsertPt, DL, TII->get (RISCV::PseudoVSETVLI))
1065
+ .addReg (RISCV::X0, RegState::Define | RegState::Dead)
1040
1066
.addReg (AVLReg)
1041
1067
.addImm (Info.encodeVTYPE ());
1042
1068
}
@@ -1098,14 +1124,13 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
1098
1124
// it might be defined by a VSET(I)VLI. If it has the same VLMAX we need
1099
1125
// and the last VL/VTYPE we observed is the same, we don't need a
1100
1126
// VSETVLI here.
1101
- if (Require.hasAVLReg () && Require.getAVLReg ().isVirtual () &&
1102
- CurInfo.hasCompatibleVTYPE (Used, Require)) {
1103
- if (MachineInstr *DefMI = MRI->getVRegDef (Require.getAVLReg ())) {
1104
- if (isVectorConfigInstr (*DefMI)) {
1105
- VSETVLIInfo DefInfo = getInfoForVSETVLI (*DefMI);
1106
- if (DefInfo.hasSameAVL (CurInfo) && DefInfo.hasSameVLMAX (CurInfo))
1107
- return false ;
1108
- }
1127
+ if (Require.hasAVLReg () && CurInfo.hasCompatibleVTYPE (Used, Require)) {
1128
+ MachineInstr *DefMI = MRI->getUniqueVRegDef (Require.getAVLReg ());
1129
+ assert (DefMI);
1130
+ if (isVectorConfigInstr (*DefMI)) {
1131
+ VSETVLIInfo DefInfo = getInfoForVSETVLI (*DefMI);
1132
+ if (DefInfo.hasSameAVL (CurInfo) && DefInfo.hasSameVLMAX (CurInfo))
1133
+ return false ;
1109
1134
}
1110
1135
}
1111
1136
@@ -1290,12 +1315,11 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
1290
1315
return true ;
1291
1316
1292
1317
Register AVLReg = Require.getAVLReg ();
1293
- if (!AVLReg.isVirtual ())
1294
- return true ;
1295
1318
1296
1319
// We need the AVL to be produce by a PHI node in this basic block.
1297
- MachineInstr *PHI = MRI->getVRegDef (AVLReg);
1298
- if (!PHI || PHI->getOpcode () != RISCV::PHI || PHI->getParent () != &MBB)
1320
+ MachineInstr *PHI = MRI->getUniqueVRegDef (AVLReg);
1321
+ assert (PHI);
1322
+ if (PHI->getOpcode () != RISCV::PHI || PHI->getParent () != &MBB)
1299
1323
return true ;
1300
1324
1301
1325
for (unsigned PHIOp = 1 , NumOps = PHI->getNumOperands (); PHIOp != NumOps;
@@ -1463,10 +1487,9 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
1463
1487
// If the AVL value is a register (other than our VLMAX sentinel),
1464
1488
// we need to prove the value is available at the point we're going
1465
1489
// to insert the vsetvli at.
1466
- if (AvailableInfo.hasAVLReg () && RISCV::X0 != AvailableInfo.getAVLReg ()) {
1467
- MachineInstr *AVLDefMI = MRI->getVRegDef (AvailableInfo.getAVLReg ());
1468
- if (!AVLDefMI)
1469
- return ;
1490
+ if (AvailableInfo.hasAVLReg ()) {
1491
+ MachineInstr *AVLDefMI = MRI->getUniqueVRegDef (AvailableInfo.getAVLReg ());
1492
+ assert (AVLDefMI);
1470
1493
// This is an inline dominance check which covers the case of
1471
1494
// UnavailablePred being the preheader of a loop.
1472
1495
if (AVLDefMI->getParent () != UnavailablePred)
0 commit comments