Skip to content

Commit 1f87ee8

Browse files
committed
[SILGen] InitAccessors: Extract emission of assign_or_init into a separate method
New method is going to be used to emit default value initializations for user-defined constructors.
1 parent 5fd502b commit 1f87ee8

File tree

3 files changed

+52
-43
lines changed

3 files changed

+52
-43
lines changed

lib/SILGen/SILGenFunction.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,3 +1823,42 @@ SILGenFunction::emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
18231823
ParameterConvention::Direct_Guaranteed);
18241824
return emitManagedRValueWithCleanup(setterPAI).getValue();
18251825
}
1826+
1827+
void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
1828+
VarDecl *field, ManagedValue newValue,
1829+
SubstitutionMap substitutions) {
1830+
auto fieldTy = field->getValueInterfaceType();
1831+
if (!substitutions.empty())
1832+
fieldTy = fieldTy.subst(substitutions);
1833+
1834+
// Emit the init accessor function partially applied to the base.
1835+
SILValue initFRef = emitGlobalFunctionRef(
1836+
loc, getAccessorDeclRef(field->getOpaqueAccessor(AccessorKind::Init)));
1837+
if (!substitutions.empty()) {
1838+
// If there are substitutions we need to emit partial apply to
1839+
// apply substitutions to the init accessor reference type.
1840+
auto initTy =
1841+
initFRef->getType().castTo<SILFunctionType>()->substGenericArgs(
1842+
SGM.M, substitutions, getTypeExpansionContext());
1843+
1844+
SILFunctionConventions setterConv(initTy, SGM.M);
1845+
1846+
// Emit partial apply without argument to produce a substituted
1847+
// init accessor reference.
1848+
PartialApplyInst *initPAI =
1849+
B.createPartialApply(loc, initFRef, substitutions, ArrayRef<SILValue>(),
1850+
ParameterConvention::Direct_Guaranteed);
1851+
initFRef = emitManagedRValueWithCleanup(initPAI).getValue();
1852+
}
1853+
1854+
SILValue setterFRef;
1855+
if (auto *setter = field->getOpaqueAccessor(AccessorKind::Set)) {
1856+
setterFRef = emitApplyOfSetterToBase(loc, SILDeclRef(setter), selfValue,
1857+
substitutions);
1858+
} else {
1859+
setterFRef = SILUndef::get(initFRef->getType(), F);
1860+
}
1861+
1862+
B.createAssignOrInit(loc, selfValue.getValue(), newValue.forward(*this),
1863+
initFRef, setterFRef, AssignOrInitInst::Unknown);
1864+
}

lib/SILGen/SILGenFunction.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,17 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
819819
ManagedValue base,
820820
SubstitutionMap substitutions);
821821

822+
/// Emit `assign_or_init` instruction that is going to either initialize
823+
/// or assign the given value to the given field.
824+
///
825+
/// \param loc The location to use for the instruction.
826+
/// \param selfValue The 'self' value.
827+
/// \param field The field to assign or initialize.
828+
/// \param newValue the value to assign/initialize the field with.
829+
/// \param substitutions The substitutions to apply to initializer and setter.
830+
void emitAssignOrInit(SILLocation loc, ManagedValue selfValue, VarDecl *field,
831+
ManagedValue newValue, SubstitutionMap substitutions);
832+
822833
/// Generates code to destroy the instance variables of a class.
823834
///
824835
/// \param selfValue The 'self' value.

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,24 +1526,10 @@ namespace {
15261526
void set(SILGenFunction &SGF, SILLocation loc, ArgumentSource &&value,
15271527
ManagedValue base) &&
15281528
override {
1529-
auto *field = cast<VarDecl>(Storage);
1530-
// Emit the init accessor function partially applied to the base.
1531-
SILValue initFRef =
1532-
emitPartialInitAccessorReference(SGF, loc, getAccessorDecl());
1533-
1534-
SILValue setterFRef;
1535-
if (auto *setter = field->getOpaqueAccessor(AccessorKind::Set)) {
1536-
setterFRef = SGF.emitApplyOfSetterToBase(loc, SILDeclRef(setter), base,
1537-
Substitutions);
1538-
} else {
1539-
setterFRef = SILUndef::get(initFRef->getType(), SGF.F);
1540-
}
1541-
1529+
VarDecl *field = cast<VarDecl>(Storage);
15421530
auto Mval =
15431531
emitValue(SGF, loc, field, std::move(value), AccessorKind::Init);
1544-
1545-
SGF.B.createAssignOrInit(loc, base.getValue(), Mval.forward(SGF),
1546-
initFRef, setterFRef, AssignOrInitInst::Unknown);
1532+
SGF.emitAssignOrInit(loc, base, field, Mval, Substitutions);
15471533
}
15481534

15491535
RValue get(SILGenFunction &SGF, SILLocation loc, ManagedValue base,
@@ -1571,33 +1557,6 @@ namespace {
15711557
Indices.isNull() ? nullptr : &Indices,
15721558
ArgListForDiagnostics};
15731559
}
1574-
1575-
private:
1576-
SILValue emitPartialInitAccessorReference(SILGenFunction &SGF,
1577-
SILLocation loc,
1578-
AccessorDecl *initAccessor) {
1579-
assert(initAccessor->isInitAccessor());
1580-
auto initConstant = SGF.getAccessorDeclRef(initAccessor);
1581-
SILValue initFRef = SGF.emitGlobalFunctionRef(loc, initConstant);
1582-
1583-
// If there are no substitutions there is no need to emit partial
1584-
// apply.
1585-
if (Substitutions.empty())
1586-
return initFRef;
1587-
1588-
CanSILFunctionType initTy =
1589-
initFRef->getType().castTo<SILFunctionType>()->substGenericArgs(
1590-
SGF.SGM.M, Substitutions, SGF.getTypeExpansionContext());
1591-
1592-
SILFunctionConventions setterConv(initTy, SGF.SGM.M);
1593-
1594-
// Emit partial apply without argument to produce a substituted
1595-
// init accessor reference.
1596-
PartialApplyInst *initPAI = SGF.B.createPartialApply(
1597-
loc, initFRef, Substitutions, ArrayRef<SILValue>(),
1598-
ParameterConvention::Direct_Guaranteed);
1599-
return SGF.emitManagedRValueWithCleanup(initPAI).getValue();
1600-
}
16011560
};
16021561

16031562
class GetterSetterComponent

0 commit comments

Comments
 (0)