Skip to content

Commit 003bd5a

Browse files
authored
Merge pull request #39736 from atrick/cse-clonecheck
CSE/OSSA avoid endless cloning and reoptimization
2 parents b6bed2a + d27d83a commit 003bd5a

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ struct OwnershipFixupContext {
7171
/// and use this to seed that new lifetime.
7272
SmallVector<Operand *, 8> allAddressUsesFromOldValue;
7373

74-
/// This is the interior pointer operand that the new value we want to RAUW
75-
/// is transitively derived from and enables us to know the underlying
76-
/// borrowed base value that we need to lifetime extend.
74+
/// This is the interior pointer (e.g. ref_element_addr)
75+
/// that the new value we want to RAUW is transitively derived from and
76+
/// enables us to know the underlying borrowed base value that we need to
77+
/// lifetime extend.
7778
///
7879
/// This is only initialized when the interior pointer has uses that must be
7980
/// replaced.
@@ -149,9 +150,15 @@ class OwnershipRAUWHelper {
149150
operator bool() const { return isValid(); }
150151
bool isValid() const { return bool(ctx) && bool(oldValue) && bool(newValue); }
151152

152-
/// Perform the actual RAUW. We require that \p newValue and \p oldValue have
153-
/// the same type at this point (in contrast to when calling
154-
/// OwnershipRAUWFixupHelper::get()).
153+
/// True if replacement requires copying the original instruction's source
154+
/// operand, creating a new borrow scope for that copy, then cloning the
155+
/// original.
156+
bool requiresCopyBorrowAndClone() const {
157+
return ctx->extraAddressFixupInfo.base;
158+
}
159+
160+
/// Perform OSSA fixup on newValue and return a fixed-up value based that can
161+
/// be used to replace all uses of oldValue.
155162
///
156163
/// This is so that we can avoid creating "forwarding" transformation
157164
/// instructions before we know if we can perform the RAUW. Any such

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,10 @@ bool CSE::processNode(DominanceInfoNode *Node) {
10331033
OwnershipRAUWHelper helper(RAUWFixupContext,
10341034
cast<SingleValueInstruction>(Inst),
10351035
cast<SingleValueInstruction>(AvailInst));
1036-
if (!helper.isValid())
1036+
// If RAUW requires cloning the original, then there's no point. If it
1037+
// also requires introducing a copy and new borrow scope, then it's a
1038+
// very bad idea.
1039+
if (!helper.isValid() || helper.requiresCopyBorrowAndClone())
10371040
continue;
10381041
// Replace SingleValueInstruction using OSSA RAUW here
10391042
nextI = helper.perform();

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,10 +1041,9 @@ OwnershipRAUWHelper::replaceAddressUses(SingleValueInstruction *oldValue,
10411041
SILValue newValue) {
10421042
assert(oldValue->getType().isAddress() && newValue->getType().isAddress());
10431043

1044-
// If we are replacing addresses, see if we need to handle interior pointer
1045-
// fixups. If we don't have any extra info, then we know that we can just RAUW
1046-
// without any further work.
1047-
if (!ctx->extraAddressFixupInfo.base)
1044+
// If newValue was not generated by an interior pointer, then it cannot
1045+
// be within a borrow scope, so direct replacement works.
1046+
if (!requiresCopyBorrowAndClone())
10481047
return replaceAllUsesAndErase(oldValue, newValue, ctx->callbacks);
10491048

10501049
// We are RAUWing two addresses and we found that:

0 commit comments

Comments
 (0)