Skip to content

Commit 15b5dcb

Browse files
committed
Simplify the representation of conversions to make it easier to extract
the source/result/lowered-result types.
1 parent 79d1d68 commit 15b5dcb

File tree

3 files changed

+70
-101
lines changed

3 files changed

+70
-101
lines changed

lib/SILGen/Conversion.h

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,7 @@ class Conversion {
112112
private:
113113
KindTy Kind;
114114

115-
struct BridgingTypes {
116-
CanType OrigType;
117-
CanType ResultType;
118-
SILType LoweredResultType;
115+
struct BridgingStorage {
119116
bool IsExplicit;
120117
};
121118

@@ -129,16 +126,17 @@ class Conversion {
129126
/// elegantly perform a single (perhaps identity) reabstraction when
130127
/// receiving a function result or loading a value from abstracted
131128
/// storage.
132-
struct ReabstractionTypes {
129+
struct ReabstractionStorage {
133130
AbstractionPattern InputOrigType;
134131
AbstractionPattern OutputOrigType;
135-
CanType InputSubstType;
136-
CanType OutputSubstType;
137132
SILType InputLoweredTy;
138-
SILType OutputLoweredTy;
139133
};
140134

141-
using Members = ExternalUnionMembers<BridgingTypes, ReabstractionTypes>;
135+
CanType SourceType;
136+
CanType ResultType;
137+
SILType LoweredResultType;
138+
139+
using Members = ExternalUnionMembers<BridgingStorage, ReabstractionStorage>;
142140

143141
static Members::Index getStorageIndexForKind(KindTy kind) {
144142
switch (kind) {
@@ -150,10 +148,10 @@ class Conversion {
150148
case AnyErasure:
151149
case BridgingSubtype:
152150
case Subtype:
153-
return Members::indexOf<BridgingTypes>();
151+
return Members::indexOf<BridgingStorage>();
154152

155153
case Reabstract:
156-
return Members::indexOf<ReabstractionTypes>();
154+
return Members::indexOf<ReabstractionStorage>();
157155
}
158156
llvm_unreachable("bad kind");
159157
}
@@ -162,21 +160,23 @@ class Conversion {
162160
static_assert(decltype(Types)::union_is_trivially_copyable,
163161
"define the special members if this changes");
164162

165-
Conversion(KindTy kind, CanType origType, CanType resultType,
163+
Conversion(KindTy kind, CanType sourceType, CanType resultType,
166164
SILType loweredResultTy, bool isExplicit)
167-
: Kind(kind) {
168-
Types.emplaceAggregate<BridgingTypes>(kind, origType, resultType,
169-
loweredResultTy, isExplicit);
165+
: Kind(kind), SourceType(sourceType), ResultType(resultType),
166+
LoweredResultType(loweredResultTy) {
167+
Types.emplaceAggregate<BridgingStorage>(kind, isExplicit);
170168
}
171169

172170
Conversion(AbstractionPattern inputOrigType, CanType inputSubstType,
173171
SILType inputLoweredTy,
174172
AbstractionPattern outputOrigType, CanType outputSubstType,
175173
SILType outputLoweredTy)
176-
: Kind(Reabstract) {
177-
Types.emplaceAggregate<ReabstractionTypes>(Kind, inputOrigType, outputOrigType,
178-
inputSubstType, outputSubstType,
179-
inputLoweredTy, outputLoweredTy);
174+
: Kind(Reabstract), SourceType(inputSubstType),
175+
ResultType(outputSubstType),
176+
LoweredResultType(outputLoweredTy) {
177+
Types.emplaceAggregate<ReabstractionStorage>(Kind, inputOrigType,
178+
outputOrigType,
179+
inputLoweredTy);
180180
}
181181

182182
static bool isAllowedConversion(CanType inputType, CanType outputType) {
@@ -262,61 +262,43 @@ class Conversion {
262262
}
263263

264264
AbstractionPattern getReabstractionInputOrigType() const {
265-
return Types.get<ReabstractionTypes>(Kind).InputOrigType;
265+
return Types.get<ReabstractionStorage>(Kind).InputOrigType;
266266
}
267267

268268
CanType getReabstractionInputSubstType() const {
269-
return Types.get<ReabstractionTypes>(Kind).InputSubstType;
269+
return getSourceType();
270270
}
271271

272272
SILType getReabstractionInputLoweredType() const {
273-
return Types.get<ReabstractionTypes>(Kind).InputLoweredTy;
273+
return Types.get<ReabstractionStorage>(Kind).InputLoweredTy;
274274
}
275275

276276
AbstractionPattern getReabstractionOutputOrigType() const {
277-
return Types.get<ReabstractionTypes>(Kind).OutputOrigType;
277+
return Types.get<ReabstractionStorage>(Kind).OutputOrigType;
278278
}
279279

280280
CanType getReabstractionOutputSubstType() const {
281-
return Types.get<ReabstractionTypes>(Kind).OutputSubstType;
281+
return getResultType();
282282
}
283283

284284
SILType getReabstractionOutputLoweredType() const {
285-
return Types.get<ReabstractionTypes>(Kind).OutputLoweredTy;
285+
return getLoweredResultType();
286286
}
287287

288288
bool isBridgingExplicit() const {
289-
return Types.get<BridgingTypes>(Kind).IsExplicit;
290-
}
291-
292-
CanType getBridgingSourceType() const {
293-
return Types.get<BridgingTypes>(Kind).OrigType;
294-
}
295-
296-
CanType getBridgingResultType() const {
297-
return Types.get<BridgingTypes>(Kind).ResultType;
298-
}
299-
300-
SILType getBridgingLoweredResultType() const {
301-
return Types.get<BridgingTypes>(Kind).LoweredResultType;
289+
return Types.get<BridgingStorage>(Kind).IsExplicit;
302290
}
303291

304292
CanType getSourceType() const {
305-
if (isBridging())
306-
return getBridgingSourceType();
307-
return getReabstractionInputSubstType();
293+
return SourceType;
308294
}
309295

310296
CanType getResultType() const {
311-
if (isBridging())
312-
return getBridgingResultType();
313-
return getReabstractionOutputSubstType();
297+
return ResultType;
314298
}
315299

316300
SILType getLoweredResultType() const {
317-
if (isBridging())
318-
return getBridgingLoweredResultType();
319-
return getReabstractionOutputLoweredType();
301+
return LoweredResultType;
320302
}
321303

322304
/// Given that this conversion is not one of the specialized bridging

lib/SILGen/SILGenConvert.cpp

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,8 +1258,8 @@ ManagedValue Conversion::emit(SILGenFunction &SGF, SILLocation loc,
12581258
case AnyErasure:
12591259
case BridgingSubtype:
12601260
case Subtype:
1261-
return SGF.emitTransformedValue(loc, value, getBridgingSourceType(),
1262-
getBridgingResultType(), C);
1261+
return SGF.emitTransformedValue(loc, value, getSourceType(),
1262+
getResultType(), C);
12631263

12641264
case ForceOptional: {
12651265
auto &optTL = SGF.getTypeLowering(value.getType());
@@ -1270,32 +1270,30 @@ ManagedValue Conversion::emit(SILGenFunction &SGF, SILLocation loc,
12701270

12711271
case BridgeToObjC:
12721272
return SGF.emitNativeToBridgedValue(loc, value,
1273-
getBridgingSourceType(),
1274-
getBridgingResultType(),
1275-
getBridgingLoweredResultType(), C);
1273+
getSourceType(),
1274+
getResultType(),
1275+
getLoweredResultType(), C);
12761276

12771277
case ForceAndBridgeToObjC: {
12781278
auto &tl = SGF.getTypeLowering(value.getType());
1279-
auto sourceValueType = getBridgingSourceType().getOptionalObjectType();
1279+
auto sourceValueType = getSourceType().getOptionalObjectType();
12801280
value = SGF.emitCheckedGetOptionalValueFrom(loc, value,
12811281
/*isImplicitUnwrap*/ true,
12821282
tl, SGFContext());
12831283
return SGF.emitNativeToBridgedValue(loc, value, sourceValueType,
1284-
getBridgingResultType(),
1285-
getBridgingLoweredResultType(), C);
1284+
getResultType(),
1285+
getLoweredResultType(), C);
12861286
}
12871287

12881288
case BridgeFromObjC:
12891289
return SGF.emitBridgedToNativeValue(loc, value,
1290-
getBridgingSourceType(),
1291-
getBridgingResultType(),
1292-
getBridgingLoweredResultType(), C);
1290+
getSourceType(), getResultType(),
1291+
getLoweredResultType(), C);
12931292

12941293
case BridgeResultFromObjC:
12951294
return SGF.emitBridgedToNativeValue(loc, value,
1296-
getBridgingSourceType(),
1297-
getBridgingResultType(),
1298-
getBridgingLoweredResultType(), C,
1295+
getSourceType(), getResultType(),
1296+
getLoweredResultType(), C,
12991297
/*isResult*/ true);
13001298

13011299
case Reabstract:
@@ -1328,9 +1326,9 @@ Conversion::adjustForInitialOptionalInjection() const {
13281326
case Subtype:
13291327
return OptionalInjectionConversion::forValue(
13301328
getSubtype(
1331-
getBridgingSourceType().getOptionalObjectType(),
1332-
getBridgingResultType().getOptionalObjectType(),
1333-
getBridgingLoweredResultType().getOptionalObjectType())
1329+
getSourceType().getOptionalObjectType(),
1330+
getResultType().getOptionalObjectType(),
1331+
getLoweredResultType().getOptionalObjectType())
13341332
);
13351333

13361334
// TODO: can these actually happen?
@@ -1344,9 +1342,8 @@ Conversion::adjustForInitialOptionalInjection() const {
13441342
case BridgeFromObjC:
13451343
case BridgeResultFromObjC:
13461344
return OptionalInjectionConversion::forInjection(
1347-
getBridging(getKind(), getBridgingSourceType().getOptionalObjectType(),
1348-
getBridgingResultType(),
1349-
getBridgingLoweredResultType(),
1345+
getBridging(getKind(), getSourceType().getOptionalObjectType(),
1346+
getResultType(), getLoweredResultType(),
13501347
isBridgingExplicit())
13511348
);
13521349
}
@@ -1371,8 +1368,7 @@ Conversion::adjustForInitialOptionalConversions(CanType newSourceType) const {
13711368
case BridgeFromObjC:
13721369
case BridgeResultFromObjC:
13731370
return Conversion::getBridging(getKind(), newSourceType,
1374-
getBridgingResultType(),
1375-
getBridgingLoweredResultType(),
1371+
getResultType(), getLoweredResultType(),
13761372
isBridgingExplicit());
13771373
}
13781374
llvm_unreachable("bad kind");
@@ -1391,12 +1387,10 @@ std::optional<Conversion> Conversion::adjustForInitialForceValue() const {
13911387
return std::nullopt;
13921388

13931389
case BridgeToObjC: {
1394-
auto sourceOptType =
1395-
OptionalType::get(getBridgingSourceType())->getCanonicalType();
1390+
auto sourceOptType = getSourceType().wrapInOptionalType();
13961391
return Conversion::getBridging(ForceAndBridgeToObjC,
1397-
sourceOptType,
1398-
getBridgingResultType(),
1399-
getBridgingLoweredResultType(),
1392+
sourceOptType, getResultType(),
1393+
getLoweredResultType(),
14001394
isBridgingExplicit());
14011395
}
14021396
}
@@ -1428,9 +1422,9 @@ static void printReabstraction(const Conversion &conversion,
14281422
static void printBridging(const Conversion &conversion, llvm::raw_ostream &out,
14291423
StringRef name) {
14301424
out << name << "(from: ";
1431-
conversion.getBridgingSourceType().print(out);
1425+
conversion.getSourceType().print(out);
14321426
out << ", to: ";
1433-
conversion.getBridgingResultType().print(out);
1427+
conversion.getResultType().print(out);
14341428
out << ", explicit: " << conversion.isBridgingExplicit() << ')';
14351429
}
14361430

@@ -1784,7 +1778,7 @@ combineSubtypeIntoReabstract(SILGenFunction &SGF,
17841778
if (!isCombinableConversion(inner, outer))
17851779
return salvageUncombinableConversion(SGF, inner, outer);
17861780

1787-
auto inputSubstType = inner.getBridgingSourceType();
1781+
auto inputSubstType = inner.getSourceType();
17881782
auto inputOrigType = AbstractionPattern(inputSubstType);
17891783
auto inputLoweredTy = SGF.getLoweredType(inputOrigType, inputSubstType);
17901784

@@ -1804,9 +1798,8 @@ combineSubtype(SILGenFunction &SGF,
18041798
return salvageUncombinableConversion(SGF, inner, outer);
18051799

18061800
return CombinedConversions(
1807-
Conversion::getSubtype(inner.getBridgingSourceType(),
1808-
outer.getBridgingResultType(),
1809-
outer.getBridgingLoweredResultType())
1801+
Conversion::getSubtype(inner.getSourceType(), outer.getResultType(),
1802+
outer.getLoweredResultType())
18101803
);
18111804
}
18121805

@@ -1824,9 +1817,9 @@ combineBridging(SILGenFunction &SGF,
18241817
// Otherwise, we can peephole if we understand the resulting conversion
18251818
// and applying the peephole doesn't change semantics.
18261819

1827-
CanType sourceType = inner.getBridgingSourceType();
1828-
CanType intermediateType = inner.getBridgingResultType();
1829-
assert(intermediateType == outer.getBridgingSourceType());
1820+
CanType sourceType = inner.getSourceType();
1821+
CanType intermediateType = inner.getResultType();
1822+
assert(intermediateType == outer.getSourceType());
18301823

18311824
// If we're doing a peephole involving a force, we want to propagate
18321825
// the force to the source value. If it's not in fact optional, that
@@ -1841,9 +1834,9 @@ combineBridging(SILGenFunction &SGF,
18411834
assert(intermediateType);
18421835
}
18431836

1844-
CanType resultType = outer.getBridgingResultType();
1837+
CanType resultType = outer.getResultType();
18451838
SILType loweredSourceTy = SGF.getLoweredType(sourceType);
1846-
SILType loweredResultTy = outer.getBridgingLoweredResultType();
1839+
SILType loweredResultTy = outer.getLoweredResultType();
18471840

18481841
auto applyPeephole = [&](const std::optional<Conversion> &conversion) {
18491842
if (!forced) {
@@ -1854,7 +1847,7 @@ combineBridging(SILGenFunction &SGF,
18541847

18551848
auto forceConversion =
18561849
Conversion::getBridging(Conversion::ForceOptional,
1857-
inner.getBridgingSourceType(), sourceType,
1850+
inner.getSourceType(), sourceType,
18581851
loweredSourceTy);
18591852
if (conversion)
18601853
return CombinedConversions(forceConversion, *conversion);

lib/SILGen/SILGenExpr.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2840,24 +2840,18 @@ wrappedValueAutoclosurePlaceholder(const AbstractClosureExpr *e) {
28402840
static std::optional<FunctionTypeInfo>
28412841
tryGetSpecializedClosureTypeFromContext(CanAnyFunctionType closureType,
28422842
const Conversion &conv) {
2843-
if (conv.getKind() == Conversion::Reabstract) {
2843+
// Note that the kinds of conversion we work on here have to be kinds
2844+
// that we can call withSourceType on later.
2845+
if (conv.getKind() == Conversion::Reabstract ||
2846+
conv.getKind() == Conversion::Subtype) {
28442847
// We don't care about the input type here; we'll be emitting that
28452848
// based on the closure.
2846-
auto destType =
2847-
cast<AnyFunctionType>(conv.getReabstractionOutputSubstType());
2849+
auto destType = cast<AnyFunctionType>(conv.getResultType());
28482850
auto origType =
2849-
conv.getReabstractionOutputOrigType();
2850-
auto expectedTy =
2851-
conv.getReabstractionOutputLoweredType().castTo<SILFunctionType>();
2852-
return FunctionTypeInfo{origType, destType, expectedTy};
2853-
}
2854-
2855-
if (conv.getKind() == Conversion::Subtype) {
2856-
assert(closureType == conv.getBridgingSourceType());
2857-
auto destType = cast<AnyFunctionType>(conv.getBridgingResultType());
2858-
auto origType = AbstractionPattern(destType);
2859-
auto expectedTy =
2860-
conv.getBridgingLoweredResultType().castTo<SILFunctionType>();
2851+
conv.getKind() == Conversion::Reabstract
2852+
? conv.getReabstractionOutputOrigType()
2853+
: AbstractionPattern(destType);
2854+
auto expectedTy = conv.getLoweredResultType().castTo<SILFunctionType>();
28612855
return FunctionTypeInfo{origType, destType, expectedTy};
28622856
}
28632857

0 commit comments

Comments
 (0)