Skip to content

Commit e59936e

Browse files
committed
Simplify the representation of conversions to make it easier to extract
the source/result/lowered-result types.
1 parent f9cc3f4 commit e59936e

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
@@ -1266,8 +1266,8 @@ ManagedValue Conversion::emit(SILGenFunction &SGF, SILLocation loc,
12661266
case AnyErasure:
12671267
case BridgingSubtype:
12681268
case Subtype:
1269-
return SGF.emitTransformedValue(loc, value, getBridgingSourceType(),
1270-
getBridgingResultType(), C);
1269+
return SGF.emitTransformedValue(loc, value, getSourceType(),
1270+
getResultType(), C);
12711271

12721272
case ForceOptional: {
12731273
auto &optTL = SGF.getTypeLowering(value.getType());
@@ -1278,32 +1278,30 @@ ManagedValue Conversion::emit(SILGenFunction &SGF, SILLocation loc,
12781278

12791279
case BridgeToObjC:
12801280
return SGF.emitNativeToBridgedValue(loc, value,
1281-
getBridgingSourceType(),
1282-
getBridgingResultType(),
1283-
getBridgingLoweredResultType(), C);
1281+
getSourceType(),
1282+
getResultType(),
1283+
getLoweredResultType(), C);
12841284

12851285
case ForceAndBridgeToObjC: {
12861286
auto &tl = SGF.getTypeLowering(value.getType());
1287-
auto sourceValueType = getBridgingSourceType().getOptionalObjectType();
1287+
auto sourceValueType = getSourceType().getOptionalObjectType();
12881288
value = SGF.emitCheckedGetOptionalValueFrom(loc, value,
12891289
/*isImplicitUnwrap*/ true,
12901290
tl, SGFContext());
12911291
return SGF.emitNativeToBridgedValue(loc, value, sourceValueType,
1292-
getBridgingResultType(),
1293-
getBridgingLoweredResultType(), C);
1292+
getResultType(),
1293+
getLoweredResultType(), C);
12941294
}
12951295

12961296
case BridgeFromObjC:
12971297
return SGF.emitBridgedToNativeValue(loc, value,
1298-
getBridgingSourceType(),
1299-
getBridgingResultType(),
1300-
getBridgingLoweredResultType(), C);
1298+
getSourceType(), getResultType(),
1299+
getLoweredResultType(), C);
13011300

13021301
case BridgeResultFromObjC:
13031302
return SGF.emitBridgedToNativeValue(loc, value,
1304-
getBridgingSourceType(),
1305-
getBridgingResultType(),
1306-
getBridgingLoweredResultType(), C,
1303+
getSourceType(), getResultType(),
1304+
getLoweredResultType(), C,
13071305
/*isResult*/ true);
13081306

13091307
case Reabstract:
@@ -1336,9 +1334,9 @@ Conversion::adjustForInitialOptionalInjection() const {
13361334
case Subtype:
13371335
return OptionalInjectionConversion::forValue(
13381336
getSubtype(
1339-
getBridgingSourceType().getOptionalObjectType(),
1340-
getBridgingResultType().getOptionalObjectType(),
1341-
getBridgingLoweredResultType().getOptionalObjectType())
1337+
getSourceType().getOptionalObjectType(),
1338+
getResultType().getOptionalObjectType(),
1339+
getLoweredResultType().getOptionalObjectType())
13421340
);
13431341

