Skip to content

Commit a01dc22

Browse files
committed
[SILGen] InitAccessors: Generalize AccessorComponent::emitValue
Instead of taking a setter type, let's switch over to a more general `AccessorKind` which allows us to cover init accessors and simplify `emitApplySetterToBase`.
1 parent e4e5aa1 commit a01dc22

File tree

3 files changed

+35
-27
lines changed

3 files changed

+35
-27
lines changed

lib/SILGen/SILGenFunction.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ ParamDecl *SILGenFunction::isMappedToInitAccessorArgument(VarDecl *property) {
17471747
return arg->second;
17481748
}
17491749

1750-
std::pair<SILValue, CanSILFunctionType>
1750+
SILValue
17511751
SILGenFunction::emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
17521752
ManagedValue base,
17531753
SubstitutionMap substitutions) {
@@ -1775,8 +1775,7 @@ SILGenFunction::emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
17751775
getTypeExpansionContext());
17761776
};
17771777

1778-
auto setterTy = getSetterType(setterFRef);
1779-
SILFunctionConventions setterConv(setterTy, SGM.M);
1778+
SILFunctionConventions setterConv(getSetterType(setterFRef), SGM.M);
17801779

17811780
// Emit captures for the setter
17821781
SmallVector<SILValue, 4> capturedArgs;
@@ -1814,5 +1813,5 @@ SILGenFunction::emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
18141813
PartialApplyInst *setterPAI =
18151814
B.createPartialApply(loc, setterFRef, substitutions, capturedArgs,
18161815
ParameterConvention::Direct_Guaranteed);
1817-
return {emitManagedRValueWithCleanup(setterPAI).getValue(), setterTy};
1816+
return emitManagedRValueWithCleanup(setterPAI).getValue();
18181817
}

lib/SILGen/SILGenFunction.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,9 +814,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
814814
void emitInitAccessor(AccessorDecl *accessor);
815815

816816
/// Generates code to emit the given setter reference to the given base value.
817-
std::pair<SILValue, CanSILFunctionType>
818-
emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter, ManagedValue base,
819-
SubstitutionMap substitutions);
817+
SILValue emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
818+
ManagedValue base,
819+
SubstitutionMap substitutions);
820820

821821
/// Generates code to destroy the instance variables of a class.
822822
///

lib/SILGen/SILGenLValue.cpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,8 +1439,23 @@ namespace {
14391439
}
14401440

14411441
ManagedValue emitValue(SILGenFunction &SGF, SILLocation loc, VarDecl *field,
1442-
Type fieldType, ArgumentSource &&value,
1443-
CanSILFunctionType accessorTy) {
1442+
ArgumentSource &&value, AccessorKind accessorKind) {
1443+
auto accessorInfo = SGF.getConstantInfo(
1444+
SGF.getTypeExpansionContext(),
1445+
SILDeclRef(field->getOpaqueAccessor(accessorKind)));
1446+
1447+
auto fieldTy = field->getValueInterfaceType();
1448+
auto accessorTy = SGF.SGM.Types
1449+
.getLoweredType(accessorInfo.SILFnType,
1450+
SGF.getTypeExpansionContext())
1451+
.castTo<SILFunctionType>();
1452+
1453+
if (!Substitutions.empty()) {
1454+
fieldTy = fieldTy.subst(Substitutions);
1455+
accessorTy = accessorTy->substGenericArgs(
1456+
SGF.SGM.M, Substitutions, SGF.getTypeExpansionContext());
1457+
}
1458+
14441459
SILFunctionConventions accessorConv(accessorTy, SGF.SGM.M);
14451460

14461461
// FIXME: This should use CallEmission instead of doing everything
@@ -1454,19 +1469,23 @@ namespace {
14541469
loweredSubstArgType =
14551470
SILType::getPrimitiveAddressType(loweredSubstArgType.getASTType());
14561471
}
1472+
14571473
auto loweredSubstParamTy = SILType::getPrimitiveType(
14581474
param.getArgumentType(SGF.SGM.M, accessorTy,
14591475
SGF.getTypeExpansionContext()),
14601476
loweredSubstArgType.getCategory());
1477+
14611478
// Handle reabstraction differences.
14621479
if (Mval.getType() != loweredSubstParamTy) {
14631480
Mval = SGF.emitSubstToOrigValue(
14641481
loc, Mval, SGF.SGM.Types.getAbstractionPattern(field),
1465-
fieldType->getCanonicalType());
1482+
fieldTy->getCanonicalType());
14661483
}
14671484

