Skip to content

Commit d794125

Browse files
authored
---
yaml --- r: 343995 b: refs/heads/master-rebranch c: 5c01a11 h: refs/heads/master i: 343993: a4b4177 343991: e45ea99
1 parent 20fce4e commit d794125

36 files changed

+1038
-685
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14551455
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14561456
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14571457
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1458-
refs/heads/master-rebranch: 0aeaf7f15e7b18c346d026fa7535c5134b768d4c
1458+
refs/heads/master-rebranch: 5c01a1185d5c700347f0185ead5f24112bbb8139
14591459
refs/heads/rdar-53901732: 9bd06af3284e18a109cdbf9aa59d833b24eeca7b
14601460
refs/heads/revert-26776-subst-always-returns-a-type: 1b8e18fdd391903a348970a4c848995d4cdd789c
14611461
refs/heads/tensorflow-merge: 8b854f62f80d4476cb383d43c4aac2001dde3cec

branches/master-rebranch/include/swift/AST/Decl.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,12 +1505,13 @@ class alignas(8) _GenericContext {
15051505
TrailingWhereClause *TrailingWhere = nullptr;
15061506

15071507
/// The generic signature of this declaration.
1508-
GenericSignature *GenericSig = nullptr;
1508+
llvm::PointerIntPair<GenericSignature *, 1, bool> GenericSigAndBit;
15091509
};
15101510

