Skip to content

Commit 7ec8133

Browse files
authored
Merge pull request #16849 from gottesmm/pr-537fd8c1a68c98da147241a4e7e958a4dfe1752d
2 parents 042d837 + b35da17 commit 7ec8133

File tree

4 files changed

+87
-150
lines changed

4 files changed

+87
-150
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 15 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,9 @@ static unsigned getElementCountRec(SILModule &Module, SILType T,
6262
}
6363

6464
static std::pair<SILType, bool>
65-
computeMemorySILType(SILInstruction *MemoryInst) {
65+
computeMemorySILType(MarkUninitializedInst *MemoryInst) {
6666
// Compute the type of the memory object.
67-
if (auto *ABI = dyn_cast<AllocBoxInst>(MemoryInst)) {
68-
assert(ABI->getBoxType()->getLayout()->getFields().size() == 1 &&
69-
"analyzing multi-field boxes not implemented");
70-
return {ABI->getBoxType()->getFieldType(MemoryInst->getModule(), 0), false};
71-
}
72-
73-
if (auto *ASI = dyn_cast<AllocStackInst>(MemoryInst)) {
74-
return {ASI->getElementType(), false};
75-
}
76-
77-
auto *MUI = cast<MarkUninitializedInst>(MemoryInst);
67+
auto *MUI = MemoryInst;
7868
SILType MemorySILType = MUI->getType().getObjectType();
7969

8070
// If this is a let variable we're initializing, remember this so we don't
@@ -89,7 +79,7 @@ computeMemorySILType(SILInstruction *MemoryInst) {
8979
return {MemorySILType, VDecl->isLet()};
9080
}
9181

92-
DIMemoryObjectInfo::DIMemoryObjectInfo(SingleValueInstruction *MI)
82+
DIMemoryObjectInfo::DIMemoryObjectInfo(MarkUninitializedInst *MI)
9383
: MemoryInst(MI) {
9484
auto &Module = MI->getModule();
9585

@@ -352,9 +342,8 @@ DIMemoryObjectInfo::getPathStringToElement(unsigned Element,
352342

353343
// If we are analyzing a variable, we can generally get the decl associated
354344
// with it.
355-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
356-
if (MUI->isVar())
357-
return MUI->getLoc().getAsASTNode<VarDecl>();
345+
if (MemoryInst->isVar())
346+
return MemoryInst->getLoc().getAsASTNode<VarDecl>();
358347

359348
// Otherwise, we can't.
360349
return nullptr;
@@ -389,23 +378,6 @@ bool DIMemoryObjectInfo::isElementLetProperty(unsigned Element) const {
389378
return false;
390379
}
391380

392-
void DIMemoryObjectInfo::collectRetainCountInfo(
393-
DIElementUseInfo &OutVar) const {
394-
if (isa<MarkUninitializedInst>(MemoryInst))
395-
return;
396-
397-
// Collect information about the retain count result as well.
398-
for (auto *Op : MemoryInst->getUses()) {
399-
auto *User = Op->getUser();
400-
401-
// If this is a release or dealloc_stack, then remember it as such.
402-
if (isa<StrongReleaseInst>(User) || isa<DeallocStackInst>(User) ||
403-
isa<DeallocBoxInst>(User) || isa<DestroyValueInst>(User)) {
404-
OutVar.trackDestroy(User);
405-
}
406-
}
407-
}
408-
409381
//===----------------------------------------------------------------------===//
410382
// DIMemoryUse Implementation
411383
//===----------------------------------------------------------------------===//
@@ -535,17 +507,10 @@ class ElementUseCollector {
535507
"Should have been handled outside of here");
536508
// If this is a class pointer, we need to look through ref_element_addrs.
537509
collectClassSelfUses();
538-
TheMemory.collectRetainCountInfo(UseInfo);
539510
return;
540511
}
541512

542-
if (auto *ABI = TheMemory.getContainer()) {
543-
collectContainerUses(ABI);
544-
} else {
545-
collectUses(TheMemory.getAddress(), 0);
546-
}
547-
548-
TheMemory.collectRetainCountInfo(UseInfo);
513+
collectUses(TheMemory.MemoryInst, 0);
549514
}
550515

551516
void trackUse(DIMemoryUse Use) { UseInfo.trackUse(Use); }
@@ -558,7 +523,6 @@ class ElementUseCollector {
558523

559524
private:
560525
void collectUses(SILValue Pointer, unsigned BaseEltNo);
561-
void collectContainerUses(AllocBoxInst *ABI);
562526
void collectClassSelfUses();
563527
void collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
564528
llvm::SmallDenseMap<VarDecl *, unsigned> &EN);
@@ -670,29 +634,6 @@ void ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
670634
collectUses(SEAI, BaseEltNo);
671635
}
672636

673-
void ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
674-
for (auto *Op : ABI->getUses()) {
675-
auto *User = Op->getUser();
676-
677-
// Deallocations and retain/release don't affect the value directly.
678-
if (isa<DeallocBoxInst>(User) || isa<StrongRetainInst>(User) ||
679-
isa<StrongReleaseInst>(User) || isa<DestroyValueInst>(User))
680-
continue;
681-
682-
if (auto *PBI = dyn_cast<ProjectBoxInst>(User)) {
683-
collectUses(PBI, PBI->getFieldIndex());
684-
continue;
685-
}
686-
687-
// Other uses of the container are considered escapes of the values.
688-
for (unsigned Field : indices(ABI->getBoxType()->getLayout()->getFields())) {
689-
addElementUses(Field,
690-
ABI->getBoxType()->getFieldType(ABI->getModule(), Field),
691-
User, DIUseKind::Escape);
692-
}
693-
}
694-
}
695-
696637
/// Return the underlying accessed pointer value. This peeks through
697638
/// begin_access patterns such as:
698639
///
@@ -1092,10 +1033,9 @@ void ElementUseCollector::collectClassSelfUses() {
10921033

10931034
// If we are looking at the init method for a root class, just walk the
10941035
// MUI use-def chain directly to find our uses.
1095-
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
1096-
if (MUI->getKind() == MarkUninitializedInst::RootSelf) {
1097-
collectClassSelfUses(TheMemory.getAddress(), TheMemory.MemorySILType,
1098-
EltNumbering);
1036+
auto *MemoryInst = TheMemory.MemoryInst;
1037+
if (MemoryInst->getKind() == MarkUninitializedInst::RootSelf) {
1038+
collectClassSelfUses(MemoryInst, TheMemory.MemorySILType, EltNumbering);
10991039
return;
11001040
}
11011041

@@ -1112,7 +1052,7 @@ void ElementUseCollector::collectClassSelfUses() {
11121052
// 4) Potential escapes after super.init, if self is closed over.
11131053
//
11141054
// Handle each of these in turn.
1115-
SmallVector<Operand *, 8> Uses(MUI->getUses());
1055+
SmallVector<Operand *, 8> Uses(MemoryInst->getUses());
11161056
while (!Uses.empty()) {
11171057
Operand *Op = Uses.pop_back_val();
11181058
SILInstruction *User = Op->getUser();
@@ -1123,7 +1063,7 @@ void ElementUseCollector::collectClassSelfUses() {
11231063
// The initial store of 'self' into the box at the start of the
11241064
// function. Ignore it.
11251065
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
1126-
if (Arg->getParent() == MUI->getParent()) {
1066+
if (Arg->getParent() == MemoryInst->getParent()) {
11271067
StoresOfArgumentToSelf++;
11281068
continue;
11291069
}
@@ -1138,7 +1078,7 @@ void ElementUseCollector::collectClassSelfUses() {
11381078
src = conversion->getConverted();
11391079

11401080
if (auto *LI = dyn_cast<LoadInst>(src))
1141-
if (LI->getOperand() == MUI)
1081+
if (LI->getOperand() == MemoryInst)
11421082
continue;
11431083

11441084
// Any other store needs to be recorded.
@@ -1548,7 +1488,7 @@ void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
15481488
// all. Just treat all members of self as uses of the single
15491489
// non-field-sensitive value.
15501490
assert(TheMemory.NumElements == 1 && "delegating inits only have 1 bit");
1551-
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
1491+
auto *MUI = TheMemory.MemoryInst;
15521492

15531493
// The number of stores of the initial 'self' argument into the self box
15541494
// that we saw.
@@ -1792,16 +1732,14 @@ void swift::ownership::collectDIElementUsesFrom(
17921732
// at all. Just treat all members of self as uses of the single
17931733
// non-field-sensitive value.
17941734
assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
1795-
auto *MUI = cast<MarkUninitializedInst>(MemoryInfo.MemoryInst);
1796-
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo, MUI);
1797-
MemoryInfo.collectRetainCountInfo(UseInfo);
1735+
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo,
1736+
MemoryInfo.MemoryInst);
17981737
return;
17991738
}
18001739

18011740
if (shouldPerformClassInitSelf(MemoryInfo)) {
18021741
DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
18031742
UseCollector.collectClassInitSelfUses();
1804-
MemoryInfo.collectRetainCountInfo(UseInfo);
18051743
return;
18061744
}
18071745

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h

Lines changed: 38 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ struct DIElementUseInfo;
5353
/// not super.init() has been called or not.
5454
class DIMemoryObjectInfo {
5555
public:
56-
/// This is the instruction that represents the memory. It is either an
57-
/// allocation (alloc_box, alloc_stack) or a mark_uninitialized.
58-
SingleValueInstruction *MemoryInst;
56+
/// The uninitialized memory that we are analyzing.
57+
MarkUninitializedInst *MemoryInst;
5958

6059
/// This is the base type of the memory allocation.
6160
SILType MemorySILType;
@@ -74,7 +73,7 @@ class DIMemoryObjectInfo {
7473
bool HasDummyElement = false;
7574

7675
public:
77-
DIMemoryObjectInfo(SingleValueInstruction *MemoryInst);
76+
DIMemoryObjectInfo(MarkUninitializedInst *MemoryInst);
7877

7978
SILLocation getLoc() const { return MemoryInst->getLoc(); }
8079
SILFunction &getFunction() const { return *MemoryInst->getFunction(); }
@@ -84,17 +83,7 @@ class DIMemoryObjectInfo {
8483

8584
CanType getType() const { return MemorySILType.getASTType(); }
8685

87-
SingleValueInstruction *getAddress() const {
88-
if (isa<MarkUninitializedInst>(MemoryInst) ||
89-
isa<AllocStackInst>(MemoryInst))
90-
return MemoryInst;
91-
assert(false);
92-
return nullptr;
93-
}
94-
95-
AllocBoxInst *getContainer() const {
96-
return dyn_cast<AllocBoxInst>(MemoryInst);
97-
}
86+
SingleValueInstruction *getAddress() const { return MemoryInst; }
9887

9988
/// getNumMemoryElements - Return the number of elements, without the extra
10089
/// "super.init" tracker in initializers of derived classes.
@@ -103,99 +92,82 @@ class DIMemoryObjectInfo {
10392
}
10493

10594
/// isAnyInitSelf - Return true if this is 'self' in any kind of initializer.
106-
bool isAnyInitSelf() const {
107-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
108-
return !MUI->isVar();
109-
return false;
110-
}
95+
bool isAnyInitSelf() const { return !MemoryInst->isVar(); }
11196

11297
/// True if the memory object is the 'self' argument of a struct initializer.
11398
bool isStructInitSelf() const {
114-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
115-
if (MUI->isRootSelf() || MUI->isCrossModuleRootSelf())
116-
if (auto decl = getType()->getAnyNominal())
117-
if (isa<StructDecl>(decl))
118-
return true;
99+
if (MemoryInst->isRootSelf() || MemoryInst->isCrossModuleRootSelf()) {
100+
if (auto decl = getType()->getAnyNominal()) {
101+
if (isa<StructDecl>(decl)) {
102+
return true;
103+
}
104+
}
105+
}
119106
return false;
120107
}
121108

122109
/// True if the memory object is the 'self' argument of a non-delegating
123110
/// cross-module struct initializer.
124111
bool isCrossModuleStructInitSelf() const {
125-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst)) {
126-
if (MUI->isCrossModuleRootSelf()) {
127-
assert(isStructInitSelf());
128-
return true;
129-
}
112+
if (MemoryInst->isCrossModuleRootSelf()) {
113+
assert(isStructInitSelf());
114+
return true;
130115
}
131116
return false;
132117
}
133118

134119
/// True if the memory object is the 'self' argument of a class initializer.
135120
bool isClassInitSelf() const {
136-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
137-
if (!MUI->isVar())
138-
if (auto decl = getType()->getAnyNominal())
139-
if (isa<ClassDecl>(decl))
140-
return true;
121+
if (!MemoryInst->isVar()) {
122+
if (auto decl = getType()->getAnyNominal()) {
123+
if (isa<ClassDecl>(decl)) {
124+
return true;
125+
}
126+
}
127+
}
141128
return false;
142129
}
143130

144131
/// True if this memory object is the 'self' of a derived class initializer.
145-
bool isDerivedClassSelf() const {
146-
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
147-
return MUI->isDerivedClassSelf();
148-
return false;
149-
}
132+
bool isDerivedClassSelf() const { return MemoryInst->isDerivedClassSelf(); }
150133

151134
/// True if this memory object is the 'self' of a derived class initializer for
152135
/// which we can assume that all ivars have been initialized.
153136
bool isDerivedClassSelfOnly() const {
154-
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
155-
return MUI->isDerivedClassSelfOnly();
156-
return false;
137+
return MemoryInst->isDerivedClassSelfOnly();
157138
}
158139

159140
/// True if this memory object is the 'self' of a derived class init method,
160141
/// regardless of whether we're tracking ivar initializations or not.
161142
bool isAnyDerivedClassSelf() const {
162-
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
163-
return MUI->isDerivedClassSelf() || MUI->isDerivedClassSelfOnly();
164-
return false;
143+
return MemoryInst->isDerivedClassSelf() ||
144+
MemoryInst->isDerivedClassSelfOnly();
165145
}
166146

167147
/// True if this memory object is the 'self' of a non-root class init method.
168148
bool isNonRootClassSelf() const {
169-
if (isClassInitSelf())
170-
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
171-
return !MUI->isRootSelf();
172-
173-
return false;
149+
return isClassInitSelf() && !MemoryInst->isRootSelf();
174150
}
175151

176152
/// isDelegatingInit - True if this is a delegating initializer, one that
177153
/// calls 'self.init'.
178154
bool isDelegatingInit() const {
179-
if (auto MUI = dyn_cast<MarkUninitializedInst>(MemoryInst))
180-
return MUI->isDelegatingSelf();
181-
return false;
155+
return MemoryInst->isDelegatingSelf();
182156
}
183157

184158
/// isNonDelegatingInit - True if this is an initializer that initializes
185159
/// stored properties.
186160
bool isNonDelegatingInit() const {
187-
if (auto *MUI = dyn_cast<MarkUninitializedInst>(MemoryInst)) {
188-
switch (MUI->getKind()) {
189-
case MarkUninitializedInst::Var:
190-
return false;
191-
case MarkUninitializedInst::RootSelf:
192-
case MarkUninitializedInst::CrossModuleRootSelf:
193-
case MarkUninitializedInst::DerivedSelf:
194-
case MarkUninitializedInst::DerivedSelfOnly:
195-
return true;
196-
case MarkUninitializedInst::DelegatingSelf:
197-
return false;
198-
}
161+
switch (MemoryInst->getKind()) {
162+
case MarkUninitializedInst::Var:
163+
return false;
164+
case MarkUninitializedInst::RootSelf:
165+
case MarkUninitializedInst::CrossModuleRootSelf:
166+
case MarkUninitializedInst::DerivedSelf:
167+
case MarkUninitializedInst::DerivedSelfOnly:
168+
return true;
169+
case MarkUninitializedInst::DelegatingSelf:
170+
return false;
199171
}
200172
return false;
201173
}
@@ -218,8 +190,6 @@ class DIMemoryObjectInfo {
218190

219191
/// If the specified value is a 'let' property in an initializer, return true.
220192
bool isElementLetProperty(unsigned Element) const;
221-
222-
void collectRetainCountInfo(DIElementUseInfo &OutVar) const;
223193
};
224194

225195
enum DIUseKind {

0 commit comments

Comments
 (0)