18
18
19
19
#include " RISCV.h"
20
20
#include " RISCVSubtarget.h"
21
- #include " llvm/ADT/SetVector .h"
21
+ #include " llvm/ADT/PostOrderIterator .h"
22
22
#include " llvm/CodeGen/MachineDominators.h"
23
23
#include " llvm/CodeGen/MachineFunctionPass.h"
24
24
#include " llvm/InitializePasses.h"
@@ -56,6 +56,10 @@ class RISCVVLOptimizer : public MachineFunctionPass {
56
56
std::optional<MachineOperand> checkUsers (MachineInstr &MI);
57
57
bool tryReduceVL (MachineInstr &MI);
58
58
bool isCandidate (const MachineInstr &MI) const ;
59
+
60
+ // / For a given instruction, records what elements of it are demanded by
61
+ // / downstream users.
62
+ DenseMap<const MachineInstr *, std::optional<MachineOperand>> DemandedVLs;
59
63
};
60
64
61
65
} // end anonymous namespace
@@ -1201,14 +1205,19 @@ RISCVVLOptimizer::getMinimumVLForUser(MachineOperand &UserOp) {
1201
1205
// Looking for an immediate or a register VL that isn't X0.
1202
1206
assert ((!VLOp.isReg () || VLOp.getReg () != RISCV::X0) &&
1203
1207
" Did not expect X0 VL" );
1208
+
1209
+ // If we know the demanded VL of UserMI, then we can reduce the VL it
1210
+ // requires.
1211
+ if (auto DemandedVL = DemandedVLs[&UserMI]) {
1212
+ assert (isCandidate (UserMI));
1213
+ if (RISCV::isVLKnownLE (*DemandedVL, VLOp))
1214
+ return DemandedVL;
1215
+ }
1216
+
1204
1217
return VLOp;
1205
1218
}
1206
1219
1207
1220
std::optional<MachineOperand> RISCVVLOptimizer::checkUsers (MachineInstr &MI) {
1208
- // FIXME: Avoid visiting each user for each time we visit something on the
1209
- // worklist, combined with an extra visit from the outer loop. Restructure
1210
- // along lines of an instcombine style worklist which integrates the outer
1211
- // pass.
1212
1221
std::optional<MachineOperand> CommonVL;
1213
1222
for (auto &UserOp : MRI->use_operands (MI.getOperand (0 ).getReg ())) {
1214
1223
const MachineInstr &UserMI = *UserOp.getParent ();
@@ -1285,7 +1294,7 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) {
1285
1294
return false ;
1286
1295
}
1287
1296
1288
- auto CommonVL = checkUsers (MI) ;
1297
+ auto CommonVL = DemandedVLs[&MI] ;
1289
1298
if (!CommonVL)
1290
1299
return false ;
1291
1300
@@ -1333,29 +1342,19 @@ bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1333
1342
if (!ST.hasVInstructions ())
1334
1343
return false ;
1335
1344
1336
- SetVector<MachineInstr *> Worklist;
1337
- auto PushOperands = [this , &Worklist](MachineInstr &MI,
1338
- bool IgnoreSameBlock) {
1339
- for (auto &Op : MI.operands ()) {
1340
- if (!Op.isReg () || !Op.isUse () || !Op.getReg ().isVirtual () ||
1341
- !isVectorRegClass (Op.getReg (), MRI))
1342
- continue ;
1343
-
1344
- MachineInstr *DefMI = MRI->getVRegDef (Op.getReg ());
1345
- if (!isCandidate (*DefMI))
1346
- continue ;
1347
-
1348
- if (IgnoreSameBlock && DefMI->getParent () == MI.getParent ())
1345
+ // For each instruction that defines a vector, compute what VL its
1346
+ // downstream users demand.
1347
+ for (MachineBasicBlock *MBB : post_order (&MF)) {
1348
+ assert (MDT->isReachableFromEntry (MBB));
1349
+ for (MachineInstr &MI : reverse (*MBB)) {
1350
+ if (!isCandidate (MI))
1349
1351
continue ;
1350
-
1351
- Worklist.insert (DefMI);
1352
+ DemandedVLs.insert ({&MI, checkUsers (MI)});
1352
1353
}
1353
- };
1354
+ }
1354
1355
1355
- // Do a first pass eagerly rewriting in roughly reverse instruction
1356
- // order, populate the worklist with any instructions we might need to
1357
- // revisit. We avoid adding definitions to the worklist if they're
1358
- // in the same block - we're about to visit them anyways.
1356
+ // Then go through and see if we can reduce the VL of any instructions to
1357
+ // only what's demanded.
1359
1358
bool MadeChange = false ;
1360
1359
for (MachineBasicBlock &MBB : MF) {
1361
1360
// Avoid unreachable blocks as they have degenerate dominance
@@ -1368,18 +1367,8 @@ bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1368
1367
if (!tryReduceVL (MI))
1369
1368
continue ;
1370
1369
MadeChange = true ;
1371
- PushOperands (MI, /* IgnoreSameBlock*/ true );
1372
1370
}
1373
1371
}
1374
1372
1375
- while (!Worklist.empty ()) {
1376
- assert (MadeChange);
1377
- MachineInstr &MI = *Worklist.pop_back_val ();
1378
- assert (isCandidate (MI));
1379
- if (!tryReduceVL (MI))
1380
- continue ;
1381
- PushOperands (MI, /* IgnoreSameBlock*/ false );
1382
- }
1383
-
1384
1373
return MadeChange;
1385
1374
}
0 commit comments