Skip to content

Commit b35da17

Browse files
committed
[definite-init] DI only analyzes mark_uninitialized... so eliminate more dead code and conditional checks.
rdar://40332620
1 parent 46c025a commit b35da17

File tree

2 files changed

+53
-121
lines changed

2 files changed

+53
-121
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 15 additions & 55 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;
@@ -521,11 +510,7 @@ class ElementUseCollector {
521510
return;
522511
}
523512

524-
if (auto *ABI = TheMemory.getContainer()) {
525-
collectContainerUses(ABI);
526-
} else {
527-
collectUses(TheMemory.getAddress(), 0);
528-
}
513+
collectUses(TheMemory.MemoryInst, 0);
529514
}
530515

531516
void trackUse(DIMemoryUse Use) { UseInfo.trackUse(Use); }
@@ -538,7 +523,6 @@ class ElementUseCollector {
538523

539524
private:
540525
void collectUses(SILValue Pointer, unsigned BaseEltNo);
541-
void collectContainerUses(AllocBoxInst *ABI);
542526
void collectClassSelfUses();
543527
void collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
544528
llvm::SmallDenseMap<VarDecl *, unsigned> &EN);
@@ -650,29 +634,6 @@ void ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
650634
collectUses(SEAI, BaseEltNo);
651635
}
652636

653-
void ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
654-
for (auto *Op : ABI->getUses()) {
655-
auto *User = Op->getUser();
656-
657-
// Deallocations and retain/release don't affect the value directly.
658-
if (isa<DeallocBoxInst>(User) || isa<StrongRetainInst>(User) ||
659-
isa<StrongReleaseInst>(User) || isa<DestroyValueInst>(User))
660-
continue;
661-
662-
if (auto *PBI = dyn_cast<ProjectBoxInst>(User)) {
663-
collectUses(PBI, PBI->getFieldIndex());
664-
continue;
665-
}
666-
667-
// Other uses of the container are considered escapes of the values.
668-
for (unsigned Field : indices(ABI->getBoxType()->getLayout()->getFields())) {
669-
addElementUses(Field,
670-
ABI->getBoxType()->getFieldType(ABI->getModule(), Field),
671-
User, DIUseKind::Escape);
672-
}
673-
}
674-
}
675-
676637
/// Return the underlying accessed pointer value. This peeks through
677638
/// begin_access patterns such as:
678639
///
@@ -1072,10 +1033,9 @@ void ElementUseCollector::collectClassSelfUses() {
10721033

10731034
// If we are looking at the init method for a root class, just walk the
10741035
// MUI use-def chain directly to find our uses.
1075-
auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
1076-
if (MUI->getKind() == MarkUninitializedInst::RootSelf) {
1077-
collectClassSelfUses(TheMemory.getAddress(), TheMemory.MemorySILType,
1078-
EltNumbering);
1036+
auto *MemoryInst = TheMemory.MemoryInst;
1037+
if (MemoryInst->getKind() == MarkUninitializedInst::RootSelf) {
1038+
collectClassSelfUses(MemoryInst, TheMemory.MemorySILType, EltNumbering);
10791039
return;
10801040
}
10811041

@@ -1092,7 +1052,7 @@ void ElementUseCollector::collectClassSelfUses() {
10921052
// 4) Potential escapes after super.init, if self is closed over.
10931053
//
10941054
// Handle each of these in turn.
1095-
SmallVector<Operand *, 8> Uses(MUI->getUses());
1055+
SmallVector<Operand *, 8> Uses(MemoryInst->getUses());
10961056
while (!Uses.empty()) {
10971057
Operand *Op = Uses.pop_back_val();
10981058
SILInstruction *User = Op->getUser();
@@ -1103,7 +1063,7 @@ void ElementUseCollector::collectClassSelfUses() {
11031063
// The initial store of 'self' into the box at the start of the
11041064
// function. Ignore it.
11051065
if (auto *Arg = dyn_cast<SILArgument>(SI->getSrc())) {
1106-
if (Arg->getParent() == MUI->getParent()) {
1066+
if (Arg->getParent() == MemoryInst->getParent()) {
11071067
StoresOfArgumentToSelf++;
11081068
continue;
11091069
}
@@ -1118,7 +1078,7 @@ void ElementUseCollector::collectClassSelfUses() {
11181078
src = conversion->getConverted();
11191079

11201080
if (auto *LI = dyn_cast<LoadInst>(src))
1121-
if (LI->getOperand() == MUI)
1081+
if (LI->getOperand() == MemoryInst)
11221082
continue;
11231083

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

15331493
// The number of stores of the initial 'self' argument into the self box
15341494
// that we saw.
@@ -1772,8 +1732,8 @@ void swift::ownership::collectDIElementUsesFrom(
17721732
// at all. Just treat all members of self as uses of the single
17731733
// non-field-sensitive value.
17741734
assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
1775-
auto *MUI = cast<MarkUninitializedInst>(MemoryInfo.MemoryInst);
1776-
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo, MUI);
1735+
collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo,
1736+
MemoryInfo.MemoryInst);
17771737
return;
17781738
}
17791739

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h

Lines changed: 38 additions & 66 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
}

0 commit comments

Comments
 (0)