1485+
auto newValueArgIdx = accessorConv.getNumIndirectSILResults();
14681486
// If we need the argument in memory, materialize an address.
1469-
if (accessorConv.getSILArgumentConvention(0).isIndirectConvention() &&
1487+
if (accessorConv.getSILArgumentConvention(newValueArgIdx)
1488+
.isIndirectConvention() &&
14701489
!Mval.getType().isAddress()) {
14711490
Mval = Mval.materialize(SGF, loc);
14721491
}
@@ -1503,29 +1522,21 @@ namespace {
15031522
void set(SILGenFunction &SGF, SILLocation loc, ArgumentSource &&value,
15041523
ManagedValue base) &&
15051524
override {
1506-
VarDecl *field = cast<VarDecl>(Storage);
1507-
auto fieldType = field->getValueInterfaceType();
1508-
if (!Substitutions.empty()) {
1509-
fieldType = fieldType.subst(Substitutions);
1510-
}
1511-
1525+
auto *field = cast<VarDecl>(Storage);
15121526
// Emit the init accessor function partially applied to the base.
15131527
SILValue initFRef =
15141528
emitPartialInitAccessorReference(SGF, loc, getAccessorDecl());
15151529

15161530
SILValue setterFRef;
1517-
CanSILFunctionType setterTy;
1518-
15191531
if (auto *setter = field->getOpaqueAccessor(AccessorKind::Set)) {
1520-
std::tie(setterFRef, setterTy) = SGF.emitApplyOfSetterToBase(
1521-
loc, SILDeclRef(setter), base, Substitutions);
1532+
setterFRef = SGF.emitApplyOfSetterToBase(loc, SILDeclRef(setter), base,
1533+
Substitutions);
15221534
} else {
15231535
setterFRef = SILUndef::get(initFRef->getType(), SGF.F);
1524-
setterTy = initFRef->getType().castTo<SILFunctionType>();
15251536
}
15261537

15271538
auto Mval =
1528-
emitValue(SGF, loc, field, fieldType, std::move(value), setterTy);
1539+
emitValue(SGF, loc, field, std::move(value), AccessorKind::Init);
15291540

15301541
SGF.B.createAssignOrInit(loc, base.getValue(), Mval.forward(SGF),
15311542
initFRef, setterFRef, AssignOrInitInst::Unknown);
@@ -1818,15 +1829,13 @@ namespace {
18181829
ManagedValue initFn = SGF.emitManagedRValueWithCleanup(initPAI);
18191830

18201831
// Create the allocating setter function. It captures the base address.
1821-
SILValue setterFn;
1822-
CanSILFunctionType setterTy;
1823-
std::tie(setterFn, setterTy) =
1832+
SILValue setterFn =
18241833
SGF.emitApplyOfSetterToBase(loc, Accessor, base, Substitutions);
18251834

18261835
// Create the assign_by_wrapper with the initializer and setter.
18271836

18281837
auto Mval =
1829-
emitValue(SGF, loc, field, FieldType, std::move(value), setterTy);
1838+
emitValue(SGF, loc, field, std::move(value), AccessorKind::Set);
18301839

18311840
SGF.B.createAssignByWrapper(loc, Mval.forward(SGF), proj.forward(SGF),
18321841
initFn.getValue(), setterFn,

0 commit comments

Comments
 (0)