13441342
// TODO: can these actually happen?
@@ -1352,9 +1350,8 @@ Conversion::adjustForInitialOptionalInjection() const {
13521350
case BridgeFromObjC:
13531351
case BridgeResultFromObjC:
13541352
return OptionalInjectionConversion::forInjection(
1355-
getBridging(getKind(), getBridgingSourceType().getOptionalObjectType(),
1356-
getBridgingResultType(),
1357-
getBridgingLoweredResultType(),
1353+
getBridging(getKind(), getSourceType().getOptionalObjectType(),
1354+
getResultType(), getLoweredResultType(),
13581355
isBridgingExplicit())
13591356
);
13601357
}
@@ -1379,8 +1376,7 @@ Conversion::adjustForInitialOptionalConversions(CanType newSourceType) const {
13791376
case BridgeFromObjC:
13801377
case BridgeResultFromObjC:
13811378
return Conversion::getBridging(getKind(), newSourceType,
1382-
getBridgingResultType(),
1383-
getBridgingLoweredResultType(),
1379+
getResultType(), getLoweredResultType(),
13841380
isBridgingExplicit());
13851381
}
13861382
llvm_unreachable("bad kind");
@@ -1399,12 +1395,10 @@ std::optional<Conversion> Conversion::adjustForInitialForceValue() const {
13991395
return std::nullopt;
14001396

14011397
case BridgeToObjC: {
1402-
auto sourceOptType =
1403-
OptionalType::get(getBridgingSourceType())->getCanonicalType();
1398+
auto sourceOptType = getSourceType().wrapInOptionalType();
14041399
return Conversion::getBridging(ForceAndBridgeToObjC,
1405-
sourceOptType,
1406-
getBridgingResultType(),
1407-
getBridgingLoweredResultType(),
1400+
sourceOptType, getResultType(),
1401+
getLoweredResultType(),
14081402
isBridgingExplicit());
14091403
}
14101404
}
@@ -1436,9 +1430,9 @@ static void printReabstraction(const Conversion &conversion,
14361430
static void printBridging(const Conversion &conversion, llvm::raw_ostream &out,
14371431
StringRef name) {
14381432
out << name << "(from: ";
1439-
conversion.getBridgingSourceType().print(out);
1433+
conversion.getSourceType().print(out);
14401434
out << ", to: ";
1441-
conversion.getBridgingResultType().print(out);
1435+
conversion.getResultType().print(out);
14421436
out << ", explicit: " << conversion.isBridgingExplicit() << ')';
14431437
}
14441438

@@ -1792,7 +1786,7 @@ combineSubtypeIntoReabstract(SILGenFunction &SGF,
17921786
if (!isCombinableConversion(inner, outer))
17931787
return salvageUncombinableConversion(SGF, inner, outer);
17941788

1795-
auto inputSubstType = inner.getBridgingSourceType();
1789+
auto inputSubstType = inner.getSourceType();
17961790
auto inputOrigType = AbstractionPattern(inputSubstType);
17971791
auto inputLoweredTy = SGF.getLoweredType(inputOrigType, inputSubstType);
17981792

@@ -1812,9 +1806,8 @@ combineSubtype(SILGenFunction &SGF,
18121806
return salvageUncombinableConversion(SGF, inner, outer);
18131807

18141808
return CombinedConversions(
1815-
Conversion::getSubtype(inner.getBridgingSourceType(),
1816-
outer.getBridgingResultType(),
1817-
outer.getBridgingLoweredResultType())
1809+
Conversion::getSubtype(inner.getSourceType(), outer.getResultType(),
1810+
outer.getLoweredResultType())
18181811
);
18191812
}
18201813

@@ -1832,9 +1825,9 @@ combineBridging(SILGenFunction &SGF,
18321825
// Otherwise, we can peephole if we understand the resulting conversion
18331826
// and applying the peephole doesn't change semantics.
18341827

1835-
CanType sourceType = inner.getBridgingSourceType();
1836-
CanType intermediateType = inner.getBridgingResultType();
1837-
assert(intermediateType == outer.getBridgingSourceType());
1828+
CanType sourceType = inner.getSourceType();
1829+
CanType intermediateType = inner.getResultType();
1830+
assert(intermediateType == outer.getSourceType());
18381831

18391832
// If we're doing a peephole involving a force, we want to propagate
18401833
// the force to the source value. If it's not in fact optional, that
@@ -1849,9 +1842,9 @@ combineBridging(SILGenFunction &SGF,
18491842
assert(intermediateType);
18501843
}
18511844

1852-
CanType resultType = outer.getBridgingResultType();
1845+
CanType resultType = outer.getResultType();
18531846
SILType loweredSourceTy = SGF.getLoweredType(sourceType);
1854-
SILType loweredResultTy = outer.getBridgingLoweredResultType();
1847+
SILType loweredResultTy = outer.getLoweredResultType();
18551848

18561849
auto applyPeephole = [&](const std::optional<Conversion> &conversion) {
18571850
if (!forced) {
@@ -1862,7 +1855,7 @@ combineBridging(SILGenFunction &SGF,
18621855

18631856
auto forceConversion =
18641857
Conversion::getBridging(Conversion::ForceOptional,
1865-
inner.getBridgingSourceType(), sourceType,
1858+
inner.getSourceType(), sourceType,
18661859
loweredSourceTy);
18671860
if (conversion)
18681861
return CombinedConversions(forceConversion, *conversion);

lib/SILGen/SILGenExpr.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,24 +2853,18 @@ wrappedValueAutoclosurePlaceholder(const AbstractClosureExpr *e) {
28532853
static std::optional<FunctionTypeInfo>
28542854
tryGetSpecializedClosureTypeFromContext(CanAnyFunctionType closureType,
28552855
const Conversion &conv) {
2856-
if (conv.getKind() == Conversion::Reabstract) {
2856+
// Note that the kinds of conversion we work on here have to be kinds
2857+
// that we can call withSourceType on later.
2858+
if (conv.getKind() == Conversion::Reabstract ||
2859+
conv.getKind() == Conversion::Subtype) {
28572860
// We don't care about the input type here; we'll be emitting that
28582861
// based on the closure.
2859-
auto destType =
2860-
cast<AnyFunctionType>(conv.getReabstractionOutputSubstType());
2862+
auto destType = cast<AnyFunctionType>(conv.getResultType());
28612863
auto origType =
2862-
conv.getReabstractionOutputOrigType();
2863-
auto expectedTy =
2864-
conv.getReabstractionOutputLoweredType().castTo<SILFunctionType>();
2865-
return FunctionTypeInfo{origType, destType, expectedTy};
2866-
}
2867-
2868-
if (conv.getKind() == Conversion::Subtype) {
2869-
assert(closureType == conv.getBridgingSourceType());
2870-
auto destType = cast<AnyFunctionType>(conv.getBridgingResultType());
2871-
auto origType = AbstractionPattern(destType);
2872-
auto expectedTy =
2873-
conv.getBridgingLoweredResultType().castTo<SILFunctionType>();
2864+
conv.getKind() == Conversion::Reabstract
2865+
? conv.getReabstractionOutputOrigType()
2866+
: AbstractionPattern(destType);
2867+
auto expectedTy = conv.getLoweredResultType().castTo<SILFunctionType>();
28742868
return FunctionTypeInfo{origType, destType, expectedTy};
28752869
}
28762870

0 commit comments

Comments
 (0)