Skip to content

Commit 203ad94

Browse files
authored
Merge pull request #80083 from jckarter/addressable-buffer-begin-scope
SILGen: Adjust allocation point for addressable representations.
2 parents 5e3bd9f + 85425fb commit 203ad94

File tree

3 files changed

+101
-11
lines changed

3 files changed

+101
-11
lines changed

lib/SILGen/SILGenDecl.cpp

+25-10
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ class LetValueInitialization : public Initialization {
818818
DestroyCleanup = SGF.Cleanups.getTopCleanup();
819819

820820
// If the binding has an addressable buffer forced, it should be cleaned
821-
// up here.
821+
// up at this scope.
822822
SGF.enterLocalVariableAddressableBufferScope(vd);
823823
}
824824

@@ -2461,6 +2461,8 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
24612461

24622462
void
24632463
SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl) {
2464+
auto marker = B.createTuple(decl, {});
2465+
AddressableBuffers[decl] = marker;
24642466
Cleanups.pushCleanup<DeallocateLocalVariableAddressableBuffer>(decl);
24652467
}
24662468

@@ -2513,7 +2515,28 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
25132515
SILValue reabstraction, allocStack, storeBorrow;
25142516
{
25152517
SavedInsertionPointRAII save(B);
2516-
B.setInsertionPoint(value->getNextInstruction());
2518+
auto insertPoint = AddressableBuffers[decl].insertPoint;
2519+
B.setInsertionPoint(insertPoint);
2520+
auto allocStackTy = fullyAbstractedTy;
2521+
if (value->getType().isMoveOnlyWrapped()) {
2522+
allocStackTy = allocStackTy.addingMoveOnlyWrapper();
2523+
}
2524+
allocStack = B.createAllocStack(decl,
2525+
allocStackTy,
2526+
std::nullopt,
2527+
DoesNotHaveDynamicLifetime,
2528+
IsNotLexical,
2529+
IsNotFromVarDecl,
2530+
DoesNotUseMoveableValueDebugInfo,
2531+
/*skipVarDeclAssert*/ true);
2532+
}
2533+
{
2534+
SavedInsertionPointRAII save(B);
2535+
if (isa<ParamDecl>(decl)) {
2536+
B.setInsertionPoint(allocStack->getNextInstruction());
2537+
} else {
2538+
B.setInsertionPoint(value->getNextInstruction());
2539+
}
25172540
auto declarationLoc = value->getDefiningInsertionPoint()->getLoc();
25182541

25192542
// Reabstract if necessary.
@@ -2528,14 +2551,6 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
25282551
reabstraction = reabstracted.forward(*this);
25292552
newValue = reabstraction;
25302553
}
2531-
// TODO: reabstract
2532-
allocStack = B.createAllocStack(declarationLoc, newValue->getType(),
2533-
std::nullopt,
2534-
DoesNotHaveDynamicLifetime,
2535-
IsNotLexical,
2536-
IsNotFromVarDecl,
2537-
DoesNotUseMoveableValueDebugInfo,
2538-
/*skipVarDeclAssert*/ true);
25392554
storeBorrow = B.createStoreBorrow(declarationLoc, newValue, allocStack);
25402555
}
25412556

lib/SILGen/SILGenFunction.h

+31
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,37 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
535535
/// a local variable.
536536
llvm::DenseMap<ValueDecl*, VarLoc> VarLocs;
537537

538+
// Represents an addressable buffer that has been allocated but not yet used.
539+
struct PreparedAddressableBuffer {
540+
SILInstruction *insertPoint = nullptr;
541+
542+
PreparedAddressableBuffer() = default;
543+
544+
PreparedAddressableBuffer(SILInstruction *insertPoint)
545+
: insertPoint(insertPoint)
546+
{}
547+
548+
PreparedAddressableBuffer(PreparedAddressableBuffer &&other)
549+
: insertPoint(other.insertPoint)
550+
{
551+
other.insertPoint = nullptr;
552+
}
553+
554+
PreparedAddressableBuffer &operator=(PreparedAddressableBuffer &&other) {
555+
insertPoint = other.insertPoint;
556+
other.insertPoint = nullptr;
557+
return *this;
558+
}
559+
560+
~PreparedAddressableBuffer() {
561+
if (insertPoint) {
562+
// Remove the insertion point if it went unused.
563+
insertPoint->eraseFromParent();
564+
}
565+
}
566+
};
567+
llvm::DenseMap<VarDecl *, PreparedAddressableBuffer> AddressableBuffers;
568+
538569
/// Establish the scope for the addressable buffer that might be allocated
539570
/// for a local variable binding.
540571
///

test/SILGen/addressable_representation.swift

+45-1
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ func test4(_ c: CO1, _ c1: Bool, _ c2: Bool) {
134134

135135
// CHECK-LABEL: sil {{.*}} @$s{{.*}}5test5
136136
func test5(_ f: @escaping () -> ()) {
137+
// CHECK: [[ADDRESSABLE:%.*]] = alloc_stack
137138
// CHECK: [[THUNKED:%.*]] = partial_apply
138139
// CHECK: [[CONV:%.*]] = convert_function [[THUNKED]]
139-
// CHECK: [[ADDRESSABLE:%.*]] = alloc_stack
140140
// CHECK: [[ADDRESSABLE_BORROW:%.*]] = store_borrow [[CONV]] to [[ADDRESSABLE]]
141141

142142
// CHECK: function_ref @$s{{.*}}22addressableFunctionArg
@@ -181,6 +181,30 @@ func test7(_ c: CO1) {
181181
print(v)
182182
}
183183

184+
// CHECK-LABEL: sil {{.*}} @$s{{.*}}5test8
185+
func test8() {
186+
guard #available(Span 0.1, *) else { return }
187+
188+
var s = "A long string that is absolutely not smol at all."
189+
let u = Array(s.utf8)
190+
191+
// CHECK: [[C_ADDRESSABLE:%.*]] = alloc_stack $CO2<String>
192+
// CHECK: [[C_ADDRESSABLE_BORROW:%.*]] = store_borrow {{%.*}} to [[C_ADDRESSABLE]]
193+
let c = CO2(consume s)
194+
s = ""
195+
// CHECK: [[GET_STORAGE:%.*]] = function_ref @$s{{.*}}7storage{{.*}}Gvg
196+
// CHECK: apply [[GET_STORAGE]]<String>([[C_ADDRESSABLE_BORROW]]
197+
let span = c.storage
198+
199+
_ = span.count == 1
200+
201+
// CHECK: function_ref @$s{{.*}}4utf8
202+
let v = Array(span[0].utf8)
203+
_ = u == v
204+
// CHECK: end_borrow [[C_ADDRESSABLE_BORROW]]
205+
}
206+
207+
184208
func addressableFunctionArg(_ f: @_addressable @escaping () -> ()) {}
185209

186210
@available(Span 0.1, *)
@@ -203,3 +227,23 @@ struct CO1 {
203227
}
204228
}
205229

230+
@available(Span 0.1, *)
231+
@_addressableForDependencies
232+
struct CO2<T> {
233+
var s: T
234+
235+
init(_ s: T) { self.s = s }
236+
237+
var storage: Span<T> {
238+
@lifetime(borrow self)
239+
borrowing get {
240+
fatalError()
241+
}
242+
}
243+
244+
@lifetime(borrow self)
245+
func getStorage() -> Span<T> {
246+
fatalError()
247+
}
248+
}
249+

0 commit comments

Comments
 (0)