@@ -1292,53 +1292,60 @@ std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(MachineInstr &MI) {
1292
1292
return CommonVL;
1293
1293
}
1294
1294
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 " );
1298
1297
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 ;
1303
1300
1304
- if (!isVectorRegClass (MI.getOperand (0 ).getReg (), MRI))
1305
- continue ;
1301
+ auto CommonVL = checkUsers (MI);
1302
+ if (!CommonVL)
1303
+ return false ;
1306
1304
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" );
1310
1307
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 );
1313
1310
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
+ }
1316
1315
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 " );
1321
1329
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
+ }
1334
1334
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 ();
1338
1341
1339
- MadeChange = true ;
1342
+ const RISCVSubtarget &ST = MF.getSubtarget <RISCVSubtarget>();
1343
+ if (!ST.hasVInstructions ())
1344
+ return false ;
1340
1345
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) {
1342
1349
for (auto &Op : MI.operands ()) {
1343
1350
if (!Op.isReg () || !Op.isUse () || !Op.getReg ().isVirtual ())
1344
1351
continue ;
@@ -1351,34 +1358,40 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &OrigMI) {
1351
1358
if (!isCandidate (*DefMI))
1352
1359
continue ;
1353
1360
1361
+ if (IgnoreSameBlock && DefMI->getParent () == MI.getParent ())
1362
+ continue ;
1363
+
1354
1364
Worklist.insert (DefMI);
1355
1365
}
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
+ };
1371
1367
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.
1372
1372
bool MadeChange = false ;
1373
1373
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
+
1375
1378
for (auto &MI : make_range (MBB.rbegin (), MBB.rend ())) {
1376
1379
if (!isCandidate (MI))
1377
1380
continue ;
1378
-
1379
- MadeChange |= tryReduceVL (MI);
1381
+ if (!tryReduceVL (MI))
1382
+ continue ;
1383
+ MadeChange = true ;
1384
+ PushOperands (MI, /* IgnoreSameBlock*/ true );
1380
1385
}
1381
1386
}
1382
1387
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
+
1383
1396
return MadeChange;
1384
1397
}
0 commit comments