SILArgument: Make Decls mandatory for function arguments.

Swift SVN r11099
This commit is contained in:
Adrian Prantl
2013-12-10 23:30:23 +00:00
parent 61318e33f0
commit 2acb71831e
8 changed files with 100 additions and 45 deletions

View File

@@ -25,10 +25,10 @@ class SILArgument : public ValueBase {
void operator delete(void *Ptr, size_t) = delete; void operator delete(void *Ptr, size_t) = delete;
SILBasicBlock *ParentBB; SILBasicBlock *ParentBB;
ValueDecl *Decl; const ValueDecl *Decl;
public: public:
explicit explicit
SILArgument(SILType Ty, SILBasicBlock *ParentBB, ValueDecl *D = nullptr); SILArgument(SILType Ty, SILBasicBlock *ParentBB, const ValueDecl *D = nullptr);
/// getType() is ok since this is known to only have one type. /// getType() is ok since this is known to only have one type.
SILType getType(unsigned i = 0) const { return ValueBase::getType(i); } SILType getType(unsigned i = 0) const { return ValueBase::getType(i); }

View File

@@ -26,8 +26,20 @@ using namespace swift;
// SILArgument Implementation // SILArgument Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SILArgument::SILArgument(SILType Ty, SILBasicBlock *ParentBB, ValueDecl *D) SILArgument::SILArgument(SILType Ty, SILBasicBlock *ParentBB, const ValueDecl *D)
: ValueBase(ValueKind::SILArgument, Ty), ParentBB(ParentBB), Decl(D) { : ValueBase(ValueKind::SILArgument, Ty), ParentBB(ParentBB), Decl(D) {
// Function arguments need to have a decl.
assert(
// Unless the function is transparent,
!ParentBB->getParent()->isTransparent() &&
// or an ObjC thunk,
ParentBB->getParent()->getAbstractCC() != AbstractCC::ObjCMethod &&
// or comes from a SIL file.
!ParentBB->getParent()->getLocation().is<SILFileLocation>() &&
// Is this the initial basic block in the function?
ParentBB->getParent()->size() == 1
? D != nullptr
: true );
ParentBB->addArgument(this); ParentBB->addArgument(this);
} }

View File

@@ -269,7 +269,7 @@ public:
RValue visitType(CanType t) { RValue visitType(CanType t) {
SILValue arg = new (gen.SGM.M) SILValue arg = new (gen.SGM.M)
SILArgument(gen.getLoweredType(t), parent, loc.getAsASTNode<VarDecl>()); SILArgument(gen.getLoweredType(t), parent, loc.getAsASTNode<ValueDecl>());
ManagedValue mv = isa<LValueType>(t) ManagedValue mv = isa<LValueType>(t)
? ManagedValue(arg, ManagedValue::LValue) ? ManagedValue(arg, ManagedValue::LValue)
: gen.emitManagedRValueWithCleanup(arg); : gen.emitManagedRValueWithCleanup(arg);

View File

@@ -629,7 +629,14 @@ struct ArgumentInitVisitor :
assert(I->kind == Initialization::Kind::Ignored && assert(I->kind == Initialization::Kind::Ignored &&
"any pattern should match a black-hole Initialization"); "any pattern should match a black-hole Initialization");
auto &lowering = gen.getTypeLowering(P->getType()); auto &lowering = gen.getTypeLowering(P->getType());
SILValue arg = makeArgument(P->getType(), f.begin(), P);
auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
// FIXME: we should probably number them.
AC.getIdentifier("_"), P->getType(),
f.getDeclContext());
SILValue arg = makeArgument(P->getType(), f.begin(), VD);
lowering.emitDestroyRValue(gen.B, P, arg); lowering.emitDestroyRValue(gen.B, P, arg);
return arg; return arg;
} }
@@ -676,7 +683,7 @@ static void emitCaptureArguments(SILGenFunction & gen, ValueDecl *capture) {
// the captured value, and the address of the value itself. // the captured value, and the address of the value itself.
SILType ty = gen.getLoweredType(capture->getType()).getAddressType(); SILType ty = gen.getLoweredType(capture->getType()).getAddressType();
SILValue box = new (gen.SGM.M) SILArgument(SILType::getObjectPointerType(c), SILValue box = new (gen.SGM.M) SILArgument(SILType::getObjectPointerType(c),
gen.F.begin()); gen.F.begin(), capture);
SILValue addr = new (gen.SGM.M) SILArgument(ty, gen.F.begin(), capture); SILValue addr = new (gen.SGM.M) SILArgument(ty, gen.F.begin(), capture);
gen.VarLocs[capture] = SILGenFunction::VarLoc::getAddress(addr, box); gen.VarLocs[capture] = SILGenFunction::VarLoc::getAddress(addr, box);
gen.Cleanups.pushCleanup<CleanupCaptureBox>(box); gen.Cleanups.pushCleanup<CleanupCaptureBox>(box);
@@ -735,7 +742,7 @@ static void emitCaptureArguments(SILGenFunction & gen, ValueDecl *capture) {
void SILGenFunction::emitProlog(AnyFunctionRef TheClosure, void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
ArrayRef<Pattern *> paramPatterns, ArrayRef<Pattern *> paramPatterns,
Type resultType) { Type resultType) {
emitProlog(paramPatterns, resultType); emitProlog(paramPatterns, resultType, TheClosure.getAsDeclContext());
// Emit the capture argument variables. These are placed last because they // Emit the capture argument variables. These are placed last because they
// become the first curry level of the SIL function. // become the first curry level of the SIL function.
@@ -746,12 +753,16 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
} }
void SILGenFunction::emitProlog(ArrayRef<Pattern *> paramPatterns, void SILGenFunction::emitProlog(ArrayRef<Pattern *> paramPatterns,
Type resultType) { Type resultType, DeclContext *DeclCtx) {
// If the return type is address-only, emit the indirect return argument. // If the return type is address-only, emit the indirect return argument.
const TypeLowering &returnTI = getTypeLowering(resultType); const TypeLowering &returnTI = getTypeLowering(resultType);
if (returnTI.isReturnedIndirectly()) { if (returnTI.isReturnedIndirectly()) {
IndirectReturnAddress = new (SGM.M) SILArgument(returnTI.getLoweredType(), auto &AC = getASTContext();
F.begin()); auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
AC.getIdentifier("$return_value"), resultType,
DeclCtx);
IndirectReturnAddress = new (SGM.M)
SILArgument(returnTI.getLoweredType(), F.begin(), VD);
} }
// Emit the argument variables in calling convention order. // Emit the argument variables in calling convention order.

View File

@@ -1931,23 +1931,31 @@ static void emitConstructorMetatypeArg(SILGenFunction &gen,
// In addition to the declared arguments, the constructor implicitly takes // In addition to the declared arguments, the constructor implicitly takes
// the metatype as its first argument, like a static function. // the metatype as its first argument, like a static function.
Type metatype = ctor->getType()->castTo<AnyFunctionType>()->getInput(); Type metatype = ctor->getType()->castTo<AnyFunctionType>()->getInput();
auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
AC.getIdentifier("$metatype"), metatype,
ctor->getDeclContext());
new (gen.F.getModule()) SILArgument(gen.getLoweredType(metatype), new (gen.F.getModule()) SILArgument(gen.getLoweredType(metatype),
gen.F.begin()); gen.F.begin(), VD);
} }
static RValue emitImplicitValueConstructorArg(SILGenFunction &gen, static RValue emitImplicitValueConstructorArg(SILGenFunction &gen,
SILLocation loc, SILLocation loc,
CanType ty) { CanType ty,
DeclContext *DC) {
// Restructure tuple arguments. // Restructure tuple arguments.
if (CanTupleType tupleTy = dyn_cast<TupleType>(ty)) { if (CanTupleType tupleTy = dyn_cast<TupleType>(ty)) {
RValue tuple(ty); RValue tuple(ty);
for (auto fieldType : tupleTy.getElementTypes()) for (auto fieldType : tupleTy.getElementTypes())
tuple.addElement(emitImplicitValueConstructorArg(gen, loc, fieldType)); tuple.addElement(emitImplicitValueConstructorArg(gen, loc, fieldType, DC));
return tuple; return tuple;
} else { } else {
auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
AC.getIdentifier("$implicit_value"), ty, DC);
SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty), SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty),
gen.F.begin()); gen.F.begin(), VD);
return RValue(gen, loc, ty, ManagedValue::forUnmanaged(arg)); return RValue(gen, loc, ty, ManagedValue::forUnmanaged(arg));
} }
} }
@@ -1969,20 +1977,27 @@ static void emitImplicitValueConstructor(SILGenFunction &gen,
RegularLocation Loc(ctor); RegularLocation Loc(ctor);
Loc.markAutoGenerated(); Loc.markAutoGenerated();
auto *TP = cast<TuplePattern>(ctor->getBodyParams()); auto *TP = cast<TuplePattern>(ctor->getBodyParams());
SILType selfTy = gen.getLoweredType(ctor->getImplicitSelfDecl()->getType()); auto selfTyCan = ctor->getImplicitSelfDecl()->getType();
SILType selfTy = gen.getLoweredType(selfTyCan);
// Emit the indirect return argument, if any. // Emit the indirect return argument, if any.
SILValue resultSlot; SILValue resultSlot;
if (selfTy.isAddressOnly(gen.SGM.M)) if (selfTy.isAddressOnly(gen.SGM.M)) {
resultSlot = new (gen.F.getModule()) SILArgument(selfTy, gen.F.begin()); auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
AC.getIdentifier("$return_value"), selfTyCan,
ctor);
resultSlot = new (gen.F.getModule()) SILArgument(selfTy, gen.F.begin(), VD);
}
// Emit the elementwise arguments. // Emit the elementwise arguments.
SmallVector<RValue, 4> elements; SmallVector<RValue, 4> elements;
for (size_t i = 0, size = TP->getFields().size(); i < size; ++i) { for (size_t i = 0, size = TP->getFields().size(); i < size; ++i) {
auto *P = cast<TypedPattern>(TP->getFields()[i].getPattern()); auto *P = cast<TypedPattern>(TP->getFields()[i].getPattern());
elements.push_back(emitImplicitValueConstructorArg(gen, Loc, elements.push_back(
P->getType()->getCanonicalType())); emitImplicitValueConstructorArg(gen, Loc,
P->getType()->getCanonicalType(), ctor));
} }
emitConstructorMetatypeArg(gen, ctor); emitConstructorMetatypeArg(gen, ctor);
@@ -2067,7 +2082,8 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
} }
// Emit the prolog. // Emit the prolog.
emitProlog(ctor->getBodyParams(), ctor->getImplicitSelfDecl()->getType()); emitProlog(ctor->getBodyParams(), ctor->getImplicitSelfDecl()->getType(),
ctor);
emitConstructorMetatypeArg(*this, ctor); emitConstructorMetatypeArg(*this, ctor);
// Create a basic block to jump to for the implicit 'self' return. // Create a basic block to jump to for the implicit 'self' return.
@@ -2118,20 +2134,26 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
} }
static void emitAddressOnlyEnumConstructor(SILGenFunction &gen, static void emitAddressOnlyEnumConstructor(SILGenFunction &gen,
SILType enumTy, SILType enumTy,
EnumElementDecl *element) { EnumElementDecl *element) {
RegularLocation Loc(element); RegularLocation Loc(element);
Loc.markAutoGenerated(); Loc.markAutoGenerated();
// Emit the indirect return slot. // Emit the indirect return slot.
auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
AC.getIdentifier("$return_value"),
enumTy.getSwiftType(),
element->getDeclContext());
SILValue resultSlot SILValue resultSlot
= new (gen.F.getModule()) SILArgument(enumTy, gen.F.begin()); = new (gen.F.getModule()) SILArgument(enumTy, gen.F.begin(), VD);
// Emit the exploded constructor argument. // Emit the exploded constructor argument.
ManagedValue argValue; ManagedValue argValue;
if (element->hasArgumentType()) { if (element->hasArgumentType()) {
RValue arg = emitImplicitValueConstructorArg(gen, Loc, RValue arg = emitImplicitValueConstructorArg
element->getArgumentType()->getCanonicalType()); (gen, Loc, element->getArgumentType()->getCanonicalType(),
element->getDeclContext());
argValue = std::move(arg).getAsSingleValue(gen, Loc); argValue = std::move(arg).getAsSingleValue(gen, Loc);
} }
emitConstructorMetatypeArg(gen, element); emitConstructorMetatypeArg(gen, element);
@@ -2159,8 +2181,10 @@ static void emitLoadableEnumConstructor(SILGenFunction &gen,
// Emit the exploded constructor argument. // Emit the exploded constructor argument.
SILValue argValue; SILValue argValue;
if (element->hasArgumentType()) { if (element->hasArgumentType()) {
RValue arg = emitImplicitValueConstructorArg(gen, Loc, RValue arg = emitImplicitValueConstructorArg
element->getArgumentType()->getCanonicalType()); (gen, Loc,
element->getArgumentType()->getCanonicalType(),
element->getDeclContext());
argValue = std::move(arg).forwardAsSingleValue(gen, Loc); argValue = std::move(arg).forwardAsSingleValue(gen, Loc);
} }
@@ -2198,20 +2222,22 @@ namespace {
{ {
SILGenFunction &gen; SILGenFunction &gen;
SmallVectorImpl<SILValue> &args; SmallVectorImpl<SILValue> &args;
DeclContext *DC;
public: public:
ArgumentForwardVisitor(SILGenFunction &gen, ArgumentForwardVisitor(SILGenFunction &gen,
SmallVectorImpl<SILValue> &args) SmallVectorImpl<SILValue> &args,
: gen(gen), args(args) {} DeclContext *DC)
: gen(gen), args(args), DC(DC) {}
void makeArgument(Type ty) { void makeArgument(Type ty, VarDecl *varDecl) {
assert(ty && "no type?!"); assert(ty && "no type?!");
// Destructure tuple arguments. // Destructure tuple arguments.
if (TupleType *tupleTy = ty->getAs<TupleType>()) { if (TupleType *tupleTy = ty->getAs<TupleType>()) {
for (auto fieldType : tupleTy->getElementTypes()) for (auto fieldType : tupleTy->getElementTypes())
makeArgument(fieldType); makeArgument(fieldType, varDecl);
} else { } else {
SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty), SILValue arg = new (gen.F.getModule()) SILArgument(gen.getLoweredType(ty),
gen.F.begin()); gen.F.begin(), varDecl);
args.push_back(arg); args.push_back(arg);
} }
} }
@@ -2222,8 +2248,8 @@ namespace {
void visitTypedPattern(TypedPattern *P) { void visitTypedPattern(TypedPattern *P) {
// FIXME: work around a bug in visiting the "self" argument of methods // FIXME: work around a bug in visiting the "self" argument of methods
if (isa<NamedPattern>(P->getSubPattern())) if (auto NP = dyn_cast<NamedPattern>(P->getSubPattern()))
makeArgument(P->getType()); makeArgument(P->getType(), NP->getDecl());
else else
visit(P->getSubPattern()); visit(P->getSubPattern());
} }
@@ -2234,11 +2260,15 @@ namespace {
} }
void visitAnyPattern(AnyPattern *P) { void visitAnyPattern(AnyPattern *P) {
makeArgument(P->getType()); auto &AC = gen.getASTContext();
auto VD = new (AC) VarDecl(/*static*/ false, SourceLoc(),
// FIXME: we should probably number them.
AC.getIdentifier("_"), P->getType(), DC);
makeArgument(P->getType(), VD);
} }
void visitNamedPattern(NamedPattern *P) { void visitNamedPattern(NamedPattern *P) {
makeArgument(P->getType()); makeArgument(P->getType(), P->getDecl());
} }
#define PATTERN(Id, Parent) #define PATTERN(Id, Parent)
@@ -2295,7 +2325,7 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
SmallVector<SILValue, 8> args; SmallVector<SILValue, 8> args;
// Forward the constructor arguments. // Forward the constructor arguments.
ArgumentForwardVisitor(*this, args).visit(ctor->getBodyParams()); ArgumentForwardVisitor(*this, args, ctor).visit(ctor->getBodyParams());
emitConstructorMetatypeArg(*this, ctor); emitConstructorMetatypeArg(*this, ctor);
@@ -2391,7 +2421,8 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
emitLocalVariable(selfDecl); emitLocalVariable(selfDecl);
// Emit the prolog for the non-self arguments. // Emit the prolog for the non-self arguments.
emitProlog(ctor->getBodyParams(), TupleType::getEmpty(F.getASTContext())); emitProlog(ctor->getBodyParams(), TupleType::getEmpty(F.getASTContext()),
ctor);
SILType selfTy = getLoweredLoadableType(selfDecl->getType()); SILType selfTy = getLoweredLoadableType(selfDecl->getType());
SILValue selfArg = new (SGM.M) SILArgument(selfTy, F.begin(), selfDecl); SILValue selfArg = new (SGM.M) SILArgument(selfTy, F.begin(), selfDecl);
@@ -2538,7 +2569,7 @@ void SILGenFunction::emitCurryThunk(FuncDecl *fd,
// Forward the curried formal arguments. // Forward the curried formal arguments.
auto forwardedPatterns = fd->getBodyParamPatterns().slice(0, paramCount); auto forwardedPatterns = fd->getBodyParamPatterns().slice(0, paramCount);
ArgumentForwardVisitor forwarder(*this, curriedArgs); ArgumentForwardVisitor forwarder(*this, curriedArgs, fd);
for (auto *paramPattern : reversed(forwardedPatterns)) for (auto *paramPattern : reversed(forwardedPatterns))
forwarder.visit(paramPattern); forwarder.visit(paramPattern);
@@ -2589,7 +2620,7 @@ void SILGenFunction::emitForeignThunk(SILDeclRef thunk) {
// inputs according to the foreign convention. // inputs according to the foreign convention.
auto forwardedPatterns = fd->getBodyParamPatterns(); auto forwardedPatterns = fd->getBodyParamPatterns();
SmallVector<SILValue, 8> args; SmallVector<SILValue, 8> args;
ArgumentForwardVisitor forwarder(*this, args); ArgumentForwardVisitor forwarder(*this, args, fd);
for (auto *paramPattern : reversed(forwardedPatterns)) for (auto *paramPattern : reversed(forwardedPatterns))
forwarder.visit(paramPattern); forwarder.visit(paramPattern);
@@ -2620,7 +2651,7 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) {
RegularLocation Loc(value); RegularLocation Loc(value);
Loc.markAutoGenerated(); Loc.markAutoGenerated();
emitProlog({ }, value->getType()); emitProlog({ }, value->getType(), function.getDecl()->getDeclContext());
prepareEpilog(value->getType(), CleanupLocation::getCleanupLocation(Loc)); prepareEpilog(value->getType(), CleanupLocation::getCleanupLocation(Loc));
emitReturnExpr(Loc, value); emitReturnExpr(Loc, value);
emitEpilog(Loc); emitEpilog(Loc);

View File

@@ -448,7 +448,7 @@ public:
void emitProlog(AnyFunctionRef TheClosure, ArrayRef<Pattern*> paramPatterns, void emitProlog(AnyFunctionRef TheClosure, ArrayRef<Pattern*> paramPatterns,
Type resultType); Type resultType);
void emitProlog(ArrayRef<Pattern*> paramPatterns, void emitProlog(ArrayRef<Pattern*> paramPatterns,
Type resultType); Type resultType, DeclContext *DeclCtx);
/// \brief Create (but do not emit) the epilog branch, and save the /// \brief Create (but do not emit) the epilog branch, and save the
/// current cleanups depth as the destination for return statement branches. /// current cleanups depth as the destination for return statement branches.

View File

@@ -340,14 +340,14 @@ ClosureCloner::populateCloned() {
SILArgument *ReleaseArgument = *I++; SILArgument *ReleaseArgument = *I++;
SILValue MappedValue = SILValue MappedValue =
new (M) SILArgument((*I)->getType().getObjectType(), new (M) SILArgument((*I)->getType().getObjectType(),
ClonedEntryBB); ClonedEntryBB, (*I)->getDecl());
BoxArgumentMap.insert(std::make_pair(ReleaseArgument, MappedValue)); BoxArgumentMap.insert(std::make_pair(ReleaseArgument, MappedValue));
AddrArgumentMap.insert(std::make_pair(*I, MappedValue)); AddrArgumentMap.insert(std::make_pair(*I, MappedValue));
++ArgNo; ++ArgNo;
} else { } else {
// Otherwise, create a new argument which copies the original argument // Otherwise, create a new argument which copies the original argument
SILValue MappedValue = SILValue MappedValue =
new (M) SILArgument((*I)->getType(), ClonedEntryBB); new (M) SILArgument((*I)->getType(), ClonedEntryBB, (*I)->getDecl());
ValueMap.insert(std::make_pair(*I, MappedValue)); ValueMap.insert(std::make_pair(*I, MappedValue));
} }
++ArgNo; ++ArgNo;

View File

@@ -128,7 +128,8 @@ void TypeSubCloner::populateCloned() {
auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end(); auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end();
while (I != E) { while (I != E) {
SILValue MappedValue = SILValue MappedValue =
new (M) SILArgument(remapType((*I)->getType()), ClonedEntryBB); new (M) SILArgument(remapType((*I)->getType()), ClonedEntryBB,
(*I)->getDecl());
ValueMap.insert(std::make_pair(*I, MappedValue)); ValueMap.insert(std::make_pair(*I, MappedValue));
++I; ++I;
} }