Skip to content

Commit 86ac28c

Browse files
authored
Merge pull request #8285 from gottesmm/scope_arg_transforms_1
2 parents 7d56e79 + 54a97bb commit 86ac28c

File tree

6 files changed

+95
-73
lines changed

6 files changed

+95
-73
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,16 +2566,18 @@ namespace {
25662566
SILType loweredSubstArgType,
25672567
AbstractionPattern origParamType,
25682568
SILParameterInfo param) {
2569+
Scope scope(SGF, arg.getLocation());
2570+
25692571
// TODO: We should take the opportunity to peephole certain abstraction
25702572
// changes here, for instance, directly emitting a closure literal at the
25712573
// callee's expected abstraction level instead of emitting it maximally
25722574
// substituted and thunking.
25732575
auto emitted = emitArgumentFromSource(std::move(arg), loweredSubstArgType,
25742576
origParamType, param);
2575-
return SGF.emitSubstToOrigValue(emitted.loc,
2576-
std::move(emitted.value).getScalarValue(),
2577-
origParamType, emitted.value.getType(),
2578-
emitted.contextForReabstraction);
2577+
ManagedValue result = SGF.emitSubstToOrigValue(
2578+
emitted.loc, std::move(emitted.value).getScalarValue(), origParamType,
2579+
emitted.value.getType(), emitted.contextForReabstraction);
2580+
return scope.popPreservingValue(result);
25792581
}
25802582

