@@ -1289,45 +1289,59 @@ Operation *transform::TrackingListener::getCommonDefiningOp(ValueRange values) {
1289
1289
return defOp;
1290
1290
}
1291
1291
1292
- FailureOr<Operation *>
1293
- transform::TrackingListener::findReplacementOp (Operation *op,
1294
- ValueRange newValues) const {
1292
+ DiagnosedSilenceableFailure transform::TrackingListener::findReplacementOp (
1293
+ Operation *&result, Operation *op, ValueRange newValues) const {
1295
1294
assert (op->getNumResults () == newValues.size () &&
1296
1295
" invalid number of replacement values" );
1297
1296
SmallVector<Value> values (newValues.begin (), newValues.end ());
1298
1297
1298
+ DiagnosedSilenceableFailure diag = emitSilenceableFailure (
1299
+ getTransformOp (), " tracking listener failed to find replacement op "
1300
+ " during application of this transform op" );
1301
+
1299
1302
do {
1300
1303
// If the replacement values belong to different ops, drop the mapping.
1301
1304
Operation *defOp = getCommonDefiningOp (values);
1302
- if (!defOp)
1303
- return failure ();
1305
+ if (!defOp) {
1306
+ diag.attachNote () << " replacement values belong to different ops" ;
1307
+ return diag;
1308
+ }
1304
1309
1305
1310
// If the defining op has the same type, we take it as a replacement.
1306
- if (op->getName () == defOp->getName ())
1307
- return defOp;
1311
+ if (op->getName () == defOp->getName ()) {
1312
+ result = defOp;
1313
+ return DiagnosedSilenceableFailure::success ();
1314
+ }
1308
1315
1309
1316
// Replacing an op with a constant-like equivalent is a common
1310
1317
// canonicalization.
1311
- if (defOp->hasTrait <OpTrait::ConstantLike>())
1312
- return defOp;
1318
+ if (defOp->hasTrait <OpTrait::ConstantLike>()) {
1319
+ result = defOp;
1320
+ return DiagnosedSilenceableFailure::success ();
1321
+ }
1313
1322
1314
1323
values.clear ();
1315
1324
1316
1325
// Skip through ops that implement FindPayloadReplacementOpInterface.
1317
1326
if (auto findReplacementOpInterface =
1318
1327
dyn_cast<FindPayloadReplacementOpInterface>(defOp)) {
1319
1328
values.assign (findReplacementOpInterface.getNextOperands ());
1329
+ diag.attachNote (defOp->getLoc ()) << " using operands provided by "
1330
+ " 'FindPayloadReplacementOpInterface'" ;
1320
1331
continue ;
1321
1332
}
1322
1333
1323
1334
// Skip through ops that implement CastOpInterface.
1324
1335
if (isa<CastOpInterface>(defOp)) {
1325
1336
values.assign (defOp->getOperands ().begin (), defOp->getOperands ().end ());
1337
+ diag.attachNote (defOp->getLoc ())
1338
+ << " using output of 'CastOpInterface' op" ;
1326
1339
continue ;
1327
1340
}
1328
1341
} while (!values.empty ());
1329
1342
1330
- return failure ();
1343
+ diag.attachNote () << " ran out of suitable replacement values" ;
1344
+ return diag;
1331
1345
}
1332
1346
1333
1347
LogicalResult transform::TrackingListener::notifyMatchFailure (
@@ -1396,32 +1410,39 @@ void transform::TrackingListener::notifyOperationReplaced(
1396
1410
};
1397
1411
1398
1412
// Helper function to check if the handle is alive.
1399
- auto hasAliveUser = [&]() {
1413
+ auto firstAliveUser = [&]() -> std::optional<OpOperand *> {
1400
1414
for (Value v : opHandles) {
1401
- for (Operation *user : v.getUsers ())
1402
- if (user != transformOp && !happensBefore (user, transformOp))
1403
- return true ;
1415
+ for (OpOperand &use : v.getUses ())
1416
+ if (use.getOwner () != transformOp &&
1417
+ !happensBefore (use.getOwner (), transformOp))
1418
+ return &use;
1404
1419
}
1405
- return false ;
1406
- };
1420
+ return std::nullopt ;
1421
+ }() ;
1407
1422
1408
- if (!hasAliveUser () || handleWasConsumed ()) {
1423
+ if (!firstAliveUser. has_value () || handleWasConsumed ()) {
1409
1424
// The op is tracked but the corresponding handles are dead or were
1410
1425
// consumed. Drop the op form the mapping.
1411
1426
(void )replacePayloadOp (op, nullptr );
1412
1427
return ;
1413
1428
}
1414
1429
1415
- FailureOr<Operation *> replacement = findReplacementOp (op, newValues);
1430
+ Operation *replacement;
1431
+ DiagnosedSilenceableFailure diag =
1432
+ findReplacementOp (replacement, op, newValues);
1416
1433
// If the op is tracked but no replacement op was found, send a
1417
1434
// notification.
1418
- if (failed (replacement)) {
1419
- notifyPayloadReplacementNotFound (op, newValues);
1435
+ if (!diag.succeeded ()) {
1436
+ diag.attachNote ((*firstAliveUser)->getOwner ()->getLoc ())
1437
+ << " replacement is required because alive handle(s) exist "
1438
+ << " (first use in this op as operand number "
1439
+ << (*firstAliveUser)->getOperandNumber () << " )" ;
1440
+ notifyPayloadReplacementNotFound (op, newValues, std::move (diag));
1420
1441
(void )replacePayloadOp (op, nullptr );
1421
1442
return ;
1422
1443
}
1423
1444
1424
- (void )replacePayloadOp (op, * replacement);
1445
+ (void )replacePayloadOp (op, replacement);
1425
1446
}
1426
1447
1427
1448
transform::ErrorCheckingTrackingListener::~ErrorCheckingTrackingListener () {
@@ -1444,17 +1465,20 @@ bool transform::ErrorCheckingTrackingListener::failed() const {
1444
1465
}
1445
1466
1446
1467
void transform::ErrorCheckingTrackingListener::notifyPayloadReplacementNotFound (
1447
- Operation *op, ValueRange values) {
1448
- if (status.succeeded ()) {
1449
- status = emitSilenceableFailure (
1450
- getTransformOp (), " tracking listener failed to find replacement op" );
1451
- }
1468
+ Operation *op, ValueRange values, DiagnosedSilenceableFailure &&diag) {
1469
+
1470
+ // Merge potentially existing diags and store the result in the listener.
1471
+ SmallVector<Diagnostic> diags;
1472
+ diag.takeDiagnostics (diags);
1473
+ if (!status.succeeded ())
1474
+ status.takeDiagnostics (diags);
1475
+ status = DiagnosedSilenceableFailure::silenceableFailure (std::move (diags));
1452
1476
1477
+ // Report more details.
1453
1478
status.attachNote (op->getLoc ()) << " [" << errorCounter << " ] replaced op" ;
1454
1479
for (auto &&[index , value] : llvm::enumerate (values))
1455
1480
status.attachNote (value.getLoc ())
1456
1481
<< " [" << errorCounter << " ] replacement value " << index ;
1457
-
1458
1482
++errorCounter;
1459
1483
}
1460
1484
0 commit comments