mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Two changes:
- Fix a misunderstanding I had about ownership requirements in my previous patch: now any references to value-promoted self do a retain and use a ManagedValue, just like the semantic load path used to. This is the change to visitLoadExpr - Second, change argument lowering to drop the "self" argument of normal class methods into a constant reference, instead of making a box for it. This greatly reduces the amount of SIL generated for class methods. The argument lowering piece is somewhat hacky because initializations really want to be dealing with memory, but it seemed like the best approach given the current design. Review appreciated. Swift SVN r10984
This commit is contained in:
@@ -414,6 +414,14 @@ struct InitializationForPattern
|
||||
if (isa<LValueType>(varType))
|
||||
return InitializationPtr(new InOutInitialization(vd));
|
||||
|
||||
// If this is a 'self' argument for a class method (not struct method), emit
|
||||
// it as a constant value. Since it is a constant value, there is no memory
|
||||
// location associated with it, and thus we don't need an initialization -
|
||||
// the store will provide the value directly into the VarLocs map.
|
||||
if (vd->isImplicit() && vd->getName().str() == "self" &&
|
||||
vd->getType()->hasReferenceSemantics())
|
||||
return InitializationPtr(new BlackHoleInitialization());
|
||||
|
||||
// Otherwise, we have a normal local-variable initialization.
|
||||
auto varInit = Gen.emitLocalVariableWithCleanup(vd);
|
||||
|
||||
@@ -484,6 +492,26 @@ CleanupHandle SILGenFunction::enterDeallocStackCleanup(SILLocation loc,
|
||||
return Cleanups.getTopCleanup();
|
||||
}
|
||||
|
||||
|
||||
class CleanupCaptureBox : public Cleanup {
|
||||
SILValue box;
|
||||
public:
|
||||
CleanupCaptureBox(SILValue box) : box(box) {}
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitStrongRelease(l, box);
|
||||
}
|
||||
};
|
||||
|
||||
class CleanupCaptureValue : public Cleanup {
|
||||
SILValue v;
|
||||
public:
|
||||
CleanupCaptureValue(SILValue v) : v(v) {}
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitDestroyValueOperation(l, v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/// A visitor for traversing a pattern, creating
|
||||
@@ -608,8 +636,25 @@ struct ArgumentInitVisitor :
|
||||
}
|
||||
|
||||
SILValue visitNamedPattern(NamedPattern *P, Initialization *I) {
|
||||
return makeArgumentInto(P->getType(), f.begin(),
|
||||
P->getDecl(), I);
|
||||
VarDecl *vd = P->getDecl();
|
||||
|
||||
// If this is a 'self' argument for a class method (not struct method), emit
|
||||
// it as a constant value. Since it is a constant value, there is no memory
|
||||
// location associated with it, and thus we don't need an initialization -
|
||||
// the store will provide the value directly into the VarLocs map.
|
||||
if (vd->isImplicit() && vd->getName().str() == "self" &&
|
||||
vd->getType()->hasReferenceSemantics()) {
|
||||
SILLocation loc = vd;
|
||||
loc.markAsPrologue();
|
||||
SILValue arg = makeArgument(P->getType(), f.begin(), loc);
|
||||
assert(!gen.VarLocs.count(vd) && "Already emitted a this vardecl?");
|
||||
gen.VarLocs[vd] = SILGenFunction::VarLoc::getConstant(arg);
|
||||
gen.Cleanups.pushCleanup<CleanupCaptureValue>(arg);
|
||||
I->finishInitialization(gen);
|
||||
return arg;
|
||||
}
|
||||
|
||||
return makeArgumentInto(P->getType(), f.begin(), vd, I);
|
||||
}
|
||||
|
||||
#define PATTERN(Id, Parent)
|
||||
@@ -621,25 +666,7 @@ struct ArgumentInitVisitor :
|
||||
|
||||
};
|
||||
|
||||
class CleanupCaptureBox : public Cleanup {
|
||||
SILValue box;
|
||||
public:
|
||||
CleanupCaptureBox(SILValue box) : box(box) {}
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitStrongRelease(l, box);
|
||||
}
|
||||
};
|
||||
|
||||
class CleanupCaptureValue : public Cleanup {
|
||||
SILValue v;
|
||||
public:
|
||||
CleanupCaptureValue(SILValue v) : v(v) {}
|
||||
void emit(SILGenFunction &gen, CleanupLocation l) override {
|
||||
gen.B.emitDestroyValueOperation(l, v);
|
||||
}
|
||||
};
|
||||
|
||||
static void emitCaptureArguments(SILGenFunction &gen, ValueDecl *capture) {
|
||||
static void emitCaptureArguments(SILGenFunction & gen, ValueDecl *capture) {
|
||||
ASTContext &c = capture->getASTContext();
|
||||
switch (getDeclCaptureKind(capture)) {
|
||||
case CaptureKind::None:
|
||||
|
||||
Reference in New Issue
Block a user