Skip to content

Commit dfd3b74

Browse files
authored
Merge pull request #7714 from gottesmm/completely_refactor_class_constructor_initialization
2 parents b0f83ed + 92cb1f3 commit dfd3b74

33 files changed

+1566
-220
lines changed

include/swift/SIL/SILValue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct ValueOwnershipKind {
117117
operator innerty() const { return Value; }
118118

119119
Optional<ValueOwnershipKind> merge(ValueOwnershipKind RHS) const;
120+
121+
bool isTrivialOr(ValueOwnershipKind Kind) const {
122+
return Value == Trivial || Value == Kind;
123+
}
120124
};
121125

122126
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, ValueOwnershipKind Kind);

lib/SILGen/Cleanup.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ CleanupStateRestorationScope::pushCurrentCleanupState(CleanupHandle handle) {
218218
SavedStates.push_back({handle, oldState});
219219
}
220220

221-
void CleanupStateRestorationScope::pop() {
221+
void CleanupStateRestorationScope::popImpl() {
222222
// Restore cleanup states in the opposite order in which we saved them.
223223
for (auto i = SavedStates.rbegin(), e = SavedStates.rend(); i != e; ++i) {
224224
CleanupHandle handle = i->first;
@@ -231,8 +231,12 @@ void CleanupStateRestorationScope::pop() {
231231
"changing state of dead cleanup");
232232
cleanup.setState(Cleanups.Gen, stateToRestore);
233233
}
234+
235+
SavedStates.clear();
234236
}
235237

238+
void CleanupStateRestorationScope::pop() && { popImpl(); }
239+
236240
llvm::raw_ostream &Lowering::operator<<(llvm::raw_ostream &os,
237241
CleanupState state) {
238242
switch (state) {

lib/SILGen/Cleanup.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,12 @@ class CleanupStateRestorationScope {
232232
/// Just remember whatever the current state of the given cleanup is.
233233
void pushCurrentCleanupState(CleanupHandle handle);
234234

235-
void pop();
235+
void pop() &&;
236236

237-
~CleanupStateRestorationScope() {
238-
pop();
239-
}
237+
~CleanupStateRestorationScope() { popImpl(); }
238+
239+
private:
240+
void popImpl();
240241
};
241242

242243
} // end namespace Lowering

lib/SILGen/JumpDest.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ class LLVM_LIBRARY_VISIBILITY JumpDest {
4949
CleanupsDepth getDepth() const { return Depth; }
5050
CleanupLocation getCleanupLocation() const { return CleanupLoc; }
5151

52+
JumpDest translate(CleanupsDepth NewDepth) && {
53+
JumpDest NewValue(Block, NewDepth, CleanupLoc);
54+
Block = nullptr;
55+
Depth = CleanupsDepth::invalid();
56+
// Null location.
57+
CleanupLoc = CleanupLocation::get(ArtificialUnreachableLocation());
58+
return NewValue;
59+
}
60+
5261
bool isValid() const { return Block != nullptr; }
5362
static JumpDest invalid() {
5463
return JumpDest(CleanupLocation((Expr*) nullptr));

lib/SILGen/RValue.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
//
1818
//===----------------------------------------------------------------------===//
1919

20-
#include "Initialization.h"
2120
#include "RValue.h"
21+
#include "Initialization.h"
22+
#include "SILGenFunction.h"
23+
#include "swift/AST/CanTypeVisitor.h"
2224
#include "swift/SIL/AbstractionPattern.h"
2325
#include "swift/SIL/SILArgument.h"
24-
#include "swift/AST/CanTypeVisitor.h"
2526

2627
using namespace swift;
2728
using namespace Lowering;

lib/SILGen/RValue.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@
2424
#define SWIFT_LOWERING_RVALUE_H
2525

2626
#include "ManagedValue.h"
27-
#include "SILGenFunction.h"
2827
#include "llvm/ADT/SmallVector.h"
2928

3029
namespace swift {
3130
namespace Lowering {
32-
class Initialization;
31+
32+
class Initialization;
33+
class SILGenFunction;
3334

3435
/// An "exploded" SIL rvalue, in which tuple values are recursively
3536
/// destructured. (In SILGen we don't try to explode structs, because doing so

lib/SILGen/SILGenApply.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12821282
void applySuper(ApplyExpr *apply) {
12831283
// Load the 'super' argument.
12841284
Expr *arg = apply->getArg();
1285-
ManagedValue super = SGF.emitRValueAsSingleValue(arg);
1285+
ManagedValue super;
12861286

12871287
// The callee for a super call has to be either a method or constructor.
12881288
Expr *fn = apply->getFn();
@@ -1296,6 +1296,27 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12961296

12971297
if (ctorRef->getDeclRef().isSpecialized())
12981298
substitutions = ctorRef->getDeclRef().getSubstitutions();
1299+
1300+
assert(SGF.SelfInitDelegationState ==
1301+
SILGenFunction::WillSharedBorrowSelf);
1302+
SGF.SelfInitDelegationState = SILGenFunction::WillExclusiveBorrowSelf;
1303+
super = SGF.emitRValueAsSingleValue(arg);
1304+
assert(SGF.SelfInitDelegationState ==
1305+
SILGenFunction::DidExclusiveBorrowSelf);
1306+
1307+
// Check if super is not the same as our base type. This means that we
1308+
// performed an upcast. Set SuperInitDelegationState to super.
1309+
if (super.getValue() != SGF.InitDelegationSelf.getValue()) {
1310+
assert(super.getCleanup() == SGF.InitDelegationSelf.getCleanup());
1311+
SILValue underlyingSelf = SGF.InitDelegationSelf.forward(SGF);
1312+
SGF.InitDelegationSelf = ManagedValue::forUnmanaged(underlyingSelf);
1313+
CleanupHandle newWriteback = SGF.enterDelegateInitSelfWritebackCleanup(
1314+
SGF.InitDelegationLoc.getValue(), SGF.InitDelegationSelfBox,
1315+
super.getValue());
1316+
SGF.SuperInitDelegationSelf =
1317+
ManagedValue(super.getValue(), newWriteback);
1318+
super = SGF.SuperInitDelegationSelf;
1319+
}
12991320
} else if (auto *declRef = dyn_cast<DeclRefExpr>(fn)) {
13001321
assert(isa<FuncDecl>(declRef->getDecl()) && "non-function super call?!");
13011322
constant = SILDeclRef(declRef->getDecl(),
@@ -1305,8 +1326,10 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
13051326

13061327
if (declRef->getDeclRef().isSpecialized())
13071328
substitutions = declRef->getDeclRef().getSubstitutions();
1308-
} else
1329+
super = SGF.emitRValueAsSingleValue(arg);
1330+
} else {
13091331
llvm_unreachable("invalid super callee");
1332+
}
13101333

13111334
CanType superFormalType = arg->getType()->getCanonicalType();
13121335
setSelfParam(ArgumentSource(arg, RValue(SGF, apply, superFormalType, super)),
@@ -1432,14 +1455,14 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
14321455

14331456
// If the initializer is a C function imported as a member,
14341457
// there is no 'self' parameter. Mark it undef.
1435-
if (ctorRef->getDecl()->isImportAsMember())
1458+
if (ctorRef->getDecl()->isImportAsMember()) {
14361459
self = SGF.emitUndef(expr, selfFormalType);
1437-
else if (SGF.AllocatorMetatype)
1460+
} else if (SGF.AllocatorMetatype) {
14381461
self = emitCorrespondingSelfValue(
1439-
ManagedValue::forUnmanaged(SGF.AllocatorMetatype),
1440-
arg);
1441-
else
1462+
ManagedValue::forUnmanaged(SGF.AllocatorMetatype), arg);
1463+
} else {
14421464
self = ManagedValue::forUnmanaged(SGF.emitMetatypeOfValue(expr, arg));
1465+
}
14431466
} else {
14441467
// If we're in a protocol extension initializer, we haven't allocated
14451468
// "self" yet at this point. Do so. Use alloc_ref_dynamic since we should
@@ -1455,7 +1478,12 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
14551478
// Perform any adjustments needed to 'self'.
14561479
self = emitCorrespondingSelfValue(self, arg);
14571480
} else {
1481+
assert(SGF.SelfInitDelegationState ==
1482+
SILGenFunction::WillSharedBorrowSelf);
1483+
SGF.SelfInitDelegationState = SILGenFunction::WillExclusiveBorrowSelf;
14581484
self = SGF.emitRValueAsSingleValue(arg);
1485+
assert(SGF.SelfInitDelegationState ==
1486+
SILGenFunction::DidExclusiveBorrowSelf);
14591487
}
14601488
}
14611489

@@ -3208,6 +3236,11 @@ namespace {
32083236
} else {
32093237
value = std::move(arg).getAsSingleValue(SGF, contexts.ForEmission);
32103238
}
3239+
3240+
if (param.isConsumed() &&
3241+
value.getOwnershipKind() == ValueOwnershipKind::Guaranteed) {
3242+
value = value.copyUnmanaged(SGF, arg.getLocation());
3243+
}
32113244
Args.push_back(value);
32123245
}
32133246

lib/SILGen/SILGenBuilder.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,59 @@ ManagedValue SILGenBuilder::createLoadTake(SILLocation loc, ManagedValue v,
402402
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
403403
return gen.emitManagedRValueWithCleanup(result, lowering);
404404
}
405+
406+
ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v) {
407+
auto &lowering = getFunction().getTypeLowering(v.getType());
408+
return createLoadCopy(loc, v, lowering);
409+
}
410+
411+
ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v,
412+
const TypeLowering &lowering) {
413+
assert(lowering.getLoweredType().getAddressType() == v.getType());
414+
SILValue result =
415+
lowering.emitLoadOfCopy(*this, loc, v.forward(gen), IsNotTake);
416+
if (lowering.isTrivial())
417+
return ManagedValue::forUnmanaged(result);
418+
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");
419+
return gen.emitManagedRValueWithCleanup(result, lowering);
420+
}
421+
422+
ManagedValue SILGenBuilder::createFunctionArgument(SILType type,
423+
ValueDecl *decl) {
424+
SILFunction &F = getFunction();
425+
426+
SILFunctionArgument *arg = F.begin()->createFunctionArgument(type, decl);
427+
if (arg->getType().isObject()) {
428+
if (arg->getOwnershipKind().isTrivialOr(ValueOwnershipKind::Owned))
429+
return gen.emitManagedRValueWithCleanup(arg);
430+
return ManagedValue::forBorrowedRValue(arg);
431+
}
432+
433+
return gen.emitManagedBufferWithCleanup(arg);
434+
}
435+
436+
ManagedValue
437+
SILGenBuilder::createMarkUninitialized(ValueDecl *decl, ManagedValue operand,
438+
MarkUninitializedInst::Kind muKind) {
439+
// We either have an owned or trivial value.
440+
SILValue value =
441+
SILBuilder::createMarkUninitialized(decl, operand.forward(gen), muKind);
442+
assert(value->getType().isObject() && "Expected only objects here");
443+
444+
// If we have a trivial value, just return without a cleanup.
445+
if (operand.getOwnershipKind() != ValueOwnershipKind::Owned) {
446+
return ManagedValue::forUnmanaged(value);
447+
}
448+
449+
// Otherwise, recreate the cleanup.
450+
return gen.emitManagedRValueWithCleanup(value);
451+
}
452+
453+
ManagedValue SILGenBuilder::createEnum(SILLocation loc, ManagedValue payload,
454+
EnumElementDecl *decl, SILType type) {
455+
SILValue result =
456+
SILBuilder::createEnum(loc, payload.forward(gen), decl, type);
457+
if (result.getOwnershipKind() != ValueOwnershipKind::Owned)
458+
return ManagedValue::forUnmanaged(result);
459+
return gen.emitManagedRValueWithCleanup(result);
460+
}

lib/SILGen/SILGenBuilder.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class SILGenBuilder : public SILBuilder {
147147
ManagedValue originalValue);
148148
ManagedValue createOwnedPHIArgument(SILType type);
149149

150+
using SILBuilder::createMarkUninitialized;
151+
ManagedValue createMarkUninitialized(ValueDecl *decl, ManagedValue operand,
152+
MarkUninitializedInst::Kind muKind);
153+
150154
using SILBuilder::createAllocRef;
151155
ManagedValue createAllocRef(SILLocation loc, SILType refType, bool objc,
152156
bool canAllocOnStack,
@@ -192,6 +196,17 @@ class SILGenBuilder : public SILBuilder {
192196
ManagedValue createLoadTake(SILLocation loc, ManagedValue addr);
193197
ManagedValue createLoadTake(SILLocation loc, ManagedValue addr,
194198
const TypeLowering &lowering);
199+
ManagedValue createLoadCopy(SILLocation Loc, ManagedValue Addr);
200+
ManagedValue createLoadCopy(SILLocation Loc, ManagedValue Addr,
201+
const TypeLowering &Lowering);
202+
203+
ManagedValue createFunctionArgument(SILType type, ValueDecl *decl);
204+
205+
using SILBuilder::createEnum;
206+
ManagedValue createEnum(SILLocation loc, ManagedValue payload,
207+
EnumElementDecl *decl, SILType type);
208+
209+
ManagedValue createSemanticLoadBorrow(SILLocation loc, ManagedValue addr);
195210
};
196211

197212
} // namespace Lowering

0 commit comments

Comments
 (0)