@@ -2348,12 +2348,6 @@ 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
-
2357
2351
// / Legalize any unresolved type materializations.
2358
2352
LogicalResult legalizeUnresolvedMaterializations (
2359
2353
ConversionPatternRewriter &rewriter,
@@ -2365,6 +2359,14 @@ struct OperationConverter {
2365
2359
legalizeErasedResult (Operation *op, OpResult result,
2366
2360
ConversionPatternRewriterImpl &rewriterImpl);
2367
2361
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
+
2368
2370
// / Dialect conversion configuration.
2369
2371
ConversionConfig config;
2370
2372
@@ -2457,42 +2459,10 @@ OperationConverter::finalize(ConversionPatternRewriter &rewriter) {
2457
2459
return failure ();
2458
2460
DenseMap<Value, SmallVector<Value>> inverseMapping =
2459
2461
rewriterImpl.mapping .getInverse ();
2460
- if (failed (legalizeConvertedOpResultTypes (rewriter, rewriterImpl,
2461
- inverseMapping)))
2462
- return failure ();
2463
2462
if (failed (legalizeUnresolvedMaterializations (rewriter, rewriterImpl,
2464
2463
inverseMapping)))
2465
2464
return failure ();
2466
- return success ();
2467
- }
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 = {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
2465
2492
- LogicalResult OperationConverter::legalizeConvertedOpResultTypes (
2493
- ConversionPatternRewriter &rewriter,
2494
- ConversionPatternRewriterImpl &rewriterImpl,
2495
- DenseMap<Value, SmallVector<Value>> &inverseMapping) {
2496
2466
// Process requested operation replacements.
2497
2467
for (unsigned i = 0 ; i < rewriterImpl.rewrites .size (); ++i) {
2498
2468
auto *opReplacement =
@@ -2515,21 +2485,14 @@ LogicalResult OperationConverter::legalizeConvertedOpResultTypes(
2515
2485
if (result.getType () == newValue.getType ())
2516
2486
continue ;
2517
2487
2518
- Operation *liveUser =
2519
- findLiveUserOfReplaced (result, rewriterImpl, inverseMapping);
2520
- if (!liveUser)
2521
- continue ;
2522
-
2523
2488
// Legalize this result.
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);
2489
+ rewriter.setInsertionPoint (op);
2490
+ if (failed (legalizeChangedResultType (
2491
+ op, result, newValue, opReplacement->getConverter (), rewriter,
2492
+ rewriterImpl, inverseMapping)))
2493
+ return failure ();
2530
2494
}
2531
2495
}
2532
-
2533
2496
return success ();
2534
2497
}
2535
2498
@@ -2539,7 +2502,7 @@ LogicalResult OperationConverter::legalizeConvertedArgumentTypes(
2539
2502
// Functor used to check if all users of a value will be dead after
2540
2503
// conversion.
2541
2504
// TODO: This should probably query the inverse mapping, same as in
2542
- // `legalizeConvertedOpResultTypes `.
2505
+ // `legalizeChangedResultType `.
2543
2506
auto findLiveUser = [&](Value val) {
2544
2507
auto liveUserIt = llvm::find_if_not (val.getUsers (), [&](Operation *user) {
2545
2508
return rewriterImpl.isOpIgnored (user);
@@ -2869,6 +2832,67 @@ LogicalResult OperationConverter::legalizeErasedResult(
2869
2832
return success ();
2870
2833
}
2871
2834
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
+
2872
2896
// ===----------------------------------------------------------------------===//
2873
2897
// Type Conversion
2874
2898
// ===----------------------------------------------------------------------===//
0 commit comments