Skip to content

Commit 0de3535

Browse files
authored
Merge pull request #32785 from davezarzycki/pr32785
[SIL] Convert computeLoweredRValueType to CanTypeVisitor
2 parents 7fccbad + 03411af commit 0de3535

File tree

1 file changed

+126
-107
lines changed

1 file changed

+126
-107
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 126 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,131 +1772,150 @@ CanType
17721772
TypeConverter::computeLoweredRValueType(TypeExpansionContext forExpansion,
17731773
AbstractionPattern origType,
17741774
CanType substType) {
1775-
// AST function types are turned into SIL function types:
1776-
// - the type is uncurried as desired
1777-
// - types are turned into their unbridged equivalents, depending
1778-
// on the abstract CC
1779-
// - ownership conventions are deduced
1780-
// - a minimal substituted generic signature is extracted to represent
1781-
// possible ABI-compatible substitutions
1782-
if (auto substFnType = dyn_cast<AnyFunctionType>(substType)) {
1783-
// If the formal type uses a C convention, it is not formally
1784-
// abstractable, and it may be subject to implicit bridging.
1785-
auto extInfo = substFnType->getExtInfo();
1786-
if (getSILFunctionLanguage(extInfo.getSILRepresentation())
1787-
== SILFunctionLanguage::C) {
1788-
// The importer only applies fully-reversible bridging to the
1789-
// component types of C function pointers.
1790-
auto bridging = Bridgeability::Full;
1791-
if (extInfo.getSILRepresentation()
1792-
== SILFunctionTypeRepresentation::CFunctionPointer)
1793-
bridging = Bridgeability::None;
1794-
1795-
// Bridge the parameters and result of the function type.
1796-
auto bridgedFnType = getBridgedFunctionType(origType, substFnType,
1797-
extInfo, bridging);
1798-
substFnType = bridgedFnType;
1799-
1800-
// Also rewrite the type of the abstraction pattern.
1801-
auto signature = origType.getGenericSignatureOrNull();
1802-
if (origType.isTypeParameter()) {
1803-
origType = AbstractionPattern(signature, bridgedFnType);
1804-
} else {
1805-
origType.rewriteType(signature, bridgedFnType);
1775+
class LoweredRValueTypeVisitor
1776+
: public CanTypeVisitor<LoweredRValueTypeVisitor, CanType> {
1777+
TypeConverter &TC;
1778+
TypeExpansionContext forExpansion;
1779+
AbstractionPattern origType;
1780+
1781+
public:
1782+
LoweredRValueTypeVisitor(TypeConverter &TC,
1783+
TypeExpansionContext forExpansion,
1784+
AbstractionPattern origType)
1785+
: TC(TC), forExpansion(forExpansion), origType(origType) {}
1786+
1787+
// AST function types are turned into SIL function types:
1788+
// - the type is uncurried as desired
1789+
// - types are turned into their unbridged equivalents, depending
1790+
// on the abstract CC
1791+
// - ownership conventions are deduced
1792+
// - a minimal substituted generic signature is extracted to represent
1793+
// possible ABI-compatible substitutions
1794+
CanType visitAnyFunctionType(CanAnyFunctionType substFnType) {
1795+
// If the formal type uses a C convention, it is not formally
1796+
// abstractable, and it may be subject to implicit bridging.
1797+
auto extInfo = substFnType->getExtInfo();
1798+
if (getSILFunctionLanguage(extInfo.getSILRepresentation()) ==
1799+
SILFunctionLanguage::C) {
1800+
// The importer only applies fully-reversible bridging to the
1801+
// component types of C function pointers.
1802+
auto bridging = Bridgeability::Full;
1803+
if (extInfo.getSILRepresentation() ==
1804+
SILFunctionTypeRepresentation::CFunctionPointer)
1805+
bridging = Bridgeability::None;
1806+
1807+
// Bridge the parameters and result of the function type.
1808+
auto bridgedFnType =
1809+
TC.getBridgedFunctionType(origType, substFnType, extInfo, bridging);
1810+
substFnType = bridgedFnType;
1811+
1812+
// Also rewrite the type of the abstraction pattern.
1813+
auto signature = origType.getGenericSignatureOrNull();
1814+
if (origType.isTypeParameter()) {
1815+
origType = AbstractionPattern(signature, bridgedFnType);
1816+
} else {
1817+
origType.rewriteType(signature, bridgedFnType);
1818+
}
18061819
}
1820+
1821+
return ::getNativeSILFunctionType(TC, forExpansion, origType,
1822+
substFnType);
18071823
}
18081824

1809-
return getNativeSILFunctionType(*this, forExpansion, origType, substFnType);
1810-
}
1825+
// Ignore dynamic self types.
1826+
CanType visitDynamicSelfType(CanDynamicSelfType selfType) {
1827+
return TC.getLoweredRValueType(forExpansion, origType,
1828+
selfType.getSelfType());
1829+
}
18111830

1812-
// Ignore dynamic self types.
1813-
if (auto selfType = dyn_cast<DynamicSelfType>(substType)) {
1814-
return getLoweredRValueType(forExpansion, origType, selfType.getSelfType());
1815-
}
1831+
// Static metatypes are unitary and can optimized to a "thin" empty
1832+
// representation if the type also appears as a static metatype in the
1833+
// original abstraction pattern.
1834+
CanType visitMetatypeType(CanMetatypeType substMeta) {
1835+
// If the metatype has already been lowered, it will already carry its
1836+
// representation.
1837+
if (substMeta->hasRepresentation()) {
1838+
assert(substMeta->isLegalSILType());
1839+
return substOpaqueTypesWithUnderlyingTypes(substMeta, forExpansion);
1840+
}
18161841

1817-
// Static metatypes are unitary and can optimized to a "thin" empty
1818-
// representation if the type also appears as a static metatype in the
1819-
// original abstraction pattern.
1820-
if (auto substMeta = dyn_cast<MetatypeType>(substType)) {
1821-
// If the metatype has already been lowered, it will already carry its
1822-
// representation.
1823-
if (substMeta->hasRepresentation()) {
1824-
assert(substMeta->isLegalSILType());
1825-
return substOpaqueTypesWithUnderlyingTypes(substMeta, forExpansion);
1826-
}
1842+
MetatypeRepresentation repr;
18271843

1828-
MetatypeRepresentation repr;
1829-
1830-
auto origMeta = origType.getAs<MetatypeType>();
1831-
if (!origMeta) {
1832-
// If the metatype matches a dependent type, it must be thick.
1833-
assert(origType.isTypeParameterOrOpaqueArchetype());
1834-
repr = MetatypeRepresentation::Thick;
1835-
} else {
1836-
// Otherwise, we're thin if the metatype is thinnable both
1837-
// substituted and in the abstraction pattern.
1838-
if (hasSingletonMetatype(substMeta.getInstanceType())
1839-
&& hasSingletonMetatype(origMeta.getInstanceType()))
1840-
repr = MetatypeRepresentation::Thin;
1841-
else
1844+
auto origMeta = origType.getAs<MetatypeType>();
1845+
if (!origMeta) {
1846+
// If the metatype matches a dependent type, it must be thick.
1847+
assert(origType.isTypeParameterOrOpaqueArchetype());
18421848
repr = MetatypeRepresentation::Thick;
1843-
}
1849+
} else {
1850+
// Otherwise, we're thin if the metatype is thinnable both
1851+
// substituted and in the abstraction pattern.
1852+
if (hasSingletonMetatype(substMeta.getInstanceType()) &&
1853+
hasSingletonMetatype(origMeta.getInstanceType()))
1854+
repr = MetatypeRepresentation::Thin;
1855+
else
1856+
repr = MetatypeRepresentation::Thick;
1857+
}
18441858

1845-
CanType instanceType = substOpaqueTypesWithUnderlyingTypes(
1846-
substMeta.getInstanceType(), forExpansion);
1859+
CanType instanceType = substOpaqueTypesWithUnderlyingTypes(
1860+
substMeta.getInstanceType(), forExpansion);
18471861

1848-
// Regardless of thinness, metatypes are always trivial.
1849-
return CanMetatypeType::get(instanceType, repr);
1850-
}
1862+
// Regardless of thinness, metatypes are always trivial.
1863+
return CanMetatypeType::get(instanceType, repr);
1864+
}
18511865

1852-
// Give existential metatypes @thick representation by default.
1853-
if (auto existMetatype = dyn_cast<ExistentialMetatypeType>(substType)) {
1854-
if (existMetatype->hasRepresentation()) {
1855-
assert(existMetatype->isLegalSILType());
1856-
return existMetatype;
1866+
// Give existential metatypes @thick representation by default.
1867+
CanType
1868+
visitExistentialMetatypeType(CanExistentialMetatypeType existMetatype) {
1869+
if (existMetatype->hasRepresentation()) {
1870+
assert(existMetatype->isLegalSILType());
1871+
return existMetatype;
1872+
}
1873+
1874+
return CanExistentialMetatypeType::get(existMetatype.getInstanceType(),
1875+
MetatypeRepresentation::Thick);
18571876
}
18581877

1859-
return CanExistentialMetatypeType::get(existMetatype.getInstanceType(),
1860-
MetatypeRepresentation::Thick);
1861-
}
1878+
// Lower tuple element types.
1879+
CanType visitTupleType(CanTupleType substTupleType) {
1880+
return computeLoweredTupleType(TC, forExpansion, origType,
1881+
substTupleType);
1882+
}
18621883

1863-
// Lower tuple element types.
1864-
if (auto substTupleType = dyn_cast<TupleType>(substType)) {
1865-
return computeLoweredTupleType(*this, forExpansion, origType,
1866-
substTupleType);
1867-
}
1884+
// Lower the referent type of reference storage types.
1885+
CanType visitReferenceStorageType(CanReferenceStorageType substRefType) {
1886+
return computeLoweredReferenceStorageType(TC, forExpansion, origType,
1887+
substRefType);
1888+
}
18681889

1869-
// Lower the referent type of reference storage types.
1870-
if (auto substRefType = dyn_cast<ReferenceStorageType>(substType)) {
1871-
return computeLoweredReferenceStorageType(*this, forExpansion, origType,
1872-
substRefType);
1873-
}
1890+
CanType visitSILFunctionType(CanSILFunctionType silFnTy) {
1891+
if (!silFnTy->hasOpaqueArchetype() ||
1892+
!forExpansion.shouldLookThroughOpaqueTypeArchetypes())
1893+
return silFnTy;
1894+
return silFnTy->substituteOpaqueArchetypes(TC, forExpansion);
1895+
}
18741896

1875-
// Lower the object type of optional types.
1876-
if (auto substObjectType = substType.getOptionalObjectType()) {
1877-
return computeLoweredOptionalType(*this, forExpansion, origType,
1878-
substType, substObjectType);
1879-
}
1897+
CanType visitType(CanType substType) {
1898+
// Lower the object type of optional types.
1899+
if (auto substObjectType = substType.getOptionalObjectType()) {
1900+
return computeLoweredOptionalType(TC, forExpansion, origType, substType,
1901+
substObjectType);
1902+
}
18801903

1881-
if (auto silFnTy = dyn_cast<SILFunctionType>(substType)) {
1882-
if (!substType->hasOpaqueArchetype() ||
1883-
!forExpansion.shouldLookThroughOpaqueTypeArchetypes())
1884-
return substType;
1885-
return silFnTy->substituteOpaqueArchetypes(*this, forExpansion);
1886-
}
1904+
// The Swift type directly corresponds to the lowered type.
1905+
auto underlyingTy =
1906+
substOpaqueTypesWithUnderlyingTypes(substType, forExpansion,
1907+
/*allowLoweredTypes*/ true);
1908+
if (underlyingTy != substType) {
1909+
underlyingTy =
1910+
TC.computeLoweredRValueType(forExpansion, origType, underlyingTy);
1911+
}
18871912

1888-
// The Swift type directly corresponds to the lowered type.
1889-
auto underlyingTy =
1890-
substOpaqueTypesWithUnderlyingTypes(substType, forExpansion,
1891-
/*allowLoweredTypes*/ true);
1892-
if (underlyingTy != substType) {
1893-
underlyingTy = computeLoweredRValueType(
1894-
forExpansion,
1895-
origType,
1896-
underlyingTy);
1897-
}
1913+
return underlyingTy;
1914+
}
1915+
};
18981916

1899-
return underlyingTy;
1917+
LoweredRValueTypeVisitor visitor(*this, forExpansion, origType);
1918+
return visitor.visit(substType);
19001919
}
19011920

19021921
const TypeLowering &

0 commit comments

Comments
 (0)