Skip to content

Commit 01bc89d

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 a01dc22 commit 01bc89d

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
@@ -1815,3 +1815,42 @@ SILGenFunction::emitApplyOfSetterToBase(SILLocation loc, SILDeclRef setter,
18151815
ParameterConvention::Direct_Guaranteed);
18161816
return emitManagedRValueWithCleanup(setterPAI).getValue();
18171817
}
1818+
1819+
void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
1820+
VarDecl *field, ManagedValue newValue,
1821+
SubstitutionMap substitutions) {
1822+
auto fieldTy = field->getValueInterfaceType();
1823+
if (!substitutions.empty())
1824+
fieldTy = fieldTy.subst(substitutions);
1825+
1826+
// Emit the init accessor function partially applied to the base.
1827+
SILValue initFRef = emitGlobalFunctionRef(
1828+
loc, getAccessorDeclRef(field->getOpaqueAccessor(AccessorKind::Init)));
1829+
if (!substitutions.empty()) {
1830+
// If there are substitutions we need to emit partial apply to
1831+
// apply substitutions to the init accessor reference type.
1832+
auto initTy =
1833+
initFRef->getType().castTo<SILFunctionType>()->substGenericArgs(
1834+
SGM.M, substitutions, getTypeExpansionContext());
1835+
1836+
SILFunctionConventions setterConv(initTy, SGM.M);
1837+
1838+
// Emit partial apply without argument to produce a substituted
1839+
// init accessor reference.
1840+
PartialApplyInst *initPAI =
1841+
B.createPartialApply(loc, initFRef, substitutions, ArrayRef<SILValue>(),
1842+
ParameterConvention::Direct_Guaranteed);
1843+
initFRef = emitManagedRValueWithCleanup(initPAI).getValue();
1844+
}
1845+
1846+
SILValue setterFRef;
1847+
if (auto *setter = field->getOpaqueAccessor(AccessorKind::Set)) {
1848+
setterFRef = emitApplyOfSetterToBase(loc, SILDeclRef(setter), selfValue,
1849+
substitutions);
1850+
} else {
1851+
setterFRef = SILUndef::get(initFRef->getType(), F);
1852+
}
1853+
1854+
B.createAssignOrInit(loc, selfValue.getValue(), newValue.forward(*this),
1855+
initFRef, setterFRef, AssignOrInitInst::Unknown);
1856+
}

lib/SILGen/SILGenFunction.h

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

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

lib/SILGen/SILGenLValue.cpp

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

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

15991558
class GetterSetterComponent

0 commit comments

Comments
 (0)