@@ -1300,18 +1300,7 @@ void VPValue::replaceUsesWithIf(
1300
1300
1301
1301
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1302
1302
void VPValue::printAsOperand (raw_ostream &OS, VPSlotTracker &Tracker) const {
1303
- if (const Value *UV = getUnderlyingValue ()) {
1304
- OS << " ir<" ;
1305
- UV->printAsOperand (OS, false );
1306
- OS << " >" ;
1307
- return ;
1308
- }
1309
-
1310
- unsigned Slot = Tracker.getSlot (this );
1311
- if (Slot == unsigned (-1 ))
1312
- OS << " <badref>" ;
1313
- else
1314
- OS << " vp<%" << Tracker.getSlot (this ) << " >" ;
1303
+ OS << Tracker.getOrCreateName (this );
1315
1304
}
1316
1305
1317
1306
void VPUser::printOperands (raw_ostream &O, VPSlotTracker &SlotTracker) const {
@@ -1373,32 +1362,88 @@ VPInterleavedAccessInfo::VPInterleavedAccessInfo(VPlan &Plan,
1373
1362
visitRegion (Plan.getVectorLoopRegion (), Old2New, IAI);
1374
1363
}
1375
1364
1376
- void VPSlotTracker::assignSlot (const VPValue *V) {
1377
- if (V->getUnderlyingValue ())
1365
+ void VPSlotTracker::assignName (const VPValue *V) {
1366
+ assert (!VPValue2Name.contains (V) && " VPValue already has a name!" );
1367
+ auto *UV = V->getUnderlyingValue ();
1368
+ if (!UV) {
1369
+ VPValue2Name[V] = (Twine (" vp<%" ) + Twine (NextSlot) + " >" ).str ();
1370
+ NextSlot++;
1378
1371
return ;
1379
- assert (!Slots.contains (V) && " VPValue already has a slot!" );
1380
- Slots[V] = NextSlot++;
1372
+ }
1373
+
1374
+ // Use the name of the underlying Value, wrapped in "ir<>", and versioned by
1375
+ // appending ".Number" to the name if there are multiple uses.
1376
+ std::string Name;
1377
+ raw_string_ostream S (Name);
1378
+ UV->printAsOperand (S, false );
1379
+ assert (!Name.empty () && " Name cannot be empty." );
1380
+ std::string BaseName = (Twine (" ir<" ) + Name + Twine (" >" )).str ();
1381
+
1382
+ // First assign the base name for V.
1383
+ const auto &[A, _] = VPValue2Name.insert ({V, BaseName});
1384
+ // Integer or FP constants with different types will result in he same string
1385
+ // due to stripping types.
1386
+ if (V->isLiveIn () && isa<ConstantInt, ConstantFP>(UV))
1387
+ return ;
1388
+
1389
+ // If it is already used by C > 0 other VPValues, increase the version counter
1390
+ // C and use it for V.
1391
+ const auto &[C, UseInserted] = BaseName2Version.insert ({BaseName, 0 });
1392
+ if (!UseInserted) {
1393
+ C->second ++;
1394
+ A->second = (BaseName + Twine (" ." ) + Twine (C->second )).str ();
1395
+ }
1381
1396
}
1382
1397
1383
- void VPSlotTracker::assignSlots (const VPlan &Plan) {
1398
+ void VPSlotTracker::assignNames (const VPlan &Plan) {
1384
1399
if (Plan.VFxUF .getNumUsers () > 0 )
1385
- assignSlot (&Plan.VFxUF );
1386
- assignSlot (&Plan.VectorTripCount );
1400
+ assignName (&Plan.VFxUF );
1401
+ assignName (&Plan.VectorTripCount );
1387
1402
if (Plan.BackedgeTakenCount )
1388
- assignSlot (Plan.BackedgeTakenCount );
1389
- assignSlots (Plan.getPreheader ());
1403
+ assignName (Plan.BackedgeTakenCount );
1404
+ for (VPValue *LI : Plan.VPLiveInsToFree )
1405
+ assignName (LI);
1406
+ assignNames (Plan.getPreheader ());
1390
1407
1391
1408
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1392
1409
RPOT (VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.getEntry ()));
1393
1410
for (const VPBasicBlock *VPBB :
1394
1411
VPBlockUtils::blocksOnly<const VPBasicBlock>(RPOT))
1395
- assignSlots (VPBB);
1412
+ assignNames (VPBB);
1396
1413
}
1397
1414
1398
- void VPSlotTracker::assignSlots (const VPBasicBlock *VPBB) {
1415
+ void VPSlotTracker::assignNames (const VPBasicBlock *VPBB) {
1399
1416
for (const VPRecipeBase &Recipe : *VPBB)
1400
1417
for (VPValue *Def : Recipe.definedValues ())
1401
- assignSlot (Def);
1418
+ assignName (Def);
1419
+ }
1420
+
1421
+ std::string VPSlotTracker::getOrCreateName (const VPValue *V) const {
1422
+ std::string Name = VPValue2Name.lookup (V);
1423
+ if (!Name.empty ())
1424
+ return Name;
1425
+
1426
+ // If no name was assigned, no VPlan was provided when creating the slot
1427
+ // tracker or it is not reachable from the provided VPlan. This can happen,
1428
+ // e.g. when trying to print a recipe that has not been inserted into a VPlan
1429
+ // in a debugger.
1430
+ // TODO: Update VPSlotTracker constructor to assign names to recipes &
1431
+ // VPValues not associated with a VPlan, instead of constructing names ad-hoc
1432
+ // here.
1433
+ const VPRecipeBase *DefR = V->getDefiningRecipe ();
1434
+ (void )DefR;
1435
+ assert ((!DefR || !DefR->getParent () || !DefR->getParent ()->getPlan ()) &&
1436
+ " VPValue defined by a recipe in a VPlan?" );
1437
+
1438
+ // Use the underlying value's name, if there is one.
1439
+ if (auto *UV = V->getUnderlyingValue ()) {
1440
+ std::string Name;
1441
+ raw_string_ostream S (Name);
1442
+ UV->printAsOperand (S, false );
1443
+ return (Twine (" ir<" ) + Name + " >" ).str ();
1444
+ }
1445
+
1446
+ return " <badref>" ;
1402
1447
}
1403
1448
1404
1449
bool vputils::onlyFirstLaneUsed (const VPValue *Def) {
0 commit comments