25812583
CanType getAnyObjectType() {
@@ -2592,6 +2594,8 @@ namespace {
25922594
SILType loweredSubstArgType,
25932595
AbstractionPattern origParamType,
25942596
SILParameterInfo param) {
2597+
Scope scope(SGF, arg.getLocation());
2598+
25952599
// If we're bridging a concrete type to `id` via Any, skip the Any
25962600
// boxing.
25972601

@@ -2601,17 +2605,18 @@ namespace {
26012605
if (auto objTy = paramObjTy.getAnyOptionalObjectType())
26022606
paramObjTy = objTy;
26032607
if (isAnyObjectType(paramObjTy) && !arg.isRValue()) {
2604-
return emitNativeToBridgedObjectArgument(std::move(arg).asKnownExpr(),
2605-
loweredSubstArgType,
2606-
origParamType, param);
2608+
return scope.popPreservingValue(emitNativeToBridgedObjectArgument(
2609+
std::move(arg).asKnownExpr(), loweredSubstArgType, origParamType,
2610+
param));
26072611
}
26082612

26092613
auto emitted = emitArgumentFromSource(std::move(arg), loweredSubstArgType,
26102614
origParamType, param);
2611-
2612-
return SGF.emitNativeToBridgedValue(emitted.loc,
2613-
std::move(emitted.value).getAsSingleValue(SGF, emitted.loc),
2614-
Rep, param.getType());
2615+
2616+
return scope.popPreservingValue(SGF.emitNativeToBridgedValue(
2617+
emitted.loc,
2618+
std::move(emitted.value).getAsSingleValue(SGF, emitted.loc), Rep,
2619+
param.getType()));
26152620
}
26162621

26172622
enum class ExistentialPeepholeOptionality {

lib/SILGen/SILGenBuilder.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,24 @@ using namespace swift;
2222
using namespace Lowering;
2323

2424
//===----------------------------------------------------------------------===//
25-
// Cleanup Forwarder
25+
// CleanupCloner
2626
//===----------------------------------------------------------------------===//
2727

28-
namespace {
29-
class CleanupCloner {
30-
SILGenFunction &SGF;
31-
bool hasCleanup;
32-
bool isLValue;
33-
ValueOwnershipKind ownershipKind;
34-
35-
public:
36-
CleanupCloner(SILGenBuilder &Builder, ManagedValue M)
37-
: SGF(Builder.getSILGenFunction()), hasCleanup(M.hasCleanup()),
38-
isLValue(M.isLValue()), ownershipKind(M.getOwnershipKind()) {}
39-
40-
ManagedValue clone(SILValue value) {
41-
if (isLValue) {
42-
return ManagedValue::forLValue(value);
43-
}
44-
45-
if (!hasCleanup) {
46-
return ManagedValue::forUnmanaged(value);
47-
}
28+
ManagedValue CleanupCloner::clone(SILValue value) const {
29+
if (isLValue) {
30+
return ManagedValue::forLValue(value);
31+
}
4832

49-
if (value->getType().isAddress()) {
50-
return SGF.emitManagedBufferWithCleanup(value);
51-
}
33+
if (!hasCleanup) {
34+
return ManagedValue::forUnmanaged(value);
35+
}
5236

53-
return SGF.emitManagedRValueWithCleanup(value);
37+
if (value->getType().isAddress()) {
38+
return SGF.emitManagedBufferWithCleanup(value);
5439
}
55-
};
56-
} // end anonymous namespace
40+
41+
return SGF.emitManagedRValueWithCleanup(value);
42+
}
5743

5844
//===----------------------------------------------------------------------===//
5945
// Utility Methods

lib/SILGen/SILGenBuilder.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,23 @@ class SwitchEnumBuilder {
329329
SILGenFunction &getSGF() const { return builder.getSILGenFunction(); }
330330
};
331331

332+
class CleanupCloner {
333+
SILGenFunction &SGF;
334+
bool hasCleanup;
335+
bool isLValue;
336+
ValueOwnershipKind ownershipKind;
337+
338+
public:
339+
CleanupCloner(SILGenBuilder &builder, ManagedValue mv)
340+
: CleanupCloner(builder.getSILGenFunction(), mv) {}
341+
342+
CleanupCloner(SILGenFunction &SGF, ManagedValue mv)
343+
: SGF(SGF), hasCleanup(mv.hasCleanup()), isLValue(mv.isLValue()),
344+
ownershipKind(mv.getOwnershipKind()) {}
345+
346+
ManagedValue clone(SILValue value) const;
347+
};
348+
332349
} // namespace Lowering
333350
} // namespace swift
334351

lib/SILGen/Scope.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class LLVM_LIBRARY_VISIBILITY Scope {
4141
cleanups.innermostScope = depth;
4242
}
4343

44+
explicit Scope(SILGenFunction &SGF, SILLocation loc)
45+
: Scope(SGF.Cleanups, CleanupLocation::get(loc)) {}
46+
4447
void pop() {
4548
assert(depth.isValid() && "popping a scope twice!");
4649
popImpl();
@@ -54,6 +57,17 @@ class LLVM_LIBRARY_VISIBILITY Scope {
5457

5558
bool isValid() const { return depth.isValid(); }
5659

60+
ManagedValue popPreservingValue(ManagedValue mv) {
61+
// If we have a value, make sure that it is an object. The reason why is
62+
// that we want to make sure that we are not forwarding a cleanup for a
63+
// stack location that will be destroyed by this scope.
64+
assert(!mv.getValue() || mv.getType().isObject());
65+
CleanupCloner cloner(cleanups.SGF, mv);
66+
SILValue value = mv.forward(cleanups.SGF);
67+
pop();
68+
return cloner.clone(value);
69+
}
70+
5771
private:
5872
void popImpl() {
5973
cleanups.stack.checkIterator(depth);

test/SILGen/objc_bridging.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,10 +515,10 @@ func applyStringBlock(_ f: @convention(block) (String) -> String, x: String) ->
515515
// CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @_T0SS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF
516516
// CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
517517
// CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[BORROWED_STRING_COPY]]) : $@convention(method) (@guaranteed String)
518-
// CHECK: [[RESULT_NSSTR:%.*]] = apply [[BLOCK_COPY_COPY]]([[NSSTR]]) : $@convention(block) (NSString) -> @autoreleased NSString
519-
// CHECK: destroy_value [[NSSTR]]
520518
// CHECK: end_borrow [[BORROWED_STRING_COPY]] from [[STRING_COPY]]
521519
// CHECK: destroy_value [[STRING_COPY]]
520+
// CHECK: [[RESULT_NSSTR:%.*]] = apply [[BLOCK_COPY_COPY]]([[NSSTR]]) : $@convention(block) (NSString) -> @autoreleased NSString
521+
// CHECK: destroy_value [[NSSTR]]
522522
// CHECK: [[FINAL_BRIDGE:%.*]] = function_ref @_T0SS10FoundationE36_unconditionallyBridgeFromObjectiveCSSSo8NSStringCSgFZ
523523
// CHECK: [[OPTIONAL_NSSTR:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[RESULT_NSSTR]]
524524
// CHECK: [[RESULT:%.*]] = apply [[FINAL_BRIDGE]]([[OPTIONAL_NSSTR]], {{.*}}) : $@convention(method) (@owned Optional<NSString>, @thin String.Type) -> @owned String

0 commit comments

Comments
 (0)