Skip to content

Commit 5f3664e

Browse files
Merge pull request #62563 from nate-chandler/opaque-values/1/20221212
[OpaqueValues] Initial key-path support.
2 parents 99089c8 + cd03615 commit 5f3664e

File tree

3 files changed

+82
-20
lines changed

3 files changed

+82
-20
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,9 +2743,11 @@ emitKeyPathRValueBase(SILGenFunction &subSGF,
27432743
// There no real argument to pass to the underlying accessors.
27442744
if (!storage->getDeclContext()->isTypeContext())
27452745
return ManagedValue();
2746-
2747-
auto paramOrigValue =
2748-
ManagedValue::forBorrowedRValue(paramArg).copy(subSGF, loc);
2746+
2747+
auto paramOrigValue = paramArg->getType().isTrivial(subSGF.F)
2748+
? ManagedValue::forTrivialRValue(paramArg)
2749+
: ManagedValue::forBorrowedRValue(paramArg);
2750+
paramOrigValue = paramOrigValue.copy(subSGF, loc);
27492751
auto paramSubstValue = subSGF.emitOrigToSubstValue(loc, paramOrigValue,
27502752
AbstractionPattern::getOpaque(),
27512753
baseType);
@@ -2942,15 +2944,20 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
29422944
subSGF.F.getTypeExpansionContext());
29432945

29442946
auto entry = thunk->begin();
2945-
auto resultArgTy = signature->getSingleResult().getSILStorageType(
2946-
SGM.M, signature, subSGF.F.getTypeExpansionContext());
2947-
auto baseArgTy = signature->getParameters()[0].getSILStorageType(
2948-
SGM.M, signature, subSGF.F.getTypeExpansionContext());
2947+
auto resultArgTy =
2948+
subSGF.silConv.getSILType(signature->getSingleResult(), signature,
2949+
subSGF.F.getTypeExpansionContext());
2950+
auto baseArgTy =
2951+
subSGF.silConv.getSILType(signature->getParameters()[0], signature,
2952+
subSGF.F.getTypeExpansionContext());
29492953
if (genericEnv) {
29502954
resultArgTy = genericEnv->mapTypeIntoContext(SGM.M, resultArgTy);
29512955
baseArgTy = genericEnv->mapTypeIntoContext(SGM.M, baseArgTy);
29522956
}
2953-
auto resultArg = entry->createFunctionArgument(resultArgTy);
2957+
SILFunctionArgument *resultArg = nullptr;
2958+
if (SGM.M.useLoweredAddresses()) {
2959+
resultArg = entry->createFunctionArgument(resultArgTy);
2960+
}
29542961
auto baseArg = entry->createFunctionArgument(baseArgTy);
29552962
SILValue indexPtrArg;
29562963
if (!indexes.empty()) {
@@ -2997,15 +3004,21 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
29973004
resultSubst = std::move(resultRValue).getAsSingleValue(subSGF, loc);
29983005
}
29993006

3000-
if (resultSubst.getType().getAddressType() != resultArg->getType())
3007+
if (resultSubst.getType().getAddressType() != resultArgTy)
30013008
resultSubst = subSGF.emitSubstToOrigValue(loc, resultSubst,
30023009
AbstractionPattern::getOpaque(),
30033010
propertyType);
3004-
3005-
resultSubst.forwardInto(subSGF, loc, resultArg);
3006-
scope.pop();
3007-
3008-
subSGF.B.createReturn(loc, subSGF.emitEmptyTuple(loc));
3011+
3012+
if (SGM.M.useLoweredAddresses()) {
3013+
resultSubst.forwardInto(subSGF, loc, resultArg);
3014+
scope.pop();
3015+
3016+
subSGF.B.createReturn(loc, subSGF.emitEmptyTuple(loc));
3017+
} else {
3018+
auto result = resultSubst.forward(subSGF);
3019+
scope.pop();
3020+
subSGF.B.createReturn(loc, result);
3021+
}
30093022

30103023
SGM.emitLazyConformancesForFunction(thunk);
30113024
return thunk;

