Skip to content

Commit 4fd61ee

Browse files
authored
Merge pull request #80854 from jckarter/moveonly-trivial-field-as-reinitialize-6.2
[6.2] MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations.
2 parents 7d77c61 + 66764a3 commit 4fd61ee

6 files changed

+42
-7
lines changed

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,8 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock(
15621562
return getBlockLiveness(predBlock, bitNo) ==
15631563
FieldSensitivePrunedLiveBlocks::IsLive::LiveOut;
15641564
})) {
1565+
PRUNED_LIVENESS_LOG(llvm::dbgs() << "Marking ourself as boundary edge: bb"
1566+
<< block->getDebugID() << '\n');
15651567
boundary.getBoundaryEdgeBits(block).set(bitNo);
15661568
}
15671569
}

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ static void convertMemoryReinitToInitForm(SILInstruction *memInst,
341341
}
342342
case SILInstructionKind::StoreInst: {
343343
auto *si = cast<StoreInst>(memInst);
344-
si->setOwnershipQualifier(StoreOwnershipQualifier::Init);
344+
if (si->getOwnershipQualifier() != StoreOwnershipQualifier::Trivial) {
345+
si->setOwnershipQualifier(StoreOwnershipQualifier::Init);
346+
}
345347
dest = si->getDest();
346348
break;
347349
}
@@ -365,7 +367,8 @@ static bool isReinitToInitConvertibleInst(SILInstruction *memInst) {
365367
}
366368
case SILInstructionKind::StoreInst: {
367369
auto *si = cast<StoreInst>(memInst);
368-
return si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign;
370+
return si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign
371+
|| si->getOwnershipQualifier() == StoreOwnershipQualifier::Trivial;
369372
}
370373
}
371374
}
@@ -2159,7 +2162,7 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
21592162
}
21602163
return true;
21612164
}
2162-
2165+
21632166
// Then handle destroy_addr specially. We want to as part of our dataflow to
21642167
// ignore destroy_addr, so we need to track it separately from other uses.
21652168
if (auto *dvi = dyn_cast<DestroyAddrInst>(user)) {

lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,7 @@ bool noncopyable::memInstMustInitialize(Operand *memOper) {
213213
}
214214
case SILInstructionKind::StoreInst: {
215215
auto qual = cast<StoreInst>(memInst)->getOwnershipQualifier();
216-
return qual == StoreOwnershipQualifier::Init ||
217-
qual == StoreOwnershipQualifier::Trivial;
216+
return qual == StoreOwnershipQualifier::Init;
218217
}
219218
case SILInstructionKind::BuiltinInst: {
220219
auto bi = cast<BuiltinInst>(memInst);
@@ -264,7 +263,9 @@ bool noncopyable::memInstMustReinitialize(Operand *memOper) {
264263
}
265264
case SILInstructionKind::StoreInst:
266265
return cast<StoreInst>(memInst)->getOwnershipQualifier() ==
267-
StoreOwnershipQualifier::Assign;
266+
StoreOwnershipQualifier::Assign
267+
|| cast<StoreInst>(memInst)->getOwnershipQualifier() ==
268+
StoreOwnershipQualifier::Trivial;
268269

269270
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
270271
case SILInstructionKind::Store##Name##Inst: \
@@ -507,6 +508,13 @@ struct SimpleTemporaryAllocStackElimVisitor
507508
// tell these projections apart from projections from earlier allocations.
508509
return state.setFinalUser(op);
509510
}
511+
512+
if (auto *si = dyn_cast<StoreInst>(user);
513+
si && si->getOwnershipQualifier() == StoreOwnershipQualifier::Trivial) {
514+
// Bail on trivial stores.
515+
LLVM_DEBUG(llvm::dbgs() << "Found trivial store: " << *user);
516+
return false;
517+
}
510518

511519
if (auto *cai = dyn_cast<CopyAddrInst>(user)) {
512520
// If we already found a copy, bail. We always only visit one of these
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking -verify %s
2+
3+
4+
let a: InlineArray<_, (Int)->Int> = [{$0*2}]
5+
print(a[0](3))

test/SILOptimizer/moveonly_addresschecker.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,9 @@ bb0(%0 : @owned $Klass, %1 : @owned $Klass):
367367
// CHECK: bb0([[ARG0:%.*]] : ${{.*}}, [[ARG1:%.*]] :
368368
// CHECK: debug_value [[ARG0]]
369369
// CHECK: debug_value [[ARG1]]
370-
// CHECK: destroy_addr [[ARG1]]
371370
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [static] [[ARG1]]
372371
// CHECK: [[GEP:%.*]] = struct_element_addr [[ACCESS]]
372+
// CHECK: destroy_addr [[ARG1]]
373373
// CHECK: store [[ARG0]] to [trivial] [[GEP]]
374374
// CHECK: end_access [[ACCESS]]
375375
// CHECK: } // end sil function 'myBufferViewSetter'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s
2+
3+
final class Bar {
4+
func update() {
5+
foo?.baz = Foo2(baz: 5)
6+
}
7+
var foo: Foo? = Foo()
8+
}
9+
10+
struct Foo: ~Copyable {
11+
var baz: Foo2 = Foo2(baz: 0)
12+
}
13+
14+
struct Foo2: ~Copyable {
15+
var baz: Int = 0
16+
}
17+

0 commit comments

Comments
 (0)