Skip to content

Commit 8462493

Browse files
committed
SILGen: Avoid passing an expression to emitDynamicSubscriptExpr
1 parent c23b9a4 commit 8462493

File tree

3 files changed

+63
-40
lines changed

3 files changed

+63
-40
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6255,17 +6255,14 @@ RValue SILGenFunction::emitDynamicMemberRef(SILLocation loc, SILValue operand,
62556255
emitManagedRValueWithCleanup(optResult, optTL));
62566256
}
62576257

6258-
RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e,
6258+
RValue
6259+
SILGenFunction::emitDynamicSubscriptGetterApply(SILLocation loc,
6260+
SILValue operand,
6261+
ConcreteDeclRef subscriptRef,
6262+
PreparedArguments &&indexArgs,
6263+
CanType resultTy,
62596264
SGFContext c) {
6260-
// Emit the base operand.
6261-
ManagedValue managedBase = emitRValueAsSingleValue(e->getBase());
6262-
6263-
SILValue base = managedBase.getValue();
6264-
6265-
// Emit the index.
6266-
auto *indexExpr = e->getArgs()->getUnaryExpr();
6267-
assert(indexExpr);
6268-
RValue index = emitRValue(indexExpr);
6265+
assert(resultTy->isOptional());
62696266

62706267
// Create the continuation block.
62716268
SILBasicBlock *contBB = createBasicBlock();
@@ -6276,72 +6273,77 @@ RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e,
62766273
// Create the has-member block.
62776274
SILBasicBlock *hasMemberBB = createBasicBlock();
62786275

6279-
const TypeLowering &optTL = getTypeLowering(e->getType());
6280-
auto loweredOptTy = optTL.getLoweredType();
6281-
SILValue optTemp = emitTemporaryAllocation(e, loweredOptTy);
6276+
const TypeLowering &optTL = getTypeLowering(resultTy);
6277+
const SILValue optTemp = emitTemporaryAllocation(loc, optTL.getLoweredType());
62826278

62836279
// Create the branch.
6284-
auto subscriptDecl = cast<SubscriptDecl>(e->getMember().getDecl());
6280+
auto *subscriptDecl = cast<SubscriptDecl>(subscriptRef.getDecl());
62856281
auto member = SILDeclRef(subscriptDecl->getOpaqueAccessor(AccessorKind::Get),
62866282
SILDeclRef::Kind::Func)
62876283
.asForeign();
6288-
B.createDynamicMethodBranch(e, base, member, hasMemberBB, noMemberBB);
6284+
B.createDynamicMethodBranch(loc, operand, member, hasMemberBB, noMemberBB);
62896285

62906286
// Create the has-member branch.
62916287
{
62926288
B.emitBlock(hasMemberBB);
62936289

6294-
FullExpr hasMemberScope(Cleanups, CleanupLocation(e));
6290+
FullExpr hasMemberScope(Cleanups, CleanupLocation(loc));
62956291

62966292
// The argument to the has-member block is the uncurried method.
62976293
// Build the substituted getter type from the AST nodes.
6298-
auto valueTy = e->getType()->getCanonicalType().getOptionalObjectType();
6294+
const CanType valueTy = resultTy.getOptionalObjectType();
62996295

6300-
// Objective-C subscripts only ever have a single parameter.
6301-
//
63026296
// FIXME: Verify ExtInfo state is correct, not working by accident.
63036297
CanFunctionType::ExtInfo methodInfo;
6304-
FunctionType::Param indexArg(indexExpr->getType()->getCanonicalType());
6305-
auto methodTy = CanFunctionType::get({indexArg}, valueTy, methodInfo);
6298+
const auto methodTy =
6299+
CanFunctionType::get(indexArgs.getParams(), valueTy, methodInfo);
63066300
auto foreignMethodTy =
6307-
getPartialApplyOfDynamicMethodFormalType(SGM, member, e->getMember());
6301+
getPartialApplyOfDynamicMethodFormalType(SGM, member, subscriptRef);
63086302

63096303
// FIXME: Verify ExtInfo state is correct, not working by accident.
63106304
CanFunctionType::ExtInfo functionInfo;
6311-
FunctionType::Param baseArg(base->getType().getASTType());
6305+
FunctionType::Param baseArg(operand->getType().getASTType());
63126306
auto functionTy = CanFunctionType::get({baseArg}, methodTy, functionInfo);
63136307
auto loweredMethodTy = getDynamicMethodLoweredType(SGM.M, member,
63146308
functionTy);
63156309
SILValue memberArg =
63166310
hasMemberBB->createPhiArgument(loweredMethodTy, OwnershipKind::Owned);
63176311
// Emit the application of 'self'.
6318-
Scope applyScope(Cleanups, CleanupLocation(e));
6319-
ManagedValue result = emitDynamicPartialApply(*this, e, memberArg, base,
6320-
foreignMethodTy, methodTy);
6321-
// Emit the index.
6322-
llvm::SmallVector<ManagedValue, 2> indexArgs;
6323-
std::move(index).getAll(indexArgs);
6324-
6325-
auto resultRV = emitMonomorphicApply(e, result, indexArgs,
6312+
Scope applyScope(Cleanups, CleanupLocation(loc));
6313+
ManagedValue result = emitDynamicPartialApply(
6314+
*this, loc, memberArg, operand, foreignMethodTy, methodTy);
6315+
6316+
// Collect the index values for application.
6317+
llvm::SmallVector<ManagedValue, 2> indexValues;
6318+
for (auto &source : std::move(indexArgs).getSources()) {
6319+
// @objc subscripts cannot have 'inout' indices.
6320+
RValue rVal = std::move(source).asKnownRValue(*this);
6321+
6322+
// @objc subscripts cannot have tuple indices.
6323+
indexValues.push_back(std::move(rVal).getScalarValue());
6324+
}
6325+
6326+
auto resultRV = emitMonomorphicApply(loc, result, indexValues,
63266327
foreignMethodTy.getResult(), valueTy,
63276328
ApplyOptions(), None, None);
63286329

63296330
// Package up the result in an optional.
6330-
emitInjectOptionalValueInto(e, {e, std::move(resultRV)}, optTemp, optTL);
6331+
emitInjectOptionalValueInto(loc, {loc, std::move(resultRV)}, optTemp,
6332+
optTL);
63316333

63326334
applyScope.pop();
63336335
// Branch to the continuation block.
6334-
B.createBranch(e, contBB);
6336+
B.createBranch(loc, contBB);
63356337
}
63366338

63376339
// Create the no-member branch.
63386340
{
63396341
B.emitBlock(noMemberBB);
63406342

6341-
emitInjectOptionalNothingInto(e, optTemp, optTL);
6343+
emitInjectOptionalNothingInto(loc, optTemp, optTL);
63426344

63436345
// Branch to the continuation block.
6344-
B.createBranch(e, contBB);
6346+
B.createBranch(loc, contBB);
63456347
}
63466348

63476349
// Emit the continuation block.
@@ -6350,8 +6352,9 @@ RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e,
63506352
// Package up the result.
63516353
auto optResult = optTemp;
63526354
if (optTL.isLoadable())
6353-
optResult = optTL.emitLoad(B, e, optResult, LoadOwnershipQualifier::Take);
6354-
return RValue(*this, e, emitManagedRValueWithCleanup(optResult, optTL));
6355+
optResult = optTL.emitLoad(B, loc, optResult, LoadOwnershipQualifier::Take);
6356+
return RValue(*this, loc, resultTy,
6357+
emitManagedRValueWithCleanup(optResult, optTL));
63556358
}
63566359

63576360
SmallVector<ManagedValue, 4> SILGenFunction::emitKeyPathSubscriptOperands(

lib/SILGen/SILGenExpr.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,24 @@ RValue RValueEmitter::visitDynamicSubscriptExpr(
22482248
DynamicSubscriptExpr *E, SGFContext C) {
22492249
assert(!E->isImplicitlyAsync() && "an actor-isolated @objc member?");
22502250
assert(!E->isImplicitlyThrows() && "an distributed-actor-isolated @objc member?");
2251-
return SGF.emitDynamicSubscriptExpr(E, C);
2251+
2252+
// Emit the base operand.
2253+
SILValue Operand = SGF.emitRValueAsSingleValue(E->getBase()).getValue();
2254+
2255+
// Emit the indices.
2256+
//
2257+
// FIXME: This is apparently not true for Swift @objc subscripts.
2258+
// Objective-C subscripts only ever have a single parameter.
2259+
Expr *IndexExpr = E->getArgs()->getUnaryExpr();
2260+
assert(IndexExpr);
2261+
2262+
PreparedArguments IndexArgs(
2263+
FunctionType::Param(IndexExpr->getType()->getCanonicalType()));
2264+
IndexArgs.add(E, SGF.emitRValue(IndexExpr));
2265+
2266+
return SGF.emitDynamicSubscriptGetterApply(
2267+
E, Operand, E->getMember(), std::move(IndexArgs),
2268+
E->getType()->getCanonicalType(), C);
22522269
}
22532270

22542271

lib/SILGen/SILGenFunction.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,8 +1755,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
17551755
ConcreteDeclRef memberRef, CanType refTy,
17561756
SGFContext C);
17571757

1758-
/// Emit a dynamic subscript.
1759-
RValue emitDynamicSubscriptExpr(DynamicSubscriptExpr *e, SGFContext c);
1758+
/// Emit a dynamic subscript getter application.
1759+
RValue emitDynamicSubscriptGetterApply(SILLocation loc, SILValue operand,
1760+
ConcreteDeclRef subscriptRef,
1761+
PreparedArguments &&indexArgs,
1762+
CanType resultTy, SGFContext C);
17601763

17611764
/// Open up the given existential expression and emit its
17621765
/// subexpression in a caller-specified manner.

0 commit comments

Comments
 (0)