lib/SILGen/SILGenLValue.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,12 +2122,16 @@ makeBaseConsumableMaterializedRValue(SILGenFunction &SGF,
21222122
bool isBorrowed = base.isPlusZeroRValueOrTrivial()
21232123
&& !base.getType().isTrivial(SGF.F);
21242124
if (!base.getType().isAddress() || isBorrowed) {
2125-
auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
2126-
if (isBorrowed)
2127-
base.copyInto(SGF, loc, tmp);
2128-
else
2129-
base.forwardInto(SGF, loc, tmp);
2130-
return SGF.emitManagedBufferWithCleanup(tmp);
2125+
if (SGF.useLoweredAddresses()) {
2126+
auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
2127+
if (isBorrowed)
2128+
base.copyInto(SGF, loc, tmp);
2129+
else
2130+
base.forwardInto(SGF, loc, tmp);
2131+
return SGF.emitManagedBufferWithCleanup(tmp);
2132+
} else {
2133+
return base.copy(SGF, loc);
2134+
}
21312135
}
21322136

21332137
return base;

test/SILGen/opaque_values_silgen.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,48 @@ func duplicate_with_int3<Value>(value: Value) -> (Int, (Value, (Value, (Value, I
591591
(42, (value, (value, (value, 43), value)), 44)
592592
}
593593
}
594+
595+
// Keypaths
596+
597+
indirect enum IndirectEnumWithAReadableIntProperty {
598+
// CHECK-LABEL: sil {{.*}}@$s20opaque_values_silgen36IndirectEnumWithAReadableIntPropertyO1iSivpACTK : {{.*}} {
599+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
600+
// TODO: Eliminate this copy.
601+
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
602+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[COPY]]
603+
// CHECK: [[FN:%[^,]+]] = function_ref @$s20opaque_values_silgen36IndirectEnumWithAReadableIntPropertyO1iSivg : $@convention(method) (@guaranteed IndirectEnumWithAReadableIntProperty) -> Int
604+
// CHECK: [[RESULT:%[^,]+]] = apply [[FN]]([[LIFETIME]])
605+
// CHECK: end_borrow [[LIFETIME]]
606+
// CHECK: destroy_value [[COPY]]
607+
// CHECK: return [[RESULT]]
608+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen36IndirectEnumWithAReadableIntPropertyO1iSivpACTK'
609+
var i: Int { 0 }
610+
}
611+
612+
func takeReadableIntKeyPath<T>(_ kp: KeyPath<T, Int>) {
613+
}
614+
615+
func giveReadableIntKeyPathInt() {
616+
takeReadableIntKeyPath(\IndirectEnumWithAReadableIntProperty.i)
617+
}
618+
619+
indirect enum StructWithAReadableStringProperty {
620+
// CHECK-LABEL: sil {{.*}}@$s20opaque_values_silgen33StructWithAReadableStringPropertyO1sSSvpACTK : {{.*}} {
621+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
622+
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
623+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[COPY]]
624+
// CHECK: [[FN:%[^,]+]] = function_ref @$s20opaque_values_silgen33StructWithAReadableStringPropertyO1sSSvg : $@convention(method) (@guaranteed StructWithAReadableStringProperty) -> @owned String
625+
// CHECK: [[RESULT:%[^,]+]] = apply [[FN]]([[LIFETIME]])
626+
// CHECK: end_borrow [[LIFETIME]]
627+
// CHECK: destroy_value [[COPY]]
628+
// CHECK: return [[RESULT]]
629+
// CHECK-LABEL: } // end sil function '$s20opaque_values_silgen33StructWithAReadableStringPropertyO1sSSvpACTK'
630+
var s: String { "howdy" }
631+
}
632+
633+
func takeKeyPathString<T>(_ kp: KeyPath<T, String>) {
634+
}
635+
636+
func giveKeyPathString() {
637+
takeKeyPathString(\StructWithAReadableStringProperty.s)
638+
}

0 commit comments

Comments
 (0)