@@ -1292,53 +1292,60 @@ std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(MachineInstr &MI) {
12921292 return CommonVL;
12931293}
12941294
1295- bool RISCVVLOptimizer::tryReduceVL (MachineInstr &OrigMI) {
1296- SetVector<MachineInstr *> Worklist;
1297- Worklist.insert (&OrigMI);
1295+ bool RISCVVLOptimizer::tryReduceVL (MachineInstr &MI) {
1296+ LLVM_DEBUG (dbgs () << " Trying to reduce VL for " << MI << " \n " );
12981297
1299- bool MadeChange = false ;
1300- while (!Worklist.empty ()) {
1301- MachineInstr &MI = *Worklist.pop_back_val ();
1302- LLVM_DEBUG (dbgs () << " Trying to reduce VL for " << MI << " \n " );
1298+ if (!isVectorRegClass (MI.getOperand (0 ).getReg (), MRI))
1299+ return false ;
13031300
1304- if (!isVectorRegClass (MI.getOperand (0 ).getReg (), MRI))
1305- continue ;
1301+ auto CommonVL = checkUsers (MI);
1302+ if (!CommonVL)
1303+ return false ;
13061304
1307- auto CommonVL = checkUsers (MI);
1308- if (!CommonVL)
1309- continue ;
1305+ assert ((CommonVL->isImm () || CommonVL->getReg ().isVirtual ()) &&
1306+ " Expected VL to be an Imm or virtual Reg" );
13101307
1311- assert ((CommonVL-> isImm () || CommonVL-> getReg (). isVirtual ()) &&
1312- " Expected VL to be an Imm or virtual Reg " );
1308+ unsigned VLOpNum = RISCVII::getVLOpNum (MI. getDesc ());
1309+ MachineOperand &VLOp = MI. getOperand (VLOpNum );
13131310
1314- unsigned VLOpNum = RISCVII::getVLOpNum (MI.getDesc ());
1315- MachineOperand &VLOp = MI.getOperand (VLOpNum);
1311+ if (!RISCV::isVLKnownLE (*CommonVL, VLOp)) {
1312+ LLVM_DEBUG (dbgs () << " Abort due to CommonVL not <= VLOp.\n " );
1313+ return false ;
1314+ }
13161315
1317- if (!RISCV::isVLKnownLE (*CommonVL, VLOp)) {
1318- LLVM_DEBUG (dbgs () << " Abort due to CommonVL not <= VLOp.\n " );
1319- continue ;
1320- }
1316+ if (CommonVL->isImm ()) {
1317+ LLVM_DEBUG (dbgs () << " Reduce VL from " << VLOp << " to "
1318+ << CommonVL->getImm () << " for " << MI << " \n " );
1319+ VLOp.ChangeToImmediate (CommonVL->getImm ());
1320+ return true ;
1321+ }
1322+ const MachineInstr *VLMI = MRI->getVRegDef (CommonVL->getReg ());
1323+ if (!MDT->dominates (VLMI, &MI))
1324+ return false ;
1325+ LLVM_DEBUG (
1326+ dbgs () << " Reduce VL from " << VLOp << " to "
1327+ << printReg (CommonVL->getReg (), MRI->getTargetRegisterInfo ())
1328+ << " for " << MI << " \n " );
13211329
1322- if (CommonVL->isImm ()) {
1323- LLVM_DEBUG (dbgs () << " Reduce VL from " << VLOp << " to "
1324- << CommonVL->getImm () << " for " << MI << " \n " );
1325- VLOp.ChangeToImmediate (CommonVL->getImm ());
1326- } else {
1327- const MachineInstr *VLMI = MRI->getVRegDef (CommonVL->getReg ());
1328- if (!MDT->dominates (VLMI, &MI))
1329- continue ;
1330- LLVM_DEBUG (
1331- dbgs () << " Reduce VL from " << VLOp << " to "
1332- << printReg (CommonVL->getReg (), MRI->getTargetRegisterInfo ())
1333- << " for " << MI << " \n " );
1330+ // All our checks passed. We can reduce VL.
1331+ VLOp.ChangeToRegister (CommonVL->getReg (), false );
1332+ return true ;
1333+ }
13341334
1335- // All our checks passed. We can reduce VL.
1336- VLOp.ChangeToRegister (CommonVL->getReg (), false );
1337- }
1335+ bool RISCVVLOptimizer::runOnMachineFunction (MachineFunction &MF) {
1336+ if (skipFunction (MF.getFunction ()))
1337+ return false ;
1338+
1339+ MRI = &MF.getRegInfo ();
1340+ MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree ();
13381341
1339- MadeChange = true ;
1342+ const RISCVSubtarget &ST = MF.getSubtarget <RISCVSubtarget>();
1343+ if (!ST.hasVInstructions ())
1344+ return false ;
13401345
1341- // Now add all inputs to this instruction to the worklist.
1346+ SetVector<MachineInstr *> Worklist;
1347+ auto PushOperands = [this , &Worklist](MachineInstr &MI,
1348+ bool IgnoreSameBlock) {
13421349 for (auto &Op : MI.operands ()) {
13431350 if (!Op.isReg () || !Op.isUse () || !Op.getReg ().isVirtual ())
13441351 continue ;
@@ -1351,34 +1358,40 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &OrigMI) {
13511358 if (!isCandidate (*DefMI))
13521359 continue ;
13531360
1361+ if (IgnoreSameBlock && DefMI->getParent () == MI.getParent ())
1362+ continue ;
1363+
13541364 Worklist.insert (DefMI);
13551365 }
1356- }
1357-
1358- return MadeChange;
1359- }
1360-
1361- bool RISCVVLOptimizer::runOnMachineFunction (MachineFunction &MF) {
1362- if (skipFunction (MF.getFunction ()))
1363- return false ;
1364-
1365- MRI = &MF.getRegInfo ();
1366- MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree ();
1367-
1368- const RISCVSubtarget &ST = MF.getSubtarget <RISCVSubtarget>();
1369- if (!ST.hasVInstructions ())
1370- return false ;
1366+ };
13711367
1368+ // Do a first pass eagerly rewriting in roughly reverse instruction
1369+ // order, populate the worklist with any instructions we might need to
1370+ // revisit. We avoid adding definitions to the worklist if they're
1371+ // in the same block - we're about to visit them anyways.
13721372 bool MadeChange = false ;
13731373 for (MachineBasicBlock &MBB : MF) {
1374- // Visit instructions in reverse order.
1374+ // Avoid unreachable blocks as they have degenerate dominance
1375+ if (!MDT->isReachableFromEntry (&MBB))
1376+ continue ;
1377+
13751378 for (auto &MI : make_range (MBB.rbegin (), MBB.rend ())) {
13761379 if (!isCandidate (MI))
13771380 continue ;
1378-
1379- MadeChange |= tryReduceVL (MI);
1381+ if (!tryReduceVL (MI))
1382+ continue ;
1383+ MadeChange = true ;
1384+ PushOperands (MI, /* IgnoreSameBlock*/ true );
13801385 }
13811386 }
13821387
1388+ while (!Worklist.empty ()) {
1389+ assert (MadeChange);
1390+ MachineInstr &MI = *Worklist.pop_back_val ();
1391+ if (!tryReduceVL (MI))
1392+ continue ;
1393+ PushOperands (MI, /* IgnoreSameBlock*/ false );
1394+ }
1395+
13831396 return MadeChange;
13841397}
0 commit comments