Remove the redundant DeclCtx field in SILFunction.

In all cases the DeclCtx field was supposed to be initialized from the
SILLocation of the function, so we can save one pointer per
SILFunction.

There is one test case change where a different (more precise)
diagnostic is being generated after this change.
This commit is contained in:
Adrian Prantl
2017-02-06 10:11:07 -08:00
parent 076a64eb08
commit 4d1ae142c6
14 changed files with 78 additions and 108 deletions

View File

@@ -136,9 +136,6 @@ private:
/// function references.
BlockListType BlockList;
/// The declcontext of this function.
DeclContext *DeclCtx;
/// The owning declaration of this function's clang node, if applicable.
ValueDecl *ClangNodeOwner = nullptr;
@@ -218,35 +215,25 @@ private:
/// after the pass runs, we only see a semantic-arc world.
bool HasQualifiedOwnership = true;
SILFunction(SILModule &module, SILLinkage linkage,
StringRef mangledName, CanSILFunctionType loweredType,
GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
IsFragile_t isFragile,
IsThunk_t isThunk,
ClassVisibility_t classVisibility,
Inline_t inlineStrategy, EffectsKind E,
SILFunction *insertBefore,
const SILDebugScope *debugScope,
DeclContext *DC);
SILFunction(SILModule &module, SILLinkage linkage, StringRef mangledName,
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
IsTransparent_t isTrans, IsFragile_t isFragile, IsThunk_t isThunk,
ClassVisibility_t classVisibility, Inline_t inlineStrategy,
EffectsKind E, SILFunction *insertBefore,
const SILDebugScope *debugScope);
static SILFunction *create(SILModule &M, SILLinkage linkage, StringRef name,
CanSILFunctionType loweredType,
GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
IsFragile_t isFragile,
static SILFunction *
create(SILModule &M, SILLinkage linkage, StringRef name,
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
IsTransparent_t isTrans, IsFragile_t isFragile,
IsThunk_t isThunk = IsNotThunk,
ClassVisibility_t classVisibility = NotRelevant,
Inline_t inlineStrategy = InlineDefault,
EffectsKind EffectsKindAttr =
EffectsKind::Unspecified,
EffectsKind EffectsKindAttr = EffectsKind::Unspecified,
SILFunction *InsertBefore = nullptr,
const SILDebugScope *DebugScope = nullptr,
DeclContext *DC = nullptr);
const SILDebugScope *DebugScope = nullptr);
public:
~SILFunction();
@@ -439,10 +426,9 @@ public:
bool isExternallyUsedSymbol() const;
/// Get the DeclContext of this function. (Debug info only).
DeclContext *getDeclContext() const { return DeclCtx; }
void setDeclContext(Decl *D);
void setDeclContext(Expr *E);
void setDeclCtx(DeclContext *D) { DeclCtx = D; }
DeclContext *getDeclContext() const {
return getLocation().getAsDeclContext();
}
/// \returns True if the function is marked with the @_semantics attribute
/// and has special semantics that the optimizer can use to optimize the

View File

@@ -400,6 +400,9 @@ public:
return getNodeAs<T>(Loc.ASTNode.ForDebugger);
}
/// Return the location as a DeclContext or null.
DeclContext *getAsDeclContext() const;
SourceLoc getDebugSourceLoc() const;
SourceLoc getSourceLoc() const;
SourceLoc getStartSourceLoc() const;

View File

@@ -486,7 +486,7 @@ public:
Inline_t inlineStrategy = InlineDefault,
EffectsKind EK = EffectsKind::Unspecified,
SILFunction *InsertBefore = nullptr,
const SILDebugScope *DebugScope = nullptr, DeclContext *DC = nullptr);
const SILDebugScope *DebugScope = nullptr);
/// Look up the SILWitnessTable representing the lowering of a protocol
/// conformance, and collect the substitutions to apply to the referenced

View File

