Skip to content

Commit 68866d7

Browse files
committed
[DI] InitAccessors: Handle assign_or_init without initializations
Introduce a placeholder "init" use anchored on `assign_or_init` instruction to make sure that `handleStoreUse` gets a called and sets the kind.
1 parent 3b85840 commit 68866d7

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,8 +1209,16 @@ ElementUseCollector::collectAssignOrInitUses(PartialApplyInst *pai,
12091209
useKind);
12101210
};
12111211

1212-
for (auto *property : inst->getInitializedProperties())
1213-
addUse(property, DIUseKind::InitOrAssign);
1212+
auto initializedElts = inst->getInitializedProperties();
1213+
if (initializedElts.empty()) {
1214+
// Add a placeholder use that doesn't touch elements to make sure that
1215+
// the `assign_or_init` instruction gets the kind set when `initializes`
1216+
// list is empty.
1217+
trackUse(DIMemoryUse(User, DIUseKind::InitOrAssign, BaseEltNo, 0));
1218+
} else {
1219+
for (auto *property : initializedElts)
1220+
addUse(property, DIUseKind::InitOrAssign);
1221+
}
12141222

12151223
for (auto *property : inst->getAccessedProperties())
12161224
addUse(property, DIUseKind::Load);

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,18 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
14361436
// If this is an initialization or a normal assignment, upgrade the store to
14371437
// an initialization or assign in the uses list so that clients know about it.
14381438
if (isFullyUninitialized) {
1439-
Use.Kind = DIUseKind::Initialization;
1439+
// If this is a placeholder use of `assign_or_init` instruction,
1440+
// check whether all of the fields are initialized - if so, call a setter,
1441+
// otherwise call init accessor.
1442+
if (isa<AssignOrInitInst>(Use.Inst) && Use.NumElements == 0) {
1443+
auto allFieldsInitialized =
1444+
getAnyUninitializedMemberAtInst(Use.Inst, 0,
1445+
TheMemory.getNumElements()) == -1;
1446+
Use.Kind =
1447+
allFieldsInitialized ? DIUseKind::Set : DIUseKind::Initialization;
1448+
} else {
1449+
Use.Kind = DIUseKind::Initialization;
1450+
}
14401451
} else if (isFullyInitialized && isa<AssignByWrapperInst>(Use.Inst)) {
14411452
// If some fields are uninitialized, re-write assign_by_wrapper to assignment
14421453
// of the backing wrapper. If all fields are initialized, assign to the wrapped

0 commit comments

Comments
 (0)