Skip to content

Commit d74abf5

Browse files
committed
[DI] Add a way to find value of self in initializer context
This is staging for type wrappers that need to inject `self.$storage = ...` call to user-defined initializers, to be able to do that logic needs to be able to find `self` that is being constructed.
1 parent 9fc5bb1 commit d74abf5

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ SILInstruction *DIMemoryObjectInfo::getFunctionEntryPoint() const {
169169
return &*getFunction().begin()->begin();
170170
}
171171

172+
static SingleValueInstruction *
173+
getUninitializedValue(MarkUninitializedInst *MemoryInst) {
174+
SILValue inst = MemoryInst;
175+
if (auto *bbi = MemoryInst->getSingleUserOfType<BeginBorrowInst>()) {
176+
inst = bbi;
177+
}
178+
179+
if (SingleValueInstruction *svi =
180+
inst->getSingleUserOfType<ProjectBoxInst>()) {
181+
return svi;
182+
}
183+
184+
return MemoryInst;
185+
}
186+
187+
SingleValueInstruction *DIMemoryObjectInfo::getUninitializedValue() const {
188+
return ::getUninitializedValue(MemoryInst);
189+
}
190+
172191
/// Given a symbolic element number, return the type of the element.
173192
static SILType getElementTypeRec(TypeExpansionContext context,
174193
SILModule &Module, SILType T, unsigned EltNo,
@@ -478,6 +497,28 @@ bool DIMemoryObjectInfo::isElementLetProperty(unsigned Element) const {
478497
return false;
479498
}
480499

500+
SingleValueInstruction *DIMemoryObjectInfo::findAnyInitSelfValue() const {
501+
// If the object is 'self', return its uninitialized value.
502+
if (isAnyInitSelf())
503+
return getUninitializedValue();
504+
505+
// Otherwise we need to scan entry block to find mark_uninitialized
506+
// instruction that belongs to `self`.
507+
508+
auto *BB = getFunction().getEntryBlock();
509+
if (!BB)
510+
return nullptr;
511+
512+
for (auto &I : *BB) {
513+
SILInstruction *Inst = &I;
514+
if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) {
515+
if (!MUI->isVar())
516+
return ::getUninitializedValue(MUI);
517+
}
518+
}
519+
return nullptr;
520+
}
521+
481522
ConstructorDecl *DIMemoryObjectInfo::getActorInitSelf() const {
482523
// is it 'self'?
483524
if (!MemoryInst->isVar())

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,7 @@ class DIMemoryObjectInfo {
100100
/// alloc_stack, this always just returns the actual mark_uninitialized
101101
/// instruction. For alloc_box though it returns the project_box associated
102102
/// with the memory info.
103-
SingleValueInstruction *getUninitializedValue() const {
104-
if (IsBox) {
105-
SILValue inst = MemoryInst;
106-
if (auto *bbi = MemoryInst->getSingleUserOfType<BeginBorrowInst>()) {
107-
inst = bbi;
108-
}
109-
// TODO: consider just storing the ProjectBoxInst in this case.
110-
SingleValueInstruction *svi = inst->getSingleUserOfType<ProjectBoxInst>();
111-
assert(svi);
112-
return svi;
113-
}
114-
return MemoryInst;
115-
}
103+
SingleValueInstruction *getUninitializedValue() const;
116104

117105
/// Return the number of elements, without the extra "super.init" tracker in
118106
/// initializers of derived classes.
@@ -130,6 +118,10 @@ class DIMemoryObjectInfo {
130118
/// Return true if this is 'self' in any kind of initializer.
131119
bool isAnyInitSelf() const { return !MemoryInst->isVar(); }
132120

121+
/// Return uninitialized value of 'self' if current memory object
122+
/// is located in an initializer (of any kind).
123+
SingleValueInstruction *findAnyInitSelfValue() const;
124+
133125
/// True if the memory object is the 'self' argument of a struct initializer.
134126
bool isStructInitSelf() const {
135127
if (MemoryInst->isRootSelf() || MemoryInst->isCrossModuleRootSelf()) {

0 commit comments

Comments
 (0)