@@ -53,16 +53,6 @@ static void logFailure(llvm::ScopedPrinter &os, StringRef fmt, Args &&...args) {
53
53
});
54
54
}
55
55
56
- // / Helper function that computes an insertion point where the given value is
57
- // / defined and can be used without a dominance violation.
58
- static OpBuilder::InsertPoint computeInsertPoint (Value value) {
59
- Block *insertBlock = value.getParentBlock ();
60
- Block::iterator insertPt = insertBlock->begin ();
61
- if (OpResult inputRes = dyn_cast<OpResult>(value))
62
- insertPt = ++inputRes.getOwner ()->getIterator ();
63
- return OpBuilder::InsertPoint (insertBlock, insertPt);
64
- }
65
-
66
56
// ===----------------------------------------------------------------------===//
67
57
// ConversionValueMapping
68
58
// ===----------------------------------------------------------------------===//
@@ -455,9 +445,11 @@ class BlockTypeConversionRewrite : public BlockRewrite {
455
445
return rewrite->getKind () == Kind::BlockTypeConversion;
456
446
}
457
447
458
- Block *getOrigBlock () const { return origBlock; }
459
-
460
- const TypeConverter *getConverter () const { return converter; }
448
+ // / Materialize any necessary conversions for converted arguments that have
449
+ // / live users, using the provided `findLiveUser` to search for a user that
450
+ // / survives the conversion process.
451
+ LogicalResult
452
+ materializeLiveConversions (function_ref<Operation *(Value)> findLiveUser);
461
453
462
454
void commit (RewriterBase &rewriter) override ;
463
455
@@ -849,10 +841,14 @@ struct ConversionPatternRewriterImpl : public RewriterBase::Listener {
849
841
// / Build an unresolved materialization operation given an output type and set
850
842
// / of input operands.
851
843
Value buildUnresolvedMaterialization (MaterializationKind kind,
852
- OpBuilder::InsertPoint ip, Location loc,
844
+ Block *insertBlock,
845
+ Block::iterator insertPt, Location loc,
853
846
ValueRange inputs, Type outputType,
854
847
Type origOutputType,
855
848
const TypeConverter *converter);
849
+ Value buildUnresolvedTargetMaterialization (Location loc, Value input,
850
+ Type outputType,
851
+ const TypeConverter *converter);
856
852
857
853
// ===--------------------------------------------------------------------===//
858
854
// Rewriter Notification Hooks
@@ -985,6 +981,49 @@ void BlockTypeConversionRewrite::rollback() {
985
981
block->replaceAllUsesWith (origBlock);
986
982
}
987
983
984
+ LogicalResult BlockTypeConversionRewrite::materializeLiveConversions (
985
+ function_ref<Operation *(Value)> findLiveUser) {
986
+ // Process the remapping for each of the original arguments.
987
+ for (auto it : llvm::enumerate (origBlock->getArguments ())) {
988
+ BlockArgument origArg = it.value ();
989
+ // Note: `block` may be detached, so OpBuilder::atBlockBegin cannot be used.
990
+ OpBuilder builder (it.value ().getContext (), /* listener=*/ &rewriterImpl);
991
+ builder.setInsertionPointToStart (block);
992
+
993
+ // If the type of this argument changed and the argument is still live, we
994
+ // need to materialize a conversion.
995
+ if (rewriterImpl.mapping .lookupOrNull (origArg, origArg.getType ()))
996
+ continue ;
997
+ Operation *liveUser = findLiveUser (origArg);
998
+ if (!liveUser)
999
+ continue ;
1000
+
1001
+ Value replacementValue = rewriterImpl.mapping .lookupOrNull (origArg);
1002
+ assert (replacementValue && " replacement value not found" );
1003
+ Value newArg;
1004
+ if (converter) {
1005
+ builder.setInsertionPointAfterValue (replacementValue);
1006
+ newArg = converter->materializeSourceConversion (
1007
+ builder, origArg.getLoc (), origArg.getType (), replacementValue);
1008
+ assert ((!newArg || newArg.getType () == origArg.getType ()) &&
1009
+ " materialization hook did not provide a value of the expected "
1010
+ " type" );
1011
+ }
1012
+ if (!newArg) {
1013
+ InFlightDiagnostic diag =
1014
+ emitError (origArg.getLoc ())
1015
+ << " failed to materialize conversion for block argument #"
1016
+ << it.index () << " that remained live after conversion, type was "
1017
+ << origArg.getType ();
1018
+ diag.attachNote (liveUser->getLoc ())
1019
+ << " see existing live user here: " << *liveUser;
1020
+ return failure ();
1021
+ }
1022
+ rewriterImpl.mapping .map (origArg, newArg);
1023
+ }
1024
+ return success ();
1025
+ }
1026
+
988
1027
void ReplaceBlockArgRewrite::commit (RewriterBase &rewriter) {
989
1028
Value repl = rewriterImpl.mapping .lookupOrNull (arg, arg.getType ());
990
1029
if (!repl)
@@ -1157,10 +1196,8 @@ LogicalResult ConversionPatternRewriterImpl::remapValues(
1157
1196
Type newOperandType = newOperand.getType ();
1158
1197
if (currentTypeConverter && desiredType && newOperandType != desiredType) {
1159
1198
Location operandLoc = inputLoc ? *inputLoc : operand.getLoc ();
1160
- Value castValue = buildUnresolvedMaterialization (
1161
- MaterializationKind::Target, computeInsertPoint (newOperand),
1162
- operandLoc, /* inputs=*/ newOperand, /* outputType=*/ desiredType,
1163
- /* origArgType=*/ {}, currentTypeConverter);
1199
+ Value castValue = buildUnresolvedTargetMaterialization (
1200
+ operandLoc, newOperand, desiredType, currentTypeConverter);
1164
1201
mapping.map (mapping.lookupOrDefault (newOperand), castValue);
1165
1202
newOperand = castValue;
1166
1203
}
@@ -1288,9 +1325,8 @@ Block *ConversionPatternRewriterImpl::applySignatureConversion(
1288
1325
// This block argument was dropped and no replacement value was provided.
1289
1326
// Materialize a replacement value "out of thin air".
1290
1327
Value repl = buildUnresolvedMaterialization (
1291
- MaterializationKind::Source,
1292
- OpBuilder::InsertPoint (newBlock, newBlock->begin ()), origArg.getLoc (),
1293
- /* inputs=*/ ValueRange (),
1328
+ MaterializationKind::Source, newBlock, newBlock->begin (),
1329
+ origArg.getLoc (), /* inputs=*/ ValueRange (),
1294
1330
/* outputType=*/ origArgType, /* origArgType=*/ {}, converter);
1295
1331
mapping.map (origArg, repl);
1296
1332
appendRewrite<ReplaceBlockArgRewrite>(block, origArg);
@@ -1315,9 +1351,8 @@ Block *ConversionPatternRewriterImpl::applySignatureConversion(
1315
1351
auto replArgs =
1316
1352
newBlock->getArguments ().slice (inputMap->inputNo , inputMap->size );
1317
1353
Value repl = buildUnresolvedMaterialization (
1318
- MaterializationKind::Argument,
1319
- OpBuilder::InsertPoint (newBlock, newBlock->begin ()), origArg.getLoc (),
1320
- /* inputs=*/ replArgs,
1354
+ MaterializationKind::Argument, newBlock, newBlock->begin (),
1355
+ origArg.getLoc (), /* inputs=*/ replArgs,
1321
1356
/* outputType=*/ tryLegalizeType (origArgType), origArgType, converter);
1322
1357
mapping.map (origArg, repl);
1323
1358
appendRewrite<ReplaceBlockArgRewrite>(block, origArg);
@@ -1339,22 +1374,34 @@ Block *ConversionPatternRewriterImpl::applySignatureConversion(
1339
1374
// / Build an unresolved materialization operation given an output type and set
1340
1375
// / of input operands.
1341
1376
Value ConversionPatternRewriterImpl::buildUnresolvedMaterialization (
1342
- MaterializationKind kind, OpBuilder::InsertPoint ip, Location loc ,
1343
- ValueRange inputs, Type outputType, Type origArgType,
1377
+ MaterializationKind kind, Block *insertBlock, Block::iterator insertPt ,
1378
+ Location loc, ValueRange inputs, Type outputType, Type origArgType,
1344
1379
const TypeConverter *converter) {
1345
1380
// Avoid materializing an unnecessary cast.
1346
1381
if (inputs.size () == 1 && inputs.front ().getType () == outputType)
1347
1382
return inputs.front ();
1348
1383
1349
1384
// Create an unresolved materialization. We use a new OpBuilder to avoid
1350
1385
// tracking the materialization like we do for other operations.
1351
- OpBuilder builder (ip. getBlock (), ip. getPoint () );
1386
+ OpBuilder builder (insertBlock, insertPt );
1352
1387
auto convertOp =
1353
1388
builder.create <UnrealizedConversionCastOp>(loc, outputType, inputs);
1354
1389
appendRewrite<UnresolvedMaterializationRewrite>(convertOp, converter, kind,
1355
1390
origArgType);
1356
1391
return convertOp.getResult (0 );
1357
1392
}
1393
+ Value ConversionPatternRewriterImpl::buildUnresolvedTargetMaterialization (
1394
+ Location loc, Value input, Type outputType,
1395
+ const TypeConverter *converter) {
1396
+ Block *insertBlock = input.getParentBlock ();
1397
+ Block::iterator insertPt = insertBlock->begin ();
1398
+ if (OpResult inputRes = dyn_cast<OpResult>(input))
1399
+ insertPt = ++inputRes.getOwner ()->getIterator ();
1400
+
1401
+ return buildUnresolvedMaterialization (
1402
+ MaterializationKind::Target, insertBlock, insertPt, loc, input,
1403
+ outputType, /* origArgType=*/ {}, converter);
1404
+ }
1358
1405
1359
1406
// ===----------------------------------------------------------------------===//
1360
1407
// Rewriter Notification Hooks
@@ -2468,9 +2515,9 @@ LogicalResult
2468
2515
OperationConverter::finalize (ConversionPatternRewriter &rewriter) {
2469
2516
std::optional<DenseMap<Value, SmallVector<Value>>> inverseMapping;
2470
2517
ConversionPatternRewriterImpl &rewriterImpl = rewriter.getImpl ();
2471
- if (failed (legalizeConvertedArgumentTypes (rewriter, rewriterImpl)) ||
2472
- failed ( legalizeUnresolvedMaterializations (rewriter, rewriterImpl,
2473
- inverseMapping )))
2518
+ if (failed (legalizeUnresolvedMaterializations (rewriter, rewriterImpl,
2519
+ inverseMapping)) ||
2520
+ failed ( legalizeConvertedArgumentTypes (rewriter, rewriterImpl )))
2474
2521
return failure ();
2475
2522
2476
2523
// Process requested operation replacements.
@@ -2526,28 +2573,10 @@ LogicalResult OperationConverter::legalizeConvertedArgumentTypes(
2526
2573
++i) {
2527
2574
auto &rewrite = rewriterImpl.rewrites [i];
2528
2575
if (auto *blockTypeConversionRewrite =
2529
- dyn_cast<BlockTypeConversionRewrite>(rewrite.get ())) {
2530
- // Process the remapping for each of the original arguments.
2531
- for (Value origArg :
2532
- blockTypeConversionRewrite->getOrigBlock ()->getArguments ()) {
2533
- // If the type of this argument changed and the argument is still live,
2534
- // we need to materialize a conversion.
2535
- if (rewriterImpl.mapping .lookupOrNull (origArg, origArg.getType ()))
2536
- continue ;
2537
- Operation *liveUser = findLiveUser (origArg);
2538
- if (!liveUser)
2539
- continue ;
2540
-
2541
- Value replacementValue = rewriterImpl.mapping .lookupOrNull (origArg);
2542
- assert (replacementValue && " replacement value not found" );
2543
- Value repl = rewriterImpl.buildUnresolvedMaterialization (
2544
- MaterializationKind::Source, computeInsertPoint (replacementValue),
2545
- origArg.getLoc (), /* inputs=*/ replacementValue,
2546
- /* outputType=*/ origArg.getType (), /* origArgType=*/ {},
2547
- blockTypeConversionRewrite->getConverter ());
2548
- rewriterImpl.mapping .map (origArg, repl);
2549
- }
2550
- }
2576
+ dyn_cast<BlockTypeConversionRewrite>(rewrite.get ()))
2577
+ if (failed (blockTypeConversionRewrite->materializeLiveConversions (
2578
+ findLiveUser)))
2579
+ return failure ();
2551
2580
}
2552
2581
return success ();
2553
2582
}
0 commit comments