Skip to content

Commit f6e71d4

Browse files
committed
[mem-access-utils] Refactor isSingleInitAllocStack into getSingleInitAllocStackUse and rewrite the former in terms of the first.
This enabled me to expand this API to return the underlying single init use. I want this information in OptRemarkGen.
1 parent a532697 commit f6e71d4

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,16 +1164,25 @@ namespace swift {
11641164
/// uninitialized.
11651165
bool memInstMustInitialize(Operand *memOper);
11661166

1167-
/// Is this an alloc_stack instruction that is:
1167+
/// Is this an alloc_stack instruction that we can prove is:
11681168
///
11691169
/// 1. Only initialized once in its own def block.
11701170
/// 2. Never written to again except by destroy_addr.
11711171
///
1172-
/// On return, destroyingUsers contains the list of users that destroy the
1173-
/// alloc_stack. If the alloc_stack is destroyed in pieces, we do not guarantee
1174-
/// that the list of destroying users is a minimal jointly post-dominating set.
1175-
bool isSingleInitAllocStack(AllocStackInst *asi,
1176-
SmallVectorImpl<Operand *> &destroyingUses);
1172+
/// Then we return the single initializing use and if \p destroyingUsers was
1173+
/// non-null, On return, if non-null, \p destroyingUsers contains the list of
1174+
/// users that destroy the alloc_stack. If the alloc_stack is destroyed in
1175+
/// pieces, we do not guarantee that the list of destroying users is a minimal
1176+
/// jointly post-dominating set.
1177+
Operand *getSingleInitAllocStackUse(
1178+
AllocStackInst *asi, SmallVectorImpl<Operand *> *destroyingUses = nullptr);
1179+
1180+
/// Same as getSingleInitAllocStack except we throw away the single use and just
1181+
/// provide a bool.
1182+
inline bool isSingleInitAllocStack(AllocStackInst *asi,
1183+
SmallVectorImpl<Operand *> &destroyingUses) {
1184+
return getSingleInitAllocStackUse(asi, &destroyingUses);
1185+
}
11771186

11781187
/// Return true if the given address value is produced by a special address
11791188
/// producer that is only used for local initialization, not formal access.

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,12 +1545,13 @@ bool swift::memInstMustInitialize(Operand *memOper) {
15451545
}
15461546
}
15471547

1548-
bool swift::isSingleInitAllocStack(AllocStackInst *asi,
1549-
SmallVectorImpl<Operand *> &destroyingUses) {
1548+
Operand *
1549+
swift::getSingleInitAllocStackUse(AllocStackInst *asi,
1550+
SmallVectorImpl<Operand *> *destroyingUses) {
15501551
// For now, we just look through projections and rely on memInstMustInitialize
15511552
// to classify all other uses as init or not.
15521553
SmallVector<Operand *, 32> worklist(asi->getUses());
1553-
bool foundInit = false;
1554+
Operand *singleInit = nullptr;
15541555

15551556
while (!worklist.empty()) {
15561557
auto *use = worklist.pop_back_val();
@@ -1571,14 +1572,15 @@ bool swift::isSingleInitAllocStack(AllocStackInst *asi,
15711572
continue;
15721573
}
15731574
// Treat load [take] as a write.
1574-
return false;
1575+
return nullptr;
15751576
}
15761577

15771578
switch (user->getKind()) {
15781579
default:
15791580
break;
15801581
case SILInstructionKind::DestroyAddrInst:
1581-
destroyingUses.push_back(use);
1582+
if (destroyingUses)
1583+
destroyingUses->push_back(use);
15821584
continue;
15831585
case SILInstructionKind::DeallocStackInst:
15841586
case SILInstructionKind::LoadBorrowInst:
@@ -1589,21 +1591,21 @@ bool swift::isSingleInitAllocStack(AllocStackInst *asi,
15891591
// See if we have an initializer and that such initializer is in the same
15901592
// block.
15911593
if (memInstMustInitialize(use)) {
1592-
if (user->getParent() != asi->getParent() || foundInit) {
1593-
return false;
1594+
if (user->getParent() != asi->getParent() || singleInit) {
1595+
return nullptr;
15941596
}
15951597

1596-
foundInit = true;
1598+
singleInit = use;
15971599
continue;
15981600
}
15991601

16001602
// Otherwise, if we have found something not in our allowlist, return false.
1601-
return false;
1603+
return nullptr;
16021604
}
16031605

16041606
// We did not find any users that we did not understand. So we can
1605-
// conservatively return true here.
1606-
return true;
1607+
// conservatively return the single initializing write that we found.
1608+
return singleInit;
16071609
}
16081610

16091611
/// Return true if the given address value is produced by a special address

0 commit comments

Comments
 (0)