Skip to content

Commit fe7daf4

Browse files
authored
Merge pull request #3261 from jckarter/silgen-bridge-before-eval
2 parents ea848ae + 5e26b56 commit fe7daf4

File tree

1 file changed

+65
-20
lines changed

1 file changed

+65
-20
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,34 +3022,79 @@ namespace {
30223022
void emitDirect(ArgumentSource &&arg, SILType loweredSubstArgType,
30233023
AbstractionPattern origParamType,
30243024
SILParameterInfo param) {
3025-
auto contexts = getRValueEmissionContexts(loweredSubstArgType, param);
3026-
if (arg.isRValue()) {
3027-
emitDirect(arg.getKnownRValueLocation(), std::move(arg).asKnownRValue(),
3028-
origParamType, param, contexts.ForReabstraction);
3029-
} else {
3030-
Expr *e = std::move(arg).asKnownExpr();
3031-
emitDirect(e, SGF.emitRValue(e, contexts.ForEmission),
3032-
origParamType, param, contexts.ForReabstraction);
3033-
}
3034-
}
3035-
3036-
void emitDirect(SILLocation loc, RValue &&arg,
3037-
AbstractionPattern origParamType,
3038-
SILParameterInfo param, SGFContext ctxt) {
3039-
auto value = std::move(arg).getScalarValue();
3025+
ManagedValue value;
3026+
30403027
switch (getSILFunctionLanguage(Rep)) {
30413028
case SILFunctionLanguage::Swift:
3042-
value = SGF.emitSubstToOrigValue(loc, value, origParamType,
3043-
arg.getType(), ctxt);
3029+
value = emitSubstToOrigArgument(std::move(arg), loweredSubstArgType,
3030+
origParamType, param);
30443031
break;
30453032
case SILFunctionLanguage::C:
3046-
value = SGF.emitNativeToBridgedValue(loc, value, Rep,
3047-
param.getType());
3033+
value = emitNativeToBridgedArgument(std::move(arg), loweredSubstArgType,
3034+
origParamType, param);
30483035
break;
30493036
}
30503037
Args.push_back(value);
30513038
}
3052-
3039+
3040+
ManagedValue emitSubstToOrigArgument(ArgumentSource &&arg,
3041+
SILType loweredSubstArgType,
3042+
AbstractionPattern origParamType,
3043+
SILParameterInfo param) {
3044+
// TODO: We should take the opportunity to peephole certain abstraction
3045+
// changes here, for instance, directly emitting a closure literal at the
3046+
// callee's expected abstraction level instead of emitting it maximally
3047+
// substituted and thunking.
3048+
auto emitted = emitArgumentFromSource(std::move(arg), loweredSubstArgType,
3049+
origParamType, param);
3050+
return SGF.emitSubstToOrigValue(emitted.loc,
3051+
std::move(emitted.value).getScalarValue(),
3052+
origParamType, emitted.value.getType(),
3053+
emitted.contextForReabstraction);
3054+
}
3055+
3056+
ManagedValue emitNativeToBridgedArgument(ArgumentSource &&arg,
3057+
SILType loweredSubstArgType,
3058+
AbstractionPattern origParamType,
3059+
SILParameterInfo param) {
3060+
// TODO: We should take the opportunity to peephole certain sequences
3061+
// here. For instance, when going from concrete type -> Any -> id, we
3062+
// can skip the intermediate 'Any' boxing and directly bridge the concrete
3063+
// type to its object representation. Similarly, when bridging from
3064+
// NSFoo -> Foo -> NSFoo, we should elide the bridge altogether and pass
3065+
// the original object.
3066+
auto emitted = emitArgumentFromSource(std::move(arg), loweredSubstArgType,
3067+
origParamType, param);
3068+
3069+
return SGF.emitNativeToBridgedValue(emitted.loc,
3070+
std::move(emitted.value).getScalarValue(),
3071+
Rep, param.getType());
3072+
3073+
}
3074+
3075+
struct EmittedArgument {
3076+
SILLocation loc;
3077+
RValue value;
3078+
SGFContext contextForReabstraction;
3079+
};
3080+
EmittedArgument emitArgumentFromSource(ArgumentSource &&arg,
3081+
SILType loweredSubstArgType,
3082+
AbstractionPattern origParamType,
3083+
SILParameterInfo param) {
3084+
auto contexts = getRValueEmissionContexts(loweredSubstArgType, param);
3085+
Optional<SILLocation> loc;
3086+
RValue rv;
3087+
if (arg.isRValue()) {
3088+
loc = arg.getKnownRValueLocation();
3089+
rv = std::move(arg).asKnownRValue();
3090+
} else {
3091+
Expr *e = std::move(arg).asKnownExpr();
3092+
loc = e;
3093+
rv = SGF.emitRValue(e, contexts.ForEmission);
3094+
}
3095+
return {*loc, std::move(rv), contexts.ForReabstraction};
3096+
}
3097+
30533098
void maybeEmitForeignErrorArgument() {
30543099
if (!ForeignError ||
30553100
ForeignError->getErrorParameterIndex() != Args.size())

0 commit comments

Comments
 (0)