mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[sil] Add a new CastConsumptionKind called BorrowAlways.
This means that: 1. SILGenPattern always borrows the object before it emits a case. 2. Any cast with this cast has a +0 result. NOTE: That one can not use this with address types (so we assert if you pass this checked_cast_addr_br). NOTE: Once we have opaque values, checked_cast_br of a guaranteed value will lower to a copy + checked_cast_addr_br (assuming the operation is a consuming cast). To make sure this does not become a problem in terms of performance, we will need a pass that can transform SILGenPattern +0 cases to +1 cases. This is something that we have talked about in the past and I think it is reasonable to implement. This is an incremental commit towards fixing SILGenPattern for ownership. rdar://29791263
This commit is contained in:
@@ -1165,6 +1165,7 @@ static bool shouldTake(ConsumableManagedValue value, bool isIrrefutable) {
|
||||
case CastConsumptionKind::TakeAlways: return true;
|
||||
case CastConsumptionKind::TakeOnSuccess: return isIrrefutable;
|
||||
case CastConsumptionKind::CopyOnSuccess: return false;
|
||||
case CastConsumptionKind::BorrowAlways: return false;
|
||||
}
|
||||
llvm_unreachable("bad consumption kind");
|
||||
}
|
||||
@@ -1349,14 +1350,17 @@ static ConsumableManagedValue
|
||||
getManagedSubobject(SILGenFunction &SGF, SILValue value,
|
||||
const TypeLowering &valueTL,
|
||||
CastConsumptionKind consumption) {
|
||||
if (consumption == CastConsumptionKind::CopyOnSuccess) {
|
||||
switch (consumption) {
|
||||
case CastConsumptionKind::BorrowAlways:
|
||||
case CastConsumptionKind::CopyOnSuccess:
|
||||
return {ManagedValue::forUnmanaged(value), consumption};
|
||||
case CastConsumptionKind::TakeAlways:
|
||||
case CastConsumptionKind::TakeOnSuccess:
|
||||
assert((!SGF.F.getModule().getOptions().EnableSILOwnership ||
|
||||
consumption != CastConsumptionKind::TakeOnSuccess) &&
|
||||
"TakeOnSuccess should never be used when sil ownership is enabled");
|
||||
return {SGF.emitManagedRValueWithCleanup(value, valueTL), consumption};
|
||||
}
|
||||
|
||||
assert((!SGF.F.getModule().getOptions().EnableSILOwnership ||
|
||||
consumption != CastConsumptionKind::TakeOnSuccess) &&
|
||||
"TakeOnSuccess should never be used when sil ownership is enabled");
|
||||
return {SGF.emitManagedRValueWithCleanup(value, valueTL), consumption};
|
||||
}
|
||||
|
||||
static ConsumableManagedValue
|
||||
@@ -1873,6 +1877,7 @@ void PatternMatchEmission::emitEnumElementDispatch(
|
||||
switch (src.getFinalConsumption()) {
|
||||
case CastConsumptionKind::TakeAlways:
|
||||
case CastConsumptionKind::CopyOnSuccess:
|
||||
case CastConsumptionKind::BorrowAlways:
|
||||
// No change to src necessary.
|
||||
break;
|
||||
|
||||
@@ -1977,7 +1982,13 @@ void PatternMatchEmission::emitEnumElementDispatch(
|
||||
eltValue = SGF.B.createUncheckedTakeEnumDataAddr(loc, srcValue,
|
||||
elt, eltTy);
|
||||
break;
|
||||
|
||||
case CastConsumptionKind::BorrowAlways:
|
||||
// If we reach this point, we know that we have a loadable
|
||||
// element type from an enum with mixed address
|
||||
// only/loadable cases. Since we had an address only type,
|
||||
// we assume that we will not have BorrowAlways since
|
||||
// address only types do not support BorrowAlways.
|
||||
llvm_unreachable("not allowed");
|
||||
case CastConsumptionKind::CopyOnSuccess: {
|
||||
auto copy = SGF.emitTemporaryAllocation(loc, srcValue->getType());
|
||||
SGF.B.createCopyAddr(loc, srcValue, copy,
|
||||
|
||||
Reference in New Issue
Block a user