@@ -1074,6 +1074,69 @@ ConvertingInitialization::finishEmission(SILGenFunction &SGF,
10741074 llvm_unreachable (" bad state" );
10751075}
10761076
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+
10771140bool ConvertingInitialization::tryPeephole (SILGenFunction &SGF,
10781141 SILLocation loc,
10791142 ManagedValue origValue,
@@ -1104,6 +1167,15 @@ bool ConvertingInitialization::tryPeephole(SILGenFunction &SGF, SILLocation loc,
11041167 ManagedValue value = emitPeepholedConversions (SGF, loc, outerConversion,
11051168 innerConversion, *hint,
11061169 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+ }
11071179 setConvertedValue (value);
11081180 return true ;
11091181}
@@ -1117,15 +1189,11 @@ void ConvertingInitialization::copyOrInitValueInto(SILGenFunction &SGF,
11171189 // TODO: take advantage of borrowed inputs?
11181190 if (!isInit) formalValue = formalValue.copy (SGF, loc);
11191191 State = Initialized;
1120- SGFContext emissionContext = OwnedSubInitialization
1121- ? SGFContext () : FinalContext;
11221192
1123- Value = TheConversion.emit (SGF, loc, formalValue, emissionContext );
1193+ Value = TheConversion.emit (SGF, loc, formalValue, FinalContext );
11241194
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 ());
11291197 Value = ManagedValue::forInContext ();
11301198 }
11311199}
@@ -1512,65 +1580,3 @@ Lowering::canPeepholeConversions(SILGenFunction &SGF,
15121580 llvm_unreachable (" bad kind" );
15131581}
15141582
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