@@ -465,10 +465,10 @@ class PatternMatchEmission {
465
465
void emitSpecializedDispatch (ClauseMatrix &matrix, ArgArray args,
466
466
unsigned &lastRow, unsigned column,
467
467
const FailureHandler &failure);
468
- void emitTupleDispatchWithOwnership (ArrayRef<RowToSpecialize> rows,
469
- ConsumableManagedValue src,
470
- const SpecializationHandler &handleSpec,
471
- const FailureHandler &failure);
468
+ void emitTupleObjectDispatch (ArrayRef<RowToSpecialize> rows,
469
+ ConsumableManagedValue src,
470
+ const SpecializationHandler &handleSpec,
471
+ const FailureHandler &failure);
472
472
void emitTupleDispatch (ArrayRef<RowToSpecialize> rows,
473
473
ConsumableManagedValue src,
474
474
const SpecializationHandler &handleSpec,
@@ -738,15 +738,19 @@ forwardIntoSubtree(SILGenFunction &SGF, SILLocation loc,
738
738
ManagedValue outerMV = outerCMV.getFinalManagedValue ();
739
739
if (!outerMV.hasCleanup ()) return outerCMV;
740
740
741
- assert (outerCMV.getFinalConsumption () != CastConsumptionKind::CopyOnSuccess
742
- && " copy-on-success value with cleanup?" );
741
+ auto consumptionKind = outerCMV.getFinalConsumption ();
742
+ (void )consumptionKind;
743
+ assert ((consumptionKind == CastConsumptionKind::TakeAlways ||
744
+ consumptionKind == CastConsumptionKind::TakeOnSuccess) &&
745
+ " non-+1 consumption with a cleanup?" );
743
746
scope.pushCleanupState (outerMV.getCleanup (),
744
747
CleanupState::PersistentlyActive);
745
748
746
- // If SILOwnership is enabled, we always forward down values as borrows that
747
- // are copied on success.
748
- if (SGF.F .getModule ().getOptions ().EnableSILOwnership ) {
749
- return {outerMV.borrow (SGF, loc), CastConsumptionKind::CopyOnSuccess};
749
+ // If SILOwnership is enabled and we have an object, borrow instead of take on
750
+ // success.
751
+ if (SGF.F .getModule ().getOptions ().EnableSILOwnership &&
752
+ outerMV.getType ().isObject ()) {
753
+ return {outerMV.borrow (SGF, loc), CastConsumptionKind::BorrowAlways};
750
754
}
751
755
752
756
// Success means that we won't end up in the other branch,
@@ -766,9 +770,6 @@ static void forwardIntoIrrefutableSubtree(SILGenFunction &SGF,
766
770
767
771
assert (outerCMV.getFinalConsumption () != CastConsumptionKind::CopyOnSuccess
768
772
&& " copy-on-success value with cleanup?" );
769
- assert ((!SGF.F .getModule ().getOptions ().EnableSILOwnership ||
770
- outerCMV.getFinalConsumption () == CastConsumptionKind::TakeAlways) &&
771
- " When semantic sil is enabled, we should never see TakeOnSuccess" );
772
773
scope.pushCleanupState (outerMV.getCleanup (),
773
774
CleanupState::PersistentlyActive);
774
775
@@ -899,17 +900,9 @@ class ArgUnforwarder {
899
900
900
901
static bool requiresUnforwarding (SILGenFunction &SGF,
901
902
ConsumableManagedValue operand) {
902
- if (SGF.F .getModule ().getOptions ().EnableSILOwnership ) {
903
- assert (operand.getFinalConsumption () !=
904
- CastConsumptionKind::TakeOnSuccess &&
905
- " When compiling with sil ownership take on success is disabled" );
906
- // No unforwarding is needed, we always borrow/copy.
907
- return false ;
908
- }
909
-
910
- return (operand.hasCleanup () &&
911
- operand.getFinalConsumption ()
912
- == CastConsumptionKind::TakeOnSuccess);
903
+ return operand.hasCleanup () &&
904
+ operand.getFinalConsumption ()
905
+ == CastConsumptionKind::TakeOnSuccess;
913
906
}
914
907
915
908
// / Given that an aggregate was divided into a set of borrowed
@@ -1356,9 +1349,6 @@ getManagedSubobject(SILGenFunction &SGF, SILValue value,
1356
1349
return {ManagedValue::forUnmanaged (value), consumption};
1357
1350
case CastConsumptionKind::TakeAlways:
1358
1351
case CastConsumptionKind::TakeOnSuccess:
1359
- assert ((!SGF.F .getModule ().getOptions ().EnableSILOwnership ||
1360
- consumption != CastConsumptionKind::TakeOnSuccess) &&
1361
- " TakeOnSuccess should never be used when sil ownership is enabled" );
1362
1352
return {SGF.emitManagedRValueWithCleanup (value, valueTL), consumption};
1363
1353
}
1364
1354
}
@@ -1381,7 +1371,7 @@ emitReabstractedSubobject(SILGenFunction &SGF, SILLocation loc,
1381
1371
SGF.emitOrigToSubstValue (loc, mv, abstraction, substFormalType));
1382
1372
}
1383
1373
1384
- void PatternMatchEmission::emitTupleDispatchWithOwnership (
1374
+ void PatternMatchEmission::emitTupleObjectDispatch (
1385
1375
ArrayRef<RowToSpecialize> rows, ConsumableManagedValue src,
1386
1376
const SpecializationHandler &handleCase,
1387
1377
const FailureHandler &outerFailure) {
@@ -1409,8 +1399,7 @@ void PatternMatchEmission::emitTupleDispatchWithOwnership(
1409
1399
destructured.push_back ({v, src.getFinalConsumption ()});
1410
1400
});
1411
1401
1412
- // Break down the values.
1413
- // Recurse.
1402
+ // Since we did all of our work at +0, we just send down the outer failure.
1414
1403
handleCase (destructured, specializedRows, outerFailure);
1415
1404
}
1416
1405
@@ -1421,13 +1410,45 @@ void PatternMatchEmission::
1421
1410
emitTupleDispatch (ArrayRef<RowToSpecialize> rows, ConsumableManagedValue src,
1422
1411
const SpecializationHandler &handleCase,
1423
1412
const FailureHandler &outerFailure) {
1424
- if (SGF.getOptions ().EnableSILOwnership && src.getType ().isObject ()) {
1425
- return emitTupleDispatchWithOwnership (rows, src, handleCase, outerFailure);
1426
- }
1427
1413
auto firstPat = rows[0 ].Pattern ;
1428
- auto sourceType = cast<TupleType>(firstPat->getType ()->getCanonicalType ());
1429
1414
SILLocation loc = firstPat;
1430
1415
1416
+ // If our source is an address that is loadable, perform a load_borrow.
1417
+ if (src.getType ().isAddress () && src.getType ().isLoadable (SGF.getModule ())) {
1418
+ src = {SGF.B .createLoadBorrow (loc, src.getFinalManagedValue ()),
1419
+ CastConsumptionKind::BorrowAlways};
1420
+ }
1421
+
1422
+ // Then if we have an object...
1423
+ if (src.getType ().isObject ()) {
1424
+ // Make sure that if we ahve a copy_on_success, non-trivial value that we do
1425
+ // not have a value with @owned ownership.
1426
+ assert ((!src.getType ().isTrivial (SGF.getModule ()) ||
1427
+ src.getFinalConsumption () != CastConsumptionKind::CopyOnSuccess ||
1428
+ src.getOwnershipKind () != ValueOwnershipKind::Owned) &&
1429
+ " @owned value without cleanup + copy_on_success" );
1430
+
1431
+ // If we have are asked to perform TakeOnSuccess, borrow the value instead.
1432
+ //
1433
+ // The reason why do this for TakeOnSuccess is that we want to not have to
1434
+ // deal with unforwarding of aggregate tuples in failing cases since that
1435
+ // causes ownership invariants to be violated since we already forwarded the
1436
+ // aggregate to create cleanups on its elements.
1437
+ //
1438
+ // In contrast, we do still want to allow for TakeAlways variants to not
1439
+ // need to borrow, so we do not borrow if we take always.
1440
+ if (!src.getType ().isTrivial (SGF.getModule ()) &&
1441
+ src.getFinalConsumption () == CastConsumptionKind::TakeOnSuccess) {
1442
+ src = {src.getFinalManagedValue ().borrow (SGF, loc),
1443
+ CastConsumptionKind::BorrowAlways};
1444
+ }
1445
+
1446
+ // Then perform a forward or reborrow destructure on the object.
1447
+ return emitTupleObjectDispatch (rows, src, handleCase, outerFailure);
1448
+ }
1449
+
1450
+ auto sourceType = cast<TupleType>(firstPat->getType ()->getCanonicalType ());
1451
+
1431
1452
SILValue v = src.getFinalManagedValue ().forward (SGF);
1432
1453
SmallVector<ConsumableManagedValue, 4 > destructured;
1433
1454
@@ -1882,8 +1903,6 @@ void PatternMatchEmission::emitEnumElementDispatch(
1882
1903
break ;
1883
1904
1884
1905
case CastConsumptionKind::TakeOnSuccess:
1885
- assert (!SGF.F .getModule ().getOptions ().EnableSILOwnership &&
1886
- " TakeOnSuccess is not supported when compiling with ownership" );
1887
1906
// If any of the specialization cases is refutable, we must copy.
1888
1907
if (!blocks.hasAnyRefutableCase ())
1889
1908
break ;
@@ -1966,8 +1985,6 @@ void PatternMatchEmission::emitEnumElementDispatch(
1966
1985
auto eltConsumption = src.getFinalConsumption ();
1967
1986
if (caseInfo.Irrefutable &&
1968
1987
eltConsumption == CastConsumptionKind::TakeOnSuccess) {
1969
- assert (!SGF.F .getModule ().getOptions ().EnableSILOwnership &&
1970
- " TakeOnSuccess is not supported when compiling with ownership" );
1971
1988
eltConsumption = CastConsumptionKind::TakeAlways;
1972
1989
}
1973
1990
@@ -2760,8 +2777,9 @@ void SILGenFunction::emitCatchDispatch(DoCatchStmt *S, ManagedValue exn,
2760
2777
// Set up an initial clause matrix.
2761
2778
ClauseMatrix clauseMatrix (clauseRows);
2762
2779
ConsumableManagedValue subject;
2763
- if (F.getModule ().getOptions ().EnableSILOwnership ) {
2764
- subject = {exn.borrow (*this , S), CastConsumptionKind::CopyOnSuccess};
2780
+ if (F.getModule ().getOptions ().EnableSILOwnership &&
2781
+ exn.getType ().isObject ()) {
2782
+ subject = {exn.borrow (*this , S), CastConsumptionKind::BorrowAlways};
2765
2783
} else {
2766
2784
subject = {exn, CastConsumptionKind::TakeOnSuccess};
2767
2785
}
0 commit comments