SIL: Remove uncurryLevel from SILDeclRef

All we need to store is whether the SILDeclRef directly
references the declaration, or if it references a curry
thunk, and we already have an isCurried bit for that.
This commit is contained in:
Slava Pestov
2017-05-08 01:07:36 -07:00
parent 59ed555b09
commit edb1e97a35
14 changed files with 106 additions and 167 deletions

View File

@@ -237,84 +237,52 @@ static unsigned getFuncNaturalUncurryLevel(AnyFunctionRef AFR) {
return Level;
}
SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
ResilienceExpansion expansion,
unsigned atUncurryLevel, bool isForeign)
: loc(vd), kind(kind), Expansion(unsigned(expansion)),
isForeign(isForeign), isDirectReference(0), defaultArgIndex(0)
{
unsigned naturalUncurryLevel;
// FIXME: restructure to use a "switch".
unsigned swift::getNaturalUncurryLevel(ValueDecl *vd) {
if (auto *func = dyn_cast<FuncDecl>(vd)) {
assert(kind == Kind::Func &&
"can only create a Func SILDeclRef for a func decl");
naturalUncurryLevel = getFuncNaturalUncurryLevel(func);
return getFuncNaturalUncurryLevel(func);
} else if (isa<ConstructorDecl>(vd)) {
assert((kind == Kind::Allocator || kind == Kind::Initializer)
&& "can only create Allocator or Initializer SILDeclRef for ctor");
naturalUncurryLevel = 1;
return 1;
} else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
assert(kind == Kind::EnumElement
&& "can only create EnumElement SILDeclRef for enum element");
naturalUncurryLevel = ed->getArgumentInterfaceType() ? 1 : 0;
return ed->getArgumentInterfaceType() ? 1 : 0;
} else if (isa<DestructorDecl>(vd)) {
assert((kind == Kind::Destroyer || kind == Kind::Deallocator)
&& "can only create destroyer/deallocator SILDeclRef for dtor");
naturalUncurryLevel = 0;
return 0;
} else if (isa<ClassDecl>(vd)) {
assert((kind == Kind::IVarInitializer || kind == Kind::IVarDestroyer) &&
"can only create ivar initializer/destroyer SILDeclRef for class");
naturalUncurryLevel = 1;
} else if (auto *var = dyn_cast<VarDecl>(vd)) {
assert((kind == Kind::GlobalAccessor ||
kind == Kind::GlobalGetter ||
kind == Kind::StoredPropertyInitializer) &&
"can only create GlobalAccessor, GlobalGetter or "
"StoredPropertyInitializer SILDeclRef for var");
naturalUncurryLevel = 0;
assert(!var->getDeclContext()->isLocalContext() &&
"can't reference local var as global var");
assert(var->hasStorage() && "can't reference computed var as global var");
(void)var;
return 1;
} else if (isa<VarDecl>(vd)) {
return 0;
} else {
llvm_unreachable("Unhandled ValueDecl for SILDeclRef");
}
assert((atUncurryLevel == ConstructAtNaturalUncurryLevel
|| atUncurryLevel <= naturalUncurryLevel)
&& "can't emit SILDeclRef below natural uncurry level");
uncurryLevel = atUncurryLevel == ConstructAtNaturalUncurryLevel
? naturalUncurryLevel
: atUncurryLevel;
isCurried = uncurryLevel != naturalUncurryLevel;
}
SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
ResilienceExpansion expansion,
bool isCurried, bool isForeign)
: loc(vd), kind(kind), Expansion(unsigned(expansion)),
isCurried(isCurried), isForeign(isForeign),
isDirectReference(0), defaultArgIndex(0)
{}
SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
ResilienceExpansion expansion,
unsigned atUncurryLevel, bool asForeign)
: isDirectReference(0), defaultArgIndex(0)
bool isCurried, bool asForeign)
: isCurried(isCurried), isDirectReference(0), defaultArgIndex(0)
{
unsigned naturalUncurryLevel;
if (auto *vd = baseLoc.dyn_cast<ValueDecl*>()) {
if (auto *fd = dyn_cast<FuncDecl>(vd)) {
// Map FuncDecls directly to Func SILDeclRefs.
loc = fd;
kind = Kind::Func;
naturalUncurryLevel = getFuncNaturalUncurryLevel(fd);
}
// Map ConstructorDecls to the Allocator SILDeclRef of the constructor.
else if (auto *cd = dyn_cast<ConstructorDecl>(vd)) {
loc = cd;
kind = Kind::Allocator;
naturalUncurryLevel = 1;
}
// Map EnumElementDecls to the EnumElement SILDeclRef of the element.
else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
loc = ed;
kind = Kind::EnumElement;
naturalUncurryLevel = ed->getArgumentInterfaceType() ? 1 : 0;
}
// VarDecl constants require an explicit kind.
else if (isa<VarDecl>(vd)) {
@@ -324,7 +292,6 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
else if (auto dtor = dyn_cast<DestructorDecl>(vd)) {
loc = dtor;
kind = Kind::Deallocator;
naturalUncurryLevel = 0;
}
else {
llvm_unreachable("invalid loc decl for SILDeclRef!");
@@ -334,21 +301,11 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
kind = Kind::Func;
assert(ACE->getParameterLists().size() >= 1 &&
"no param patterns for function?!");
naturalUncurryLevel = getFuncNaturalUncurryLevel(ACE);
} else {
llvm_unreachable("impossible SILDeclRef loc");
}
// Set the uncurry level.
assert((atUncurryLevel == ConstructAtNaturalUncurryLevel
|| atUncurryLevel <= naturalUncurryLevel)
&& "can't emit SILDeclRef below natural uncurry level");
uncurryLevel = atUncurryLevel == ConstructAtNaturalUncurryLevel
? naturalUncurryLevel
: atUncurryLevel;
Expansion = (unsigned) expansion;
isCurried = uncurryLevel != naturalUncurryLevel;
isForeign = asForeign;
}
@@ -794,7 +751,7 @@ SILDeclRef SILDeclRef::getOverridden() const {
if (!overridden)
return SILDeclRef();
return SILDeclRef(overridden, kind, getResilienceExpansion(), uncurryLevel);
return SILDeclRef(overridden, kind, getResilienceExpansion(), isCurried);
}
SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const {
@@ -878,3 +835,13 @@ SubclassScope SILDeclRef::getSubclassScope() const {
llvm_unreachable("Unhandled Accessibility in switch.");
}
unsigned SILDeclRef::getUncurryLevel() const {
if (isCurried)
return 0;
if (!hasDecl())
return getFuncNaturalUncurryLevel(*getAnyFunctionRef());
if (kind == Kind::DefaultArgGenerator)
return 0;
return getNaturalUncurryLevel(getDecl());
}