Skip to content

Commit 7a848d2

Browse files
authored
Merge pull request swiftlang#36315 from slavapestov/uncurried-cleanup
SILGen: Eliminate 'uncurriedSites' from SILGenApply.cpp
2 parents 2d4198f + 047a05d commit 7a848d2

File tree

2 files changed

+57
-75
lines changed

2 files changed

+57
-75
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3135,7 +3135,7 @@ static bool isImporterGeneratedAccessor(const clang::Decl *clangDecl,
31353135
return false;
31363136

31373137
// Must be a type member.
3138-
if (constant.getParameterListCount() != 2)
3138+
if (!accessor->hasImplicitSelfDecl())
31393139
return false;
31403140

31413141
// Must be imported from a function.

lib/SILGen/SILGenApply.cpp

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -504,24 +504,6 @@ class Callee {
504504
return SubstFormalInterfaceType;
505505
}
506506

507-
unsigned getParameterListCount() const {
508-
switch (kind) {
509-
case Kind::IndirectValue:
510-
return 1;
511-
512-
case Kind::StandaloneFunction:
513-
case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
514-
case Kind::EnumElement:
515-
case Kind::ClassMethod:
516-
case Kind::SuperMethod:
517-
case Kind::WitnessMethod:
518-
case Kind::DynamicMethod:
519-
return Constant.getParameterListCount();
520-
}
521-
522-
llvm_unreachable("Unhandled Kind in switch.");
523-
}
524-
525507
bool requiresSelfValueForDispatch() const {
526508
switch (kind) {
527509
case Kind::IndirectValue:
@@ -847,22 +829,23 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
847829
selfParam = std::move(theSelfParam);
848830
}
849831

850-
bool isSelfApplyOfMethod(ApplyExpr *e) {
851-
if (auto *selfApply = dyn_cast<ApplyExpr>(e->getFn())) {
852-
if (auto *declRefExpr = dyn_cast<DeclRefExpr>(selfApply->getFn()))
853-
return declRefExpr->getDecl()->getNumCurryLevels() == 2;
854-
855-
if (isa<OtherConstructorDeclRefExpr>(selfApply->getFn()))
856-
return true;
857-
}
858-
859-
return false;
832+
bool isMethodSelfApply(Expr *e) {
833+
return (isa<SelfApplyExpr>(e) &&
834+
!isa<AutoClosureExpr>(
835+
cast<SelfApplyExpr>(e)->getFn()));
860836
}
861837

862838
void decompose(ApplyExpr *e) {
839+
if (isMethodSelfApply(e)) {
840+
selfApply = e;
841+
842+
visit(selfApply->getFn());
843+
return;
844+
}
845+
863846
callSite = e;
864847

865-
if (isSelfApplyOfMethod(e)) {
848+
if (isMethodSelfApply(e->getFn())) {
866849
selfApply = cast<ApplyExpr>(e->getFn());
867850

868851
if (selfApply->isSuper()) {
@@ -3659,10 +3642,11 @@ namespace {
36593642
class CallEmission {
36603643
SILGenFunction &SGF;
36613644

3662-
std::vector<CallSite> uncurriedSites;
3645+
Optional<CallSite> selfArg;
3646+
Optional<CallSite> callSite;
3647+
36633648
Callee callee;
36643649
FormalEvaluationScope initialWritebackScope;
3665-
unsigned expectedSiteCount;
36663650
bool implicitlyAsync;
36673651

36683652
public:
@@ -3671,7 +3655,6 @@ class CallEmission {
36713655
FormalEvaluationScope &&writebackScope)
36723656
: SGF(SGF), callee(std::move(callee)),
36733657
initialWritebackScope(std::move(writebackScope)),
3674-
expectedSiteCount(callee.getParameterListCount()),
36753658
implicitlyAsync(false) {}
36763659

36773660
/// A factory method for decomposing the apply expr \p e into a call
@@ -3682,8 +3665,8 @@ class CallEmission {
36823665
/// unevaluated arguments and their formal type.
36833666
void addCallSite(CallSite &&site) {
36843667
// Append to the main argument list if we have uncurry levels remaining.
3685-
assert(uncurriedSites.size() < expectedSiteCount);
3686-
uncurriedSites.push_back(std::move(site));
3668+
assert(!callSite.hasValue());
3669+
callSite = std::move(site);
36873670
}
36883671

36893672
/// Add a level of function application by passing in its possibly
@@ -3694,12 +3677,14 @@ class CallEmission {
36943677
}
36953678

36963679
void addSelfParam(SILLocation loc,
3697-
ArgumentSource &&selfArg,
3680+
ArgumentSource &&self,
36983681
AnyFunctionType::Param selfParam) {
3682+
assert(!selfArg.hasValue());
3683+
36993684
PreparedArguments preparedSelf(llvm::ArrayRef<AnyFunctionType::Param>{selfParam});
3700-
preparedSelf.addArbitrary(std::move(selfArg));
3685+
preparedSelf.addArbitrary(std::move(self));
37013686

3702-
addCallSite(loc, std::move(preparedSelf));
3687+
selfArg = CallSite(loc, std::move(preparedSelf));
37033688
}
37043689

37053690
/// Is this a fully-applied enum element constructor call?
@@ -3860,8 +3845,6 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
38603845
}
38613846

38623847
RValue CallEmission::applyFirstLevelCallee(SGFContext C) {
3863-
assert(uncurriedSites.size() == expectedSiteCount);
3864-
38653848
// Check for a specialized emitter.
38663849
if (auto emitter = callee.getSpecializedEmitter(SGF.SGM)) {
38673850
return applySpecializedEmitter(emitter.getValue(), C);
@@ -3882,9 +3865,6 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
38823865
auto formalType = callee.getSubstFormalType();
38833866
auto origFormalType = callee.getOrigFormalType();
38843867

3885-
bool isCurried = (uncurriedSites.size() < callee.getParameterListCount());
3886-
assert(!isCurried);
3887-
38883868
// Get the callee type information.
38893869
auto calleeTypeInfo = callee.getTypeInfo(SGF);
38903870

@@ -3904,17 +3884,17 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
39043884
calleeTypeInfo.origResultType = origFormalType.getFunctionResultType();
39053885
calleeTypeInfo.substResultType = formalType.getResult();
39063886

3907-
if (uncurriedSites.size() == 2) {
3887+
if (selfArg.hasValue() && callSite.hasValue()) {
39083888
calleeTypeInfo.origResultType =
39093889
calleeTypeInfo.origResultType->getFunctionResultType();
39103890
calleeTypeInfo.substResultType =
39113891
cast<FunctionType>(calleeTypeInfo.substResultType).getResult();
39123892
}
39133893

39143894
ResultPlanPtr resultPlan = ResultPlanBuilder::computeResultPlan(
3915-
SGF, calleeTypeInfo, uncurriedSites.back().Loc, uncurriedContext);
3895+
SGF, calleeTypeInfo, callSite->Loc, uncurriedContext);
39163896

3917-
ArgumentScope argScope(SGF, uncurriedSites.back().Loc);
3897+
ArgumentScope argScope(SGF, callSite->Loc);
39183898

39193899
// Emit the arguments.
39203900
SmallVector<ManagedValue, 4> uncurriedArgs;
@@ -3970,7 +3950,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
39703950
// construction.
39713951
EnumElementDecl *element = callee.getEnumElementDecl();
39723952

3973-
SILLocation uncurriedLoc = uncurriedSites[0].Loc;
3953+
SILLocation uncurriedLoc = selfArg->Loc;
39743954

39753955
origFormalType = origFormalType.getFunctionResultType();
39763956
CanType formalResultType = formalType.getResult();
@@ -3980,21 +3960,20 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
39803960
emitPseudoFunctionArguments(SGF,
39813961
AbstractionPattern(formalType),
39823962
formalType, metatypeVal,
3983-
std::move(uncurriedSites[0]).forward());
3963+
std::move(*selfArg).forward());
39843964
assert(metatypeVal.size() == 1);
39853965

39863966

39873967
// Get the payload argument.
39883968
ArgumentSource payload;
39893969
if (element->hasAssociatedValues()) {
3990-
assert(uncurriedSites.size() == 2);
39913970
SmallVector<ManagedValue, 4> argVals;
39923971
auto resultFnType = cast<FunctionType>(formalResultType);
39933972

39943973
emitPseudoFunctionArguments(SGF,
39953974
AbstractionPattern(resultFnType),
39963975
resultFnType, argVals,
3997-
std::move(uncurriedSites[1]).forward());
3976+
std::move(*callSite).forward());
39983977

39993978
auto payloadTy = AnyFunctionType::composeInput(SGF.getASTContext(),
40003979
resultFnType.getParams(),
@@ -4004,7 +3983,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
40043983
formalResultType = cast<FunctionType>(formalResultType).getResult();
40053984
origFormalType = origFormalType.getFunctionResultType();
40063985
} else {
4007-
assert(uncurriedSites.size() == 1);
3986+
assert(!callSite.hasValue());
40083987
}
40093988

40103989
ManagedValue resultMV = SGF.emitInjectEnum(
@@ -4038,13 +4017,13 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
40384017
if (specializedEmitter.isEarlyEmitter()) {
40394018
auto emitter = specializedEmitter.getEarlyEmitter();
40404019

4041-
assert(uncurriedSites.size() == 1);
4020+
assert(!selfArg.hasValue());
40424021
assert(!formalType->getExtInfo().isThrowing());
4043-
SILLocation uncurriedLoc = uncurriedSites[0].Loc;
4022+
SILLocation uncurriedLoc = callSite->Loc;
40444023

40454024
// We should be able to enforce that these arguments are
40464025
// always still expressions.
4047-
PreparedArguments args = std::move(uncurriedSites[0]).forward();
4026+
PreparedArguments args = std::move(*callSite).forward();
40484027
ManagedValue resultMV =
40494028
emitter(SGF, uncurriedLoc, callee.getSubstitutions(),
40504029
std::move(args), uncurriedContext);
@@ -4054,7 +4033,7 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
40544033
Optional<ResultPlanPtr> resultPlan;
40554034
Optional<ArgumentScope> argScope;
40564035
Optional<CalleeTypeInfo> calleeTypeInfo;
4057-
SILLocation loc = uncurriedSites[0].Loc;
4036+
SILLocation loc = callSite->Loc;
40584037
SILFunctionConventions substConv(substFnType, SGF.SGM.M);
40594038

40604039
// If we have a named builtin and have an indirect out parameter, compute a
@@ -4148,18 +4127,18 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
41484127
SmallVector<SmallVector<ManagedValue, 4>, 2> args;
41494128
SmallVector<DelayedArgument, 2> delayedArgs;
41504129

4151-
args.reserve(uncurriedSites.size());
4130+
args.reserve(selfArg.hasValue() ? 2 : 1);
41524131
{
41534132
ParamLowering paramLowering(substFnType, SGF);
41544133

41554134
assert((!foreign.error && !foreign.async)
4156-
|| uncurriedSites.size() == 1
4157-
|| (uncurriedSites.size() == 2 && substFnType->hasSelfParam()));
4135+
|| !selfArg.hasValue()
4136+
|| (selfArg.hasValue() && substFnType->hasSelfParam()));
41584137

4159-
if (uncurriedSites.back().isNoThrows()) {
4138+
if (callSite->isNoThrows()) {
41604139
options |= ApplyFlags::DoesNotThrow;
41614140
}
4162-
if (uncurriedSites.back().isNoAsync()) {
4141+
if (callSite->isNoAsync()) {
41634142
options |= ApplyFlags::DoesNotAwait;
41644143
}
41654144

@@ -4172,27 +4151,30 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
41724151
}
41734152

41744153
// Collect the arguments to the uncurried call.
4175-
for (auto &site : uncurriedSites) {
4176-
uncurriedLoc = site.Loc;
4154+
if (selfArg.hasValue()) {
41774155
args.push_back({});
4178-
4179-
bool isParamSite = &site == &uncurriedSites.back();
41804156

4181-
auto siteForeign = isParamSite
4182-
// Claim the foreign error and/or async argument(s) with the method
4183-
// formal params.
4184-
? CalleeTypeInfo::ForeignInfo{foreign.error, foreign.async, {}}
4185-
// Claim the foreign "self" with the self param.
4186-
: CalleeTypeInfo::ForeignInfo{{}, {}, foreign.self};
4187-
4188-
std::move(site).emit(SGF, origFormalType, substFnType, paramLowering,
4189-
args.back(), delayedArgs,
4190-
siteForeign);
4157+
// Claim the foreign "self" with the self param.
4158+
auto siteForeign = CalleeTypeInfo::ForeignInfo{{}, {}, foreign.self};
4159+
std::move(*selfArg).emit(SGF, origFormalType, substFnType, paramLowering,
4160+
args.back(), delayedArgs,
4161+
siteForeign);
41914162

41924163
origFormalType = origFormalType.getFunctionResultType();
41934164
}
4165+
4166+
args.push_back({});
4167+
4168+
// Claim the foreign error and/or async argument(s) with the method
4169+
// formal params.
4170+
auto siteForeign =
4171+
CalleeTypeInfo::ForeignInfo{foreign.error, foreign.async, {}};
4172+
std::move(*callSite).emit(SGF, origFormalType, substFnType, paramLowering,
4173+
args.back(), delayedArgs,
4174+
siteForeign);
41944175
}
4195-
assert(uncurriedLoc);
4176+
4177+
uncurriedLoc = callSite->Loc;
41964178

41974179
// Emit any delayed arguments: formal accesses to inout arguments, etc.
41984180
if (!delayedArgs.empty()) {

0 commit comments

Comments
 (0)