Skip to content

Commit fb95781

Browse files
committed
Steps towards supporting pack expansions properly in signature
lowering and argument emission. Pack expansions in argument emission don't work yet, but I wanted to land this bit of incremental progress.
1 parent bd53f5d commit fb95781

9 files changed

+1044
-128
lines changed

lib/SIL/IR/SILFunctionType.cpp

+235-92
Large diffs are not rendered by default.

lib/SILGen/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_swift_host_library(swiftSILGen STATIC
2828
SILGenGlobalVariable.cpp
2929
SILGenLazyConformance.cpp
3030
SILGenLValue.cpp
31+
SILGenPack.cpp
3132
SILGenPattern.cpp
3233
SILGenPoly.cpp
3334
SILGenProlog.cpp

lib/SILGen/SILGenApply.cpp

+318-31
Large diffs are not rendered by default.

lib/SILGen/SILGenDecl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ class ReleaseValueCleanup : public Cleanup {
234234
} // end anonymous namespace
235235

236236
namespace {
237-
/// Cleanup to destroy an initialized variable.
237+
/// Cleanup to deallocate a now-uninitialized variable.
238238
class DeallocStackCleanup : public Cleanup {
239239
SILValue Addr;
240240
public:

lib/SILGen/SILGenExpr.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,15 @@ SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty,
10721072
return alloc;
10731073
}
10741074

1075+
SILValue
1076+
SILGenFunction::emitTemporaryPackAllocation(SILLocation loc, SILType ty) {
1077+
assert(ty.is<SILPackType>());
1078+
ty = ty.getObjectType();
1079+
auto *alloc = B.createAllocPack(loc, ty);
1080+
enterDeallocPackCleanup(alloc);
1081+
return alloc;
1082+
}
1083+
10751084
SILValue SILGenFunction::
10761085
getBufferForExprResult(SILLocation loc, SILType ty, SGFContext C) {
10771086
// If you change this, change manageBufferForExprResult below as well.
@@ -3969,7 +3978,8 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
39693978

39703979
auto subscript = cast<SubscriptDecl>(decl);
39713980
auto loweredArgs = SGF.emitKeyPathSubscriptOperands(
3972-
subscript, component.getDeclRef().getSubstitutions(),
3981+
E, subscript,
3982+
component.getDeclRef().getSubstitutions(),
39733983
component.getSubscriptArgs());
39743984

39753985
for (auto &arg : loweredArgs) {

lib/SILGen/SILGenFunction.h

+83-2
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
868868
/// \param subs - Used to get subscript function type and to substitute generic args.
869869
/// \param argList - The argument list of the subscript.
870870
SmallVector<ManagedValue, 4>
871-
emitKeyPathSubscriptOperands(SubscriptDecl *subscript, SubstitutionMap subs,
871+
emitKeyPathSubscriptOperands(SILLocation loc,
872+
SubscriptDecl *subscript,
873+
SubstitutionMap subs,
872874
ArgumentList *argList);
873875

874876
/// Convert a block to a native function with a thunk.
@@ -1139,6 +1141,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
11391141
bool hasDynamicLifetime = false,
11401142
bool isLexical = false);
11411143

1144+
/// Emits a temporary allocation for a pack that will be deallocated
1145+
/// automatically at the end of the current scope. Returns the address
1146+
/// of the allocation.
1147+
SILValue emitTemporaryPackAllocation(SILLocation loc, SILType packTy);
1148+
11421149
/// Prepares a buffer to receive the result of an expression, either using the
11431150
/// 'emit into' initialization buffer if available, or allocating a temporary
11441151
/// allocation if not.
@@ -1537,7 +1544,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
15371544
SubstitutionMap subs,
15381545
bool alreadyConverted);
15391546

1540-
PreparedArguments prepareSubscriptIndices(SubscriptDecl *subscript,
1547+
PreparedArguments prepareSubscriptIndices(SILLocation loc,
1548+
SubscriptDecl *subscript,
15411549
SubstitutionMap subs,
15421550
AccessStrategy strategy,
15431551
ArgumentList *argList);
@@ -2346,10 +2354,24 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
23462354

23472355
/// Enter a cleanup to deallocate a stack variable.
23482356
CleanupHandle enterDeallocStackCleanup(SILValue address);
2357+
2358+
/// Enter a cleanup to deallocate a pack.
2359+
CleanupHandle enterDeallocPackCleanup(SILValue address);
23492360

23502361
/// Enter a cleanup to emit a ReleaseValue/DestroyAddr of the specified value.
23512362
CleanupHandle enterDestroyCleanup(SILValue valueOrAddr);
23522363

2364+
/// Enter a cleanup to destroy all of the values in the given pack.
2365+
CleanupHandle enterDestroyPackCleanup(SILValue addr,
2366+
CanPackType formalPackType);
2367+
2368+
/// Enter a cleanup to destroy the preceding values in a pack-expansion
2369+
/// component of a pack.
2370+
CleanupHandle enterPartialDestroyPackCleanup(SILValue addr,
2371+
CanPackType formalPackType,
2372+
unsigned componentIndex,
2373+
SILValue limitWithinComponent);
2374+
23532375
/// Return an owned managed value for \p value that is cleaned up using an end_lifetime instruction.
23542376
///
23552377
/// The end_lifetime cleanup is not placed into the ManagedValue itself and
@@ -2452,6 +2474,65 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
24522474
SILDeclRef getAccessorDeclRef(AccessorDecl *accessor) {
24532475
return SGM.getAccessorDeclRef(accessor, F.getResilienceExpansion());
24542476
}
2477+
2478+
/// Emit a dynamic loop over a single pack-expansion component of a pack.
2479+
///
2480+
/// \param formalPackType - a pack type with the right shape for the
2481+
/// overall pack being iterated over
2482+
/// \param componentIndex - the index of the pack expansion component
2483+
/// within the formal pack type
2484+
/// \param limitWithinComponent - the number of elements in a prefix of
2485+
/// the expansion component to dynamically visit; if null, all elements
2486+
/// will be visited
2487+
/// \param openedElementEnv - a set of opened element archetypes to bind
2488+
/// within the loop; can be null to bind no elements
2489+
/// \param reverse - if true, iterate the elements in reverse order,
2490+
/// starting at index limitWithinComponent - 1
2491+
/// \param emitBody - a function that will be called to emit the body of
2492+
/// the loop. It's okay if this has paths that exit the body of the loop,
2493+
/// but it should leave the insertion point set at the end. Will be
2494+
/// called within a cleanups scope. The first parameter is the current
2495+
/// index within the expansion component, a value of type Builtin.Word.
2496+
/// The second parameter is that index as a pack indexing instruction
2497+
/// that indexes into packs with the shape of the pack expasion.
2498+
/// The third parameter is the current pack index within the overall
2499+
/// pack, a pack indexing instruction that indexes into packs with the
2500+
/// shape of formalPackType.
2501+
void emitDynamicPackLoop(SILLocation loc,
2502+
CanPackType formalPackType,
2503+
unsigned componentIndex,
2504+
SILValue limitWithinComponent,
2505+
GenericEnvironment *openedElementEnv,
2506+
bool reverse,
2507+
llvm::function_ref<void(SILValue indexWithinComponent,
2508+
SILValue packExpansionIndex,
2509+
SILValue packIndex)> emitBody);
2510+
2511+
/// Emit a loop which destroys a prefix of a pack expansion component
2512+
/// of a pack value.
2513+
///
2514+
/// \param packAddr - the address of the overall pack value
2515+
/// \param formalPackType - a pack type with the same shape as the
2516+
/// overall pack value
2517+
/// \param componentIndex - the index of the pack expansion component
2518+
/// within the formal pack type
2519+
/// \param limitWithinComponent - the number of elements in a prefix of
2520+
/// the expansion component to destroy; if null, all elements in the
2521+
/// component will be destroyed
2522+
void emitPartialDestroyPack(SILLocation loc,
2523+
SILValue packAddr,
2524+
CanPackType formalPackType,
2525+
unsigned componentIndex,
2526+
SILValue limitWithinComponent);
2527+
2528+
/// Emit a loop which destroys all the elements of a pack value.
2529+
///
2530+
/// \param packAddr - the address of the overall pack value
2531+
/// \param formalPackType - a pack type with the same shape as the
2532+
/// overall pack value
2533+
void emitDestroyPack(SILLocation loc,
2534+
SILValue packAddr,
2535+
CanPackType formalPackType);
24552536
};
24562537

24572538

lib/SILGen/SILGenLValue.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3668,7 +3668,7 @@ LValue SILGenLValue::visitSubscriptExpr(SubscriptExpr *e,
36683668
actorIso = getActorIsolation(decl);
36693669

36703670
auto *argList = e->getArgs();
3671-
auto indices = SGF.prepareSubscriptIndices(decl, subs, strategy, argList);
3671+
auto indices = SGF.prepareSubscriptIndices(e, decl, subs, strategy, argList);
36723672

36733673
CanType formalRValueType = getSubstFormalRValueType(e);
36743674
lv.addMemberSubscriptComponent(SGF, e, decl, subs,

0 commit comments

Comments
 (0)