@@ -2348,6 +2348,12 @@ struct OperationConverter {
2348
2348
legalizeConvertedArgumentTypes (ConversionPatternRewriter &rewriter,
2349
2349
ConversionPatternRewriterImpl &rewriterImpl);
2350
2350
2351
+ // / Legalize the types of converted op results.
2352
+ LogicalResult legalizeConvertedOpResultTypes (
2353
+ ConversionPatternRewriter &rewriter,
2354
+ ConversionPatternRewriterImpl &rewriterImpl,
2355
+ DenseMap<Value, SmallVector<Value>> &inverseMapping);
2356
+
2351
2357
// / Legalize any unresolved type materializations.
2352
2358
LogicalResult legalizeUnresolvedMaterializations (
2353
2359
ConversionPatternRewriter &rewriter,
@@ -2359,14 +2365,6 @@ struct OperationConverter {
2359
2365
legalizeErasedResult (Operation *op, OpResult result,
2360
2366
ConversionPatternRewriterImpl &rewriterImpl);
2361
2367
2362
- // / Legalize an operation result that was replaced with a value of a different
2363
- // / type.
2364
- LogicalResult legalizeChangedResultType (
2365
- Operation *op, OpResult result, Value newValue,
2366
- const TypeConverter *replConverter, ConversionPatternRewriter &rewriter,
2367
- ConversionPatternRewriterImpl &rewriterImpl,
2368
- const DenseMap<Value, SmallVector<Value>> &inverseMapping);
2369
-
2370
2368
// / Dialect conversion configuration.
2371
2369
ConversionConfig config;
2372
2370
@@ -2459,10 +2457,42 @@ OperationConverter::finalize(ConversionPatternRewriter &rewriter) {
2459
2457
return failure ();
2460
2458
DenseMap<Value, SmallVector<Value>> inverseMapping =
2461
2459
rewriterImpl.mapping .getInverse ();
2460
+ if (failed (legalizeConvertedOpResultTypes (rewriter, rewriterImpl,
2461
+ inverseMapping)))
2462
+ return failure ();
2462
2463
if (failed (legalizeUnresolvedMaterializations (rewriter, rewriterImpl,
2463
2464
inverseMapping)))
2464
2465
return failure ();
2466
+ return success ();
2467
+ }
2465
2468
2469
+ // / Finds a user of the given value, or of any other value that the given value
2470
+ // / replaced, that was not replaced in the conversion process.
2471
+ static Operation *findLiveUserOfReplaced (
2472
+ Value initialValue, ConversionPatternRewriterImpl &rewriterImpl,
2473
+ const DenseMap<Value, SmallVector<Value>> &inverseMapping) {
2474
+ SmallVector<Value> worklist (1 , initialValue);
2475
+ while (!worklist.empty ()) {
2476
+ Value value = worklist.pop_back_val ();
2477
+
2478
+ // Walk the users of this value to see if there are any live users that
2479
+ // weren't replaced during conversion.
2480
+ auto liveUserIt = llvm::find_if_not (value.getUsers (), [&](Operation *user) {
2481
+ return rewriterImpl.isOpIgnored (user);
2482
+ });
2483
+ if (liveUserIt != value.user_end ())
2484
+ return *liveUserIt;
2485
+ auto mapIt = inverseMapping.find (value);
2486
+ if (mapIt != inverseMapping.end ())
2487
+ worklist.append (mapIt->second );
2488
+ }
2489
+ return nullptr ;
2490
+ }
2491
+
2492
+ LogicalResult OperationConverter::legalizeConvertedOpResultTypes (
2493
+ ConversionPatternRewriter &rewriter,
2494
+ ConversionPatternRewriterImpl &rewriterImpl,
2495
+ DenseMap<Value, SmallVector<Value>> &inverseMapping) {
2466
2496
// Process requested operation replacements.
2467
2497
for (unsigned i = 0 ; i < rewriterImpl.rewrites .size (); ++i) {
2468
2498
auto *opReplacement =
@@ -2485,14 +2515,21 @@ OperationConverter::finalize(ConversionPatternRewriter &rewriter) {
2485
2515
if (result.getType () == newValue.getType ())
2486
2516
continue ;
2487
2517
2518
+ Operation *liveUser =
2519
+ findLiveUserOfReplaced (result, rewriterImpl, inverseMapping);
2520
+ if (!liveUser)
2521
+ continue ;
2522
+
2488
2523
// Legalize this result.
2489
- rewriter.setInsertionPoint (op);
2490
- if (failed (legalizeChangedResultType (
2491
- op, result, newValue, opReplacement->getConverter (), rewriter,
2492
- rewriterImpl, inverseMapping)))
2493
- return failure ();
2524
+ Value castValue = rewriterImpl.buildUnresolvedMaterialization (
2525
+ MaterializationKind::Source, computeInsertPoint (result), op->getLoc (),
2526
+ /* inputs=*/ newValue, /* outputType=*/ result.getType (),
2527
+ opReplacement->getConverter ());
2528
+ rewriterImpl.mapping .map (result, castValue);
2529
+ inverseMapping[castValue].push_back (result);
2494
2530
}
2495
2531
}
2532
+
2496
2533
return success ();
2497
2534
}
2498
2535
@@ -2502,7 +2539,7 @@ LogicalResult OperationConverter::legalizeConvertedArgumentTypes(
2502
2539
// Functor used to check if all users of a value will be dead after
2503
2540
// conversion.
2504
2541
// TODO: This should probably query the inverse mapping, same as in
2505
- // `legalizeChangedResultType `.
2542
+ // `legalizeConvertedOpResultTypes `.
2506
2543
auto findLiveUser = [&](Value val) {
2507
2544
auto liveUserIt = llvm::find_if_not (val.getUsers (), [&](Operation *user) {
2508
2545
return rewriterImpl.isOpIgnored (user);
@@ -2832,67 +2869,6 @@ LogicalResult OperationConverter::legalizeErasedResult(
2832
2869
return success ();
2833
2870
}
2834
2871
2835
- // / Finds a user of the given value, or of any other value that the given value
2836
- // / replaced, that was not replaced in the conversion process.
2837
- static Operation *findLiveUserOfReplaced (
2838
- Value initialValue, ConversionPatternRewriterImpl &rewriterImpl,
2839
- const DenseMap<Value, SmallVector<Value>> &inverseMapping) {
2840
- SmallVector<Value> worklist (1 , initialValue);
2841
- while (!worklist.empty ()) {
2842
- Value value = worklist.pop_back_val ();
2843
-
2844
- // Walk the users of this value to see if there are any live users that
2845
- // weren't replaced during conversion.
2846
- auto liveUserIt = llvm::find_if_not (value.getUsers (), [&](Operation *user) {
2847
- return rewriterImpl.isOpIgnored (user);
2848
- });
2849
- if (liveUserIt != value.user_end ())
2850
- return *liveUserIt;
2851
- auto mapIt = inverseMapping.find (value);
2852
- if (mapIt != inverseMapping.end ())
2853
- worklist.append (mapIt->second );
2854
- }
2855
- return nullptr ;
2856
- }
2857
-
2858
- LogicalResult OperationConverter::legalizeChangedResultType (
2859
- Operation *op, OpResult result, Value newValue,
2860
- const TypeConverter *replConverter, ConversionPatternRewriter &rewriter,
2861
- ConversionPatternRewriterImpl &rewriterImpl,
2862
- const DenseMap<Value, SmallVector<Value>> &inverseMapping) {
2863
- Operation *liveUser =
2864
- findLiveUserOfReplaced (result, rewriterImpl, inverseMapping);
2865
- if (!liveUser)
2866
- return success ();
2867
-
2868
- // Functor used to emit a conversion error for a failed materialization.
2869
- auto emitConversionError = [&] {
2870
- InFlightDiagnostic diag = op->emitError ()
2871
- << " failed to materialize conversion for result #"
2872
- << result.getResultNumber () << " of operation '"
2873
- << op->getName ()
2874
- << " ' that remained live after conversion" ;
2875
- diag.attachNote (liveUser->getLoc ())
2876
- << " see existing live user here: " << *liveUser;
2877
- return failure ();
2878
- };
2879
-
2880
- // If the replacement has a type converter, attempt to materialize a
2881
- // conversion back to the original type.
2882
- if (!replConverter)
2883
- return emitConversionError ();
2884
-
2885
- // Materialize a conversion for this live result value.
2886
- Type resultType = result.getType ();
2887
- Value convertedValue = replConverter->materializeSourceConversion (
2888
- rewriter, op->getLoc (), resultType, newValue);
2889
- if (!convertedValue)
2890
- return emitConversionError ();
2891
-
2892
- rewriterImpl.mapping .map (result, convertedValue);
2893
- return success ();
2894
- }
2895
-
2896
2872
// ===----------------------------------------------------------------------===//
2897
2873
// Type Conversion
2898
2874
// ===----------------------------------------------------------------------===//
0 commit comments