15111511
class GenericContext : private _GenericContext, public DeclContext {
15121512
friend class GenericParamListRequest;
1513-
1513+
friend class GenericSignatureRequest;
1514+
15141515
protected:
15151516
GenericContext(DeclContextKind Kind, DeclContext *Parent,
15161517
GenericParamList *Params);
@@ -1534,7 +1535,8 @@ class GenericContext : private _GenericContext, public DeclContext {
15341535
/// }
15351536
/// \endcode
15361537
bool isGeneric() const { return getGenericParams() != nullptr; }
1537-
1538+
bool hasComputedGenericSignature() const;
1539+
15381540
/// Retrieve the trailing where clause for this extension, if any.
15391541
TrailingWhereClause *getTrailingWhereClause() const {
15401542
return TrailingWhere;

branches/master-rebranch/include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,27 @@ class FunctionOperatorRequest :
11601160
bool isCached() const { return true; }
11611161
};
11621162

1163+
class GenericSignatureRequest :
1164+
public SimpleRequest<GenericSignatureRequest,
1165+
GenericSignature *(GenericContext *),
1166+
CacheKind::SeparatelyCached> {
1167+
public:
1168+
using SimpleRequest::SimpleRequest;
1169+
1170+
private:
1171+
friend SimpleRequest;
1172+
1173+
// Evaluation.
1174+
llvm::Expected<GenericSignature *>
1175+
evaluate(Evaluator &evaluator, GenericContext *value) const;
1176+
1177+
public:
1178+
// Separate caching.
1179+
bool isCached() const { return true; }
1180+
Optional<GenericSignature *> getCachedResult() const;
1181+
void cacheResult(GenericSignature *value) const;
1182+
};
1183+
11631184
// Allow AnyValue to compare two Type values, even though Type doesn't
11641185
// support ==.
11651186
template<>

branches/master-rebranch/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ SWIFT_REQUEST(TypeChecker, FunctionBuilderTypeRequest, Type(ValueDecl *),
4949
Cached, NoLocationInfo)
5050
SWIFT_REQUEST(TypeChecker, FunctionOperatorRequest, OperatorDecl *(FuncDecl *),
5151
Cached, NoLocationInfo)
52+
SWIFT_REQUEST(NameLookup, GenericSignatureRequest,
53+
GenericSignature *(GenericContext *),
54+
SeparatelyCached, NoLocationInfo)
5255
SWIFT_REQUEST(TypeChecker, InferredGenericSignatureRequest,
5356
GenericSignature *(ModuleDecl *, GenericSignature *,
5457
SmallVector<GenericParamList *, 2>,

branches/master-rebranch/include/swift/SIL/BranchPropagatedUser.h

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_SIL_BRANCHPROPAGATEDUSER_H
1414
#define SWIFT_SIL_BRANCHPROPAGATEDUSER_H
1515

16+
#include "swift/Basic/LLVM.h"
1617
#include "swift/SIL/SILBasicBlock.h"
1718
#include "swift/SIL/SILInstruction.h"
1819
#include "llvm/ADT/DenseMap.h"
@@ -27,68 +28,68 @@ namespace swift {
2728
/// BranchPropagatedUser and friends break all such critical edges.
2829
class BranchPropagatedUser {
2930
using InnerTy = llvm::PointerIntPair<SILInstruction *, 1>;
30-
InnerTy User;
31+
InnerTy user;
3132

3233
public:
33-
BranchPropagatedUser(SILInstruction *I) : User(I) {
34-
assert(!isa<CondBranchInst>(I));
34+
BranchPropagatedUser(SILInstruction *inst) : user(inst) {
35+
assert(!isa<CondBranchInst>(inst));
3536
}
3637

37-
BranchPropagatedUser(CondBranchInst *I) : User(I) {}
38+
BranchPropagatedUser(CondBranchInst *cbi) : user(cbi) {}
3839

39-
BranchPropagatedUser(CondBranchInst *I, unsigned SuccessorIndex)
40-
: User(I, SuccessorIndex) {
41-
assert(SuccessorIndex == CondBranchInst::TrueIdx ||
42-
SuccessorIndex == CondBranchInst::FalseIdx);
40+
BranchPropagatedUser(CondBranchInst *cbi, unsigned successorIndex)
41+
: user(cbi, successorIndex) {
42+
assert(successorIndex == CondBranchInst::TrueIdx ||
43+
successorIndex == CondBranchInst::FalseIdx);
4344
}
4445

45-
BranchPropagatedUser(const BranchPropagatedUser &Other) : User(Other.User) {}
46-
BranchPropagatedUser &operator=(const BranchPropagatedUser &Other) {
47-
User = Other.User;
46+
BranchPropagatedUser(const BranchPropagatedUser &other) : user(other.user) {}
47+
BranchPropagatedUser &operator=(const BranchPropagatedUser &other) {
48+
user = other.user;
4849
return *this;
4950
}
5051

51-
operator SILInstruction *() { return User.getPointer(); }
52-
operator const SILInstruction *() const { return User.getPointer(); }
52+
operator SILInstruction *() { return user.getPointer(); }
53+
operator const SILInstruction *() const { return user.getPointer(); }
5354

54-
SILInstruction *getInst() const { return User.getPointer(); }
55+
SILInstruction *getInst() const { return user.getPointer(); }
5556

5657
SILBasicBlock *getParent() const {
5758
if (!isCondBranchUser()) {
5859
return getInst()->getParent();
5960
}
6061

61-
auto *CBI = cast<CondBranchInst>(getInst());
62-
unsigned Number = getCondBranchSuccessorID();
63-
if (Number == CondBranchInst::TrueIdx)
64-
return CBI->getTrueBB();
65-
return CBI->getFalseBB();
62+
auto *cbi = cast<CondBranchInst>(getInst());
63+
unsigned number = getCondBranchSuccessorID();
64+
if (number == CondBranchInst::TrueIdx)
65+
return cbi->getTrueBB();
66+
return cbi->getFalseBB();
6667
}
6768

6869
bool isCondBranchUser() const {
69-
return isa<CondBranchInst>(User.getPointer());
70+
return isa<CondBranchInst>(user.getPointer());
7071
}
7172

7273
unsigned getCondBranchSuccessorID() const {
7374
assert(isCondBranchUser());
74-
return User.getInt();
75+
return user.getInt();
7576
}
7677

7778
SILBasicBlock::iterator getIterator() const {
78-
return User.getPointer()->getIterator();
79+
return user.getPointer()->getIterator();
7980
}
8081

8182
void *getAsOpaqueValue() const {
82-
return llvm::PointerLikeTypeTraits<InnerTy>::getAsVoidPointer(User);
83+
return llvm::PointerLikeTypeTraits<InnerTy>::getAsVoidPointer(user);
8384
}
8485

8586
static BranchPropagatedUser getFromOpaqueValue(void *p) {
86-
InnerTy TmpUser =
87+
InnerTy tmpUser =
8788
llvm::PointerLikeTypeTraits<InnerTy>::getFromVoidPointer(p);
88-
if (auto *CBI = dyn_cast<CondBranchInst>(TmpUser.getPointer())) {
89-
return BranchPropagatedUser(CBI, TmpUser.getInt());
89+
if (auto *cbi = dyn_cast<CondBranchInst>(tmpUser.getPointer())) {
90+
return BranchPropagatedUser(cbi, tmpUser.getInt());
9091
}
91-
return BranchPropagatedUser(TmpUser.getPointer());
92+
return BranchPropagatedUser(tmpUser.getPointer());
9293
}
9394

9495
enum {

branches/master-rebranch/include/swift/SIL/OwnershipUtils.h

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,27 +127,50 @@ class LinearLifetimeError {
127127
}
128128
};
129129

130-
/// Returns true if:
130+
/// A class used to validate linear lifetime with respect to an SSA-like
131+
/// definition.
131132
///
132-
/// 1. No consuming uses are reachable from any other consuming use, from any
133-
/// non-consuming uses, or from the producer instruction.
134-
/// 2. The consuming use set jointly post dominates producers and all non
135-
/// consuming uses.
133+
/// This class is able to both validate that a linear lifetime has been properly
134+
/// constructed (for verification and safety purposes) as well as return to the
135+
/// caller upon failure, what the failure was. In certain cases (for instance if
136+
/// there exists a path without a non-consuming use), the class will report back
137+
/// the specific insertion points needed to insert these compensating releases.
136138
///
137-
/// \p value The value whose lifetime we are checking.
138-
/// \p consumingUses the array of users that destroy or consume a value.
139-
/// \p nonConsumingUses regular uses
140-
/// \p deadEndBlocks a cache for the dead end block computation
141-
/// \p errorBehavior If we detect an error, should we return false or hard
142-
/// error.
143-
/// \p leakingBlocks If non-null a list of blocks where the value was detected
144-
/// to leak. Can be used to insert missing destroys.
145-
LinearLifetimeError valueHasLinearLifetime(
146-
SILValue value, ArrayRef<BranchPropagatedUser> consumingUses,
147-
ArrayRef<BranchPropagatedUser> nonConsumingUses,
148-
SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
149-
DeadEndBlocks &deadEndBlocks, ownership::ErrorBehaviorKind errorBehavior,
150-
SmallVectorImpl<SILBasicBlock *> *leakingBlocks = nullptr);
139+
/// DISCUSSION: A linear lifetime consists of a starting block or instruction
140+
/// and a list of non-consuming uses and a set of consuming uses. The consuming
141+
/// uses must not be reachable from each other and jointly post-dominate all
142+
/// consuming uses as well as the defining block/instruction.
143+
class LinearLifetimeChecker {
144+
SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks;
145+
DeadEndBlocks &deadEndBlocks;
146+
147+
public:
148+
LinearLifetimeChecker(SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
149+
DeadEndBlocks &deadEndBlocks)
150+
: visitedBlocks(visitedBlocks), deadEndBlocks(deadEndBlocks) {}
151+
152+
/// Returns true if:
153+
///
154+
/// 1. No consuming uses are reachable from any other consuming use, from any
155+
/// non-consuming uses, or from the producer instruction.
156+
/// 2. The consuming use set jointly post dominates producers and all non
157+
/// consuming uses.
158+
///
159+
/// Returns false otherwise.
160+
///
161+
/// \p value The value whose lifetime we are checking.
162+
/// \p consumingUses the array of users that destroy or consume a value.
163+
/// \p nonConsumingUses regular uses
164+
/// \p errorBehavior If we detect an error, should we return false or hard
165+
/// error.
166+
/// \p leakingBlocks If non-null a list of blocks where the value was detected
167+
/// to leak. Can be used to insert missing destroys.
168+
LinearLifetimeError
169+
checkValue(SILValue value, ArrayRef<BranchPropagatedUser> consumingUses,
170+
ArrayRef<BranchPropagatedUser> nonConsumingUses,
171+
ownership::ErrorBehaviorKind errorBehavior,
172+
SmallVectorImpl<SILBasicBlock *> *leakingBlocks = nullptr);
173+
};
151174

152175
/// Returns true if v is an address or trivial.
153176
bool isValueAddressOrTrivial(SILValue v);

branches/master-rebranch/lib/AST/ASTVerifier.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,32 @@ std::pair<bool, Expr *> dispatchVisitPreExprHelper(
167167
}
168168

169169
namespace {
170-
/// Retrieve the "overridden" declaration of this declaration, but only if
171-
// it's already been computed.
172-
template<typename T>
173-
T *getOverriddenDeclIfAvailable(T *decl) {
174-
if (!decl->overriddenDeclsComputed()) return nullptr;
170+
// Retrieve the "overridden" declaration of this declaration, but only if
171+
// it's already been computed.
172+
template <typename T> T *getOverriddenDeclIfAvailable(T *decl) {
173+
if (!decl->overriddenDeclsComputed())
174+
return nullptr;
175175

176-
return cast_or_null<T>(decl->getOverriddenDecl());
177-
}
176+
return cast_or_null<T>(decl->getOverriddenDecl());
178177
}
178+
179+
// Retrieve the generic signature of the innermost context that has been forced
180+
// so far.
181+
//
182+
// This avoids kicking off the request for a generic signature in the verifier.
183+
static GenericSignature *
184+
getNearestForcedGenericSignatureOfContext(DeclContext *dc) {
185+
do {
186+
if (auto decl = dc->getAsDecl())
187+
if (auto GC = decl->getAsGenericContext())
188+
if (GC->hasComputedGenericSignature())
189+
return GC->getGenericSignature();
190+
} while ((dc = dc->getParent()));
191+
192+
return nullptr;
193+
}
194+
} // namespace
195+
179196
class Verifier : public ASTWalker {
180197
PointerUnion<ModuleDecl *, SourceFile *> M;
181198
ASTContext &Ctx;
@@ -686,14 +703,14 @@ class Verifier : public ASTWalker {
686703

687704
void pushScope(DeclContext *scope) {
688705
Scopes.push_back(scope);
689-
GenericSig.push_back(scope->getGenericSignatureOfContext());
706+
GenericSig.push_back(::getNearestForcedGenericSignatureOfContext(scope));
690707
}
691708
void pushScope(BraceStmt *scope) {
692709
Scopes.push_back(scope);
693710
}
694711
void popScope(DeclContext *scope) {
695712
assert(Scopes.back().get<DeclContext*>() == scope);
696-
assert(GenericSig.back() == scope->getGenericSignatureOfContext());
713+
assert(GenericSig.back() == ::getNearestForcedGenericSignatureOfContext(scope));
697714
Scopes.pop_back();
698715
GenericSig.pop_back();
699716
}

branches/master-rebranch/lib/AST/Decl.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -855,22 +855,14 @@ GenericParamList *GenericContext::getGenericParams() const {
855855
const_cast<GenericContext *>(this)}, nullptr);
856856
}
857857

858-
GenericSignature *GenericContext::getGenericSignature() const {
859-
if (GenericSig)
860-
return GenericSig;
861-
862-
// The signature of a Protocol is trivial (Self: TheProtocol) so let's compute
863-
// it.
864-
if (auto PD = dyn_cast<ProtocolDecl>(this)) {
865-
auto self = PD->getSelfInterfaceType()->castTo<GenericTypeParamType>();
866-
auto req =
867-
Requirement(RequirementKind::Conformance, self, PD->getDeclaredType());
868-
const_cast<GenericContext *>(this)->GenericSig
869-
= GenericSignature::get({self}, {req});
870-
return GenericSig;
871-
}
858+
bool GenericContext::hasComputedGenericSignature() const {
859+
return GenericSigAndBit.getInt();
860+
}
872861

873-
return nullptr;
862+
GenericSignature *GenericContext::getGenericSignature() const {
863+
return evaluateOrDefault(
864+
getASTContext().evaluator,
865+
GenericSignatureRequest{const_cast<GenericContext *>(this)}, nullptr);
874866
}
875867

876868
GenericEnvironment *GenericContext::getGenericEnvironment() const {
@@ -881,8 +873,9 @@ GenericEnvironment *GenericContext::getGenericEnvironment() const {
881873
}
882874

883875
void GenericContext::setGenericSignature(GenericSignature *genericSig) {
884-
assert(GenericSig == nullptr && "Generic signature cannot be changed");
885-
this->GenericSig = genericSig;
876+
assert(!GenericSigAndBit.getPointer() && "Generic signature cannot be changed");
877+
getASTContext().evaluator.cacheOutput(GenericSignatureRequest{this},
878+
std::move(genericSig));
886879
}
887880

888881
SourceRange GenericContext::getGenericTrailingWhereClauseSourceRange() const {
@@ -6159,6 +6152,10 @@ void SubscriptDecl::computeType() {
61596152

61606153
// Record the interface type.
61616154
setInterfaceType(funcTy);
6155+
6156+
// Make sure that there are no unresolved dependent types in the
6157+
// generic signature.
6158+
assert(!funcTy->findUnresolvedDependentMemberType());
61626159
}
61636160

61646161
ObjCSubscriptKind SubscriptDecl::getObjCSubscriptKind() const {
@@ -6753,6 +6750,10 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
67536750
// Compute the type of the 'self' parameter if we're created one already.
67546751
if (hasSelf)
67556752
computeSelfDeclType();
6753+
6754+
// Make sure that there are no unresolved dependent types in the
6755+
// generic signature.
6756+
assert(!funcTy->findUnresolvedDependentMemberType());
67566757
}
67576758

67586759
bool AbstractFunctionDecl::hasInlinableBodyText() const {

branches/master-rebranch/lib/AST/GenericSignatureBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,12 @@ class GenericSignatureBuilder::InferRequirementsWalker : public TypeWalker {
52965296
auto decl = ty->getAnyNominal();
52975297
if (!decl) return Action::Continue;
52985298

5299+
// FIXME: The GSB and the request evaluator both detect a cycle here if we
5300+
// force a recursive generic signature. We should look into moving cycle
5301+
// detection into the generic signature request(s) - see rdar://55263708
5302+
if (!decl->hasComputedGenericSignature())
5303+
return Action::Continue;
5304+
52995305
auto genericSig = decl->getGenericSignature();
53005306
if (!genericSig)
53015307
return Action::Continue;

0 commit comments

Comments
 (0)