@@ -1074,6 +1074,69 @@ ConvertingInitialization::finishEmission(SILGenFunction &SGF,
1074
1074
llvm_unreachable (" bad state" );
1075
1075
}
1076
1076
1077
+ static ManagedValue
1078
+ emitPeepholedConversions (SILGenFunction &SGF, SILLocation loc,
1079
+ const Conversion &outerConversion,
1080
+ const Conversion &innerConversion,
1081
+ ConversionPeepholeHint hint,
1082
+ SGFContext C,
1083
+ ValueProducerRef produceOrigValue) {
1084
+ auto produceValue = [&](SGFContext C) {
1085
+ if (!hint.isForced ()) {
1086
+ return produceOrigValue (SGF, loc, C);
1087
+ }
1088
+
1089
+ auto value = produceOrigValue (SGF, loc, SGFContext ());
1090
+ auto &optTL = SGF.getTypeLowering (value.getType ());
1091
+ // isForceUnwrap is hardcoded true because hint.isForced() is only
1092
+ // set by implicit force unwraps.
1093
+ return SGF.emitCheckedGetOptionalValueFrom (loc, value,
1094
+ /* isForceUnwrap*/ true ,
1095
+ optTL, C);
1096
+ };
1097
+
1098
+ auto getBridgingSourceType = [&] {
1099
+ CanType sourceType = innerConversion.getBridgingSourceType ();
1100
+ if (hint.isForced ())
1101
+ sourceType = sourceType.getOptionalObjectType ();
1102
+ return sourceType;
1103
+ };
1104
+ auto getBridgingResultType = [&] {
1105
+ return outerConversion.getBridgingResultType ();
1106
+ };
1107
+ auto getBridgingLoweredResultType = [&] {
1108
+ return outerConversion.getBridgingLoweredResultType ();
1109
+ };
1110
+
1111
+ switch (hint.getKind ()) {
1112
+ case ConversionPeepholeHint::Identity:
1113
+ return produceValue (C);
1114
+
1115
+ case ConversionPeepholeHint::BridgeToAnyObject: {
1116
+ auto value = produceValue (SGFContext ());
1117
+ return SGF.emitNativeToBridgedValue (loc, value, getBridgingSourceType (),
1118
+ getBridgingResultType (),
1119
+ getBridgingLoweredResultType (), C);
1120
+ }
1121
+
1122
+ case ConversionPeepholeHint::Subtype: {
1123
+ // Otherwise, emit and convert.
1124
+ // TODO: if the context allows +0, use it in more situations.
1125
+ auto value = produceValue (SGFContext ());
1126
+ SILType loweredResultTy = getBridgingLoweredResultType ();
1127
+
1128
+ // Nothing to do if the value already has the right representation.
1129
+ if (value.getType ().getObjectType () == loweredResultTy.getObjectType ())
1130
+ return value;
1131
+
1132
+ CanType sourceType = getBridgingSourceType ();
1133
+ CanType resultType = getBridgingResultType ();
1134
+ return SGF.emitTransformedValue (loc, value, sourceType, resultType, C);
1135
+ }
1136
+ }
1137
+ llvm_unreachable (" bad kind" );
1138
+ }
1139
+
1077
1140
bool ConvertingInitialization::tryPeephole (SILGenFunction &SGF,
1078
1141
SILLocation loc,
1079
1142
ManagedValue origValue,
@@ -1104,6 +1167,15 @@ bool ConvertingInitialization::tryPeephole(SILGenFunction &SGF, SILLocation loc,
1104
1167
ManagedValue value = emitPeepholedConversions (SGF, loc, outerConversion,
1105
1168
innerConversion, *hint,
1106
1169
FinalContext, produceValue);
1170
+
1171
+ // The callers to tryPeephole assume that the initialization is ready to be
1172
+ // finalized after returning. If this conversion sits on top of another
1173
+ // initialization, forward the value into the underlying initialization and
1174
+ // report the value as emitted in context.
1175
+ if (FinalContext.getEmitInto () && !value.isInContext ()) {
1176
+ value.ensurePlusOne (SGF, loc).forwardInto (SGF, loc, FinalContext.getEmitInto ());
1177
+ value = ManagedValue::forInContext ();
1178
+ }
1107
1179
setConvertedValue (value);
1108
1180
return true ;
1109
1181
}
@@ -1117,15 +1189,11 @@ void ConvertingInitialization::copyOrInitValueInto(SILGenFunction &SGF,
1117
1189
// TODO: take advantage of borrowed inputs?
1118
1190
if (!isInit) formalValue = formalValue.copy (SGF, loc);
1119
1191
State = Initialized;
1120
- SGFContext emissionContext = OwnedSubInitialization
1121
- ? SGFContext () : FinalContext;
1122
1192
1123
- Value = TheConversion.emit (SGF, loc, formalValue, emissionContext );
1193
+ Value = TheConversion.emit (SGF, loc, formalValue, FinalContext );
1124
1194
1125
- if (OwnedSubInitialization) {
1126
- OwnedSubInitialization->copyOrInitValueInto (SGF, loc,
1127
- Value,
1128
- isInit);
1195
+ if (FinalContext.getEmitInto () && !Value.isInContext ()) {
1196
+ Value.forwardInto (SGF, loc, FinalContext.getEmitInto ());
1129
1197
Value = ManagedValue::forInContext ();
1130
1198
}
1131
1199
}
@@ -1512,65 +1580,3 @@ Lowering::canPeepholeConversions(SILGenFunction &SGF,
1512
1580
llvm_unreachable (" bad kind" );
1513
1581
}
1514
1582
1515
- ManagedValue
1516
- Lowering::emitPeepholedConversions (SILGenFunction &SGF, SILLocation loc,
1517
- const Conversion &outerConversion,
1518
- const Conversion &innerConversion,
1519
- ConversionPeepholeHint hint,
1520
- SGFContext C,
1521
- ValueProducerRef produceOrigValue) {
1522
- auto produceValue = [&](SGFContext C) {
1523
- if (!hint.isForced ()) {
1524
- return produceOrigValue (SGF, loc, C);
1525
- }
1526
-
1527
- auto value = produceOrigValue (SGF, loc, SGFContext ());
1528
- auto &optTL = SGF.getTypeLowering (value.getType ());
1529
- // isForceUnwrap is hardcoded true because hint.isForced() is only
1530
- // set by implicit force unwraps.
1531
- return SGF.emitCheckedGetOptionalValueFrom (loc, value,
1532
- /* isForceUnwrap*/ true ,
1533
- optTL, C);
1534
- };
1535
-
1536
- auto getBridgingSourceType = [&] {
1537
- CanType sourceType = innerConversion.getBridgingSourceType ();
1538
- if (hint.isForced ())
1539
- sourceType = sourceType.getOptionalObjectType ();
1540
- return sourceType;
1541
- };
1542
- auto getBridgingResultType = [&] {
1543
- return outerConversion.getBridgingResultType ();
1544
- };
1545
- auto getBridgingLoweredResultType = [&] {
1546
- return outerConversion.getBridgingLoweredResultType ();
1547
- };
1548
-
1549
- switch (hint.getKind ()) {
1550
- case ConversionPeepholeHint::Identity:
1551
- return produceValue (C);
1552
-
1553
- case ConversionPeepholeHint::BridgeToAnyObject: {
1554
- auto value = produceValue (SGFContext ());
1555
- return SGF.emitNativeToBridgedValue (loc, value, getBridgingSourceType (),
1556
- getBridgingResultType (),
1557
- getBridgingLoweredResultType (), C);
1558
- }
1559
-
1560
- case ConversionPeepholeHint::Subtype: {
1561
- // Otherwise, emit and convert.
1562
- // TODO: if the context allows +0, use it in more situations.
1563
- auto value = produceValue (SGFContext ());
1564
- SILType loweredResultTy = getBridgingLoweredResultType ();
1565
-
1566
- // Nothing to do if the value already has the right representation.
1567
- if (value.getType ().getObjectType () == loweredResultTy.getObjectType ())
1568
- return value;
1569
-
1570
- CanType sourceType = getBridgingSourceType ();
1571
- CanType resultType = getBridgingResultType ();
1572
- return SGF.emitTransformedValue (loc, value, sourceType, resultType, C);
1573
- }
1574
- }
1575
- llvm_unreachable (" bad kind" );
1576
- }
0 commit comments