@@ -52,20 +52,13 @@ void SILFunction::addSpecializeAttr(SILSpecializeAttr *Attr) {
}
}
SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
StringRef name,
CanSILFunctionType loweredType,
GenericEnvironment *genericEnv,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
IsFragile_t isFragile,
IsThunk_t isThunk,
ClassVisibility_t classVisibility,
Inline_t inlineStrategy, EffectsKind E,
SILFunction *insertBefore,
const SILDebugScope *debugScope,
DeclContext *DC) {
SILFunction *SILFunction::create(
SILModule &M, SILLinkage linkage, StringRef name,
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
Optional<SILLocation> loc, IsBare_t isBareSILFunction,
IsTransparent_t isTrans, IsFragile_t isFragile, IsThunk_t isThunk,
ClassVisibility_t classVisibility, Inline_t inlineStrategy, EffectsKind E,
SILFunction *insertBefore, const SILDebugScope *debugScope) {
// Get a StringMapEntry for the function. As a sop to error cases,
// allow the name to have an empty string.
llvm::StringMapEntry<SILFunction*> *entry = nullptr;
@@ -75,11 +68,10 @@ SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
name = entry->getKey();
}
auto fn = new (M) SILFunction(M, linkage, name,
loweredType, genericEnv, loc,
auto fn = new (M)
SILFunction(M, linkage, name, loweredType, genericEnv, loc,
isBareSILFunction, isTrans, isFragile, isThunk,
classVisibility, inlineStrategy, E,
insertBefore, debugScope, DC);
classVisibility, inlineStrategy, E, insertBefore, debugScope);
if (entry) entry->setValue(fn);
return fn;
@@ -93,11 +85,11 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
IsThunk_t isThunk, ClassVisibility_t classVisibility,
Inline_t inlineStrategy, EffectsKind E,
SILFunction *InsertBefore,
const SILDebugScope *DebugScope, DeclContext *DC)
const SILDebugScope *DebugScope)
: Module(Module), Name(Name), LoweredType(LoweredType),
GenericEnv(genericEnv), DeclCtx(DC), DebugScope(DebugScope),
Bare(isBareSILFunction), Transparent(isTrans), Fragile(isFragile),
Thunk(isThunk), ClassVisibility(classVisibility), GlobalInitFlag(false),
GenericEnv(genericEnv), DebugScope(DebugScope), Bare(isBareSILFunction),
Transparent(isTrans), Fragile(isFragile), Thunk(isThunk),
ClassVisibility(classVisibility), GlobalInitFlag(false),
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
KeepAsPublic(false), EffectsKindAttr(E) {
if (InsertBefore)
@@ -138,25 +130,6 @@ SILFunction::~SILFunction() {
"Function cannot be deleted while function_ref's still exist");
}
void SILFunction::setDeclContext(Decl *D) {
if (!D)
return;
switch (D->getKind()) {
// These four dual-inherit from DeclContext.
case DeclKind::Func: DeclCtx = cast<FuncDecl>(D); break;
case DeclKind::Constructor: DeclCtx = cast<ConstructorDecl>(D); break;
case DeclKind::Extension: DeclCtx = cast<ExtensionDecl>(D); break;
case DeclKind::Destructor: DeclCtx = cast<DestructorDecl>(D); break;
default:
DeclCtx = D->getDeclContext();
}
assert(DeclCtx);
}
void SILFunction::setDeclContext(Expr *E) {
DeclCtx = dyn_cast_or_null<AbstractClosureExpr>(E);
}
bool SILFunction::hasForeignBody() const {
if (!hasClangNode()) return false;
return SILDeclRef::isClangGenerated(getClangNode());

View File

@@ -126,6 +126,24 @@ SourceLoc SILLocation::getEndSourceLoc(ASTNodeTy N) const {
llvm_unreachable("impossible SILLocation");
}
DeclContext *SILLocation::getAsDeclContext() const {
if (!isASTNode())
return nullptr;
if (auto *D = getAsASTNode<Decl>())
switch (D->getKind()) {
// These four dual-inherit from DeclContext.
case DeclKind::Func: return cast<FuncDecl>(D);
case DeclKind::Constructor: return cast<ConstructorDecl>(D);
case DeclKind::Extension: return cast<ExtensionDecl>(D);
case DeclKind::Destructor: return cast<DestructorDecl>(D);
default: return D->getDeclContext();
}
if (auto *E = getAsASTNode<Expr>())
if (auto *DC = dyn_cast<AbstractClosureExpr>(E))
return DC;
return nullptr;
}
SILLocation::DebugLoc SILLocation::decode(SourceLoc Loc,
const SourceManager &SM) {
DebugLoc DL;

View File

@@ -366,8 +366,6 @@ SILFunction *SILModule::getOrCreateFunction(SILLocation loc,
None, IsNotBare, IsTrans, IsFrag, IsNotThunk,
getClassVisibility(constant),
inlineStrategy, EK);
if (forDefinition == ForDefinition_t::ForDefinition)
F->setDebugScope(new (*this) SILDebugScope(loc, F));
F->setGlobalInit(constant.isGlobal());
@@ -393,8 +391,6 @@ SILFunction *SILModule::getOrCreateFunction(SILLocation loc,
}
}
F->setDeclContext(constant.hasDecl() ? constant.getDecl() : nullptr);
// If this function has a self parameter, make sure that it has a +0 calling
// convention. This cannot be done for general function types, since
// function_ref's SILFunctionTypes do not have archetypes associated with
@@ -429,11 +425,11 @@ SILFunction *SILModule::createFunction(
IsBare_t isBareSILFunction, IsTransparent_t isTrans, IsFragile_t isFragile,
IsThunk_t isThunk, SILFunction::ClassVisibility_t classVisibility,
Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore,
const SILDebugScope *DebugScope, DeclContext *DC) {
return SILFunction::create(*this, linkage, name, loweredType,
genericEnv, loc, isBareSILFunction,
isTrans, isFragile, isThunk, classVisibility,
inlineStrategy, EK, InsertBefore, DebugScope, DC);
const SILDebugScope *DebugScope) {
return SILFunction::create(*this, linkage, name, loweredType, genericEnv, loc,
isBareSILFunction, isTrans, isFragile, isThunk,
classVisibility, inlineStrategy, EK, InsertBefore,
DebugScope);
}
const IntrinsicInfo &SILModule::getIntrinsicInfo(Identifier ID) {

View File

@@ -492,7 +492,9 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
return emitted;
// Note: Do not provide any SILLocation. You can set it afterwards.
auto *F = M.getOrCreateFunction((Decl*)nullptr, constant, forDefinition);
auto *F = M.getOrCreateFunction(constant.hasDecl() ? constant.getDecl()
: (Decl *)nullptr,
constant, forDefinition);
assert(F && "SILFunction should have been defined");
@@ -596,7 +598,6 @@ void SILGenModule::preEmitFunction(SILDeclRef constant,
// Create a debug scope for the function using astNode as source location.
F->setDebugScope(new (M) SILDebugScope(Loc, F));
F->setDeclContext(astNode);
DEBUG(llvm::dbgs() << "lowering ";
F->printName(llvm::dbgs());

View File

@@ -455,7 +455,6 @@ ClosureCloner::initCloned(SILFunction *Orig, IsFragile_t Fragile,
if (Orig->hasUnqualifiedOwnership()) {
Fn->setUnqualifiedOwnership();
}
Fn->setDeclCtx(Orig->getDeclContext());
return Fn;
}

View File

@@ -250,11 +250,10 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI,
OrigF->isTransparent(), Fragile, OrigF->isThunk(),
OrigF->getClassVisibility(), OrigF->getInlineStrategy(),
OrigF->getEffectsKind(),
/*InsertBefore*/ OrigF, OrigF->getDebugScope(), OrigF->getDeclContext());
/*InsertBefore*/ OrigF, OrigF->getDebugScope());
if (OrigF->hasUnqualifiedOwnership()) {
NewF->setUnqualifiedOwnership();
}
NewF->setDeclCtx(OrigF->getDeclContext());
DEBUG(llvm::dbgs() << " Specialize callee as ";
NewF->printName(llvm::dbgs()); llvm::dbgs() << " " << NewFTy << "\n");

View File

@@ -559,7 +559,6 @@ ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc,
ClosureUser->isThunk(), ClosureUser->getClassVisibility(),
ClosureUser->getInlineStrategy(), ClosureUser->getEffectsKind(),
ClosureUser, ClosureUser->getDebugScope());
Fn->setDeclCtx(ClosureUser->getDeclContext());
if (ClosureUser->hasUnqualifiedOwnership()) {
Fn->setUnqualifiedOwnership();
}

View File

@@ -591,7 +591,6 @@ SILFunction *PromotedParamCloner::initCloned(SILFunction *Orig,
if (Orig->hasUnqualifiedOwnership()) {
Fn->setUnqualifiedOwnership();
}
Fn->setDeclCtx(Orig->getDeclContext());
return Fn;
}

View File

@@ -487,18 +487,17 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
DEBUG(llvm::dbgs() << " -> create specialized function " << Name << "\n");
NewF = M.createFunction(
linkage, Name, createOptimizedSILFunctionType(), nullptr,
F->getLocation(), F->isBare(), F->isTransparent(), F->isFragile(),
F->isThunk(), F->getClassVisibility(), F->getInlineStrategy(),
F->getEffectsKind(), nullptr, F->getDebugScope(), F->getDeclContext());
NewF = M.createFunction(linkage, Name, createOptimizedSILFunctionType(),
nullptr, F->getLocation(), F->isBare(),
F->isTransparent(), F->isFragile(), F->isThunk(),
F->getClassVisibility(), F->getInlineStrategy(),
F->getEffectsKind(), nullptr, F->getDebugScope());
if (F->hasUnqualifiedOwnership()) {
NewF->setUnqualifiedOwnership();
}
// Then we transfer the body of F to NewF.
NewF->spliceBody(F);
NewF->setDeclCtx(F->getDeclContext());
// Array semantic clients rely on the signature being as in the original
// version.

View File

@@ -40,12 +40,10 @@ SILFunction *GenericCloner::initCloned(SILFunction *Orig,
// Create a new empty function.
SILFunction *NewF = Orig->getModule().createFunction(
getSpecializedLinkage(Orig, Orig->getLinkage()), NewName,
ReInfo.getSpecializedType(), nullptr,
Orig->getLocation(), Orig->isBare(), Orig->isTransparent(),
Fragile, Orig->isThunk(), Orig->getClassVisibility(),
Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig,
Orig->getDebugScope(), Orig->getDeclContext());
NewF->setDeclCtx(Orig->getDeclContext());
ReInfo.getSpecializedType(), nullptr, Orig->getLocation(), Orig->isBare(),
Orig->isTransparent(), Fragile, Orig->isThunk(),
Orig->getClassVisibility(), Orig->getInlineStrategy(),
Orig->getEffectsKind(), Orig, Orig->getDebugScope());
for (auto &Attr : Orig->getSemanticsAttrs()) {
NewF->addSemanticsAttr(Attr);
}

View File

@@ -863,7 +863,7 @@ struct LetProperties {
arr = []
arr += [] // expected-error {{mutating operator '+=' may not be used on immutable value 'self.arr'}}
arr.append(4) // expected-error {{mutating method 'append' may not be used on immutable value 'self.arr'}}
arr[12] = 17 // expected-error {{immutable value 'self.arr' may not be assigned to}}
arr[12] = 17 // expected-error {{mutating subscript 'subscript' may not be used on immutable value 'self.arr'}}
}
}