diff --git a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp index 2bc9ef48d5791..70057c934a70f 100644 --- a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp +++ b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp @@ -1562,6 +1562,8 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock( return getBlockLiveness(predBlock, bitNo) == FieldSensitivePrunedLiveBlocks::IsLive::LiveOut; })) { + PRUNED_LIVENESS_LOG(llvm::dbgs() << "Marking ourself as boundary edge: bb" + << block->getDebugID() << '\n'); boundary.getBoundaryEdgeBits(block).set(bitNo); } } diff --git a/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp b/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp index c439257526236..5b913785694fb 100644 --- a/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp +++ b/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp @@ -341,7 +341,9 @@ static void convertMemoryReinitToInitForm(SILInstruction *memInst, } case SILInstructionKind::StoreInst: { auto *si = cast(memInst); - si->setOwnershipQualifier(StoreOwnershipQualifier::Init); + if (si->getOwnershipQualifier() != StoreOwnershipQualifier::Trivial) { + si->setOwnershipQualifier(StoreOwnershipQualifier::Init); + } dest = si->getDest(); break; } @@ -365,7 +367,8 @@ static bool isReinitToInitConvertibleInst(SILInstruction *memInst) { } case SILInstructionKind::StoreInst: { auto *si = cast(memInst); - return si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign; + return si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign + || si->getOwnershipQualifier() == StoreOwnershipQualifier::Trivial; } } } @@ -2158,7 +2161,7 @@ bool GatherUsesVisitor::visitUse(Operand *op) { } return true; } - + // Then handle destroy_addr specially. We want to as part of our dataflow to // ignore destroy_addr, so we need to track it separately from other uses. if (auto *dvi = dyn_cast(user)) { diff --git a/lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp b/lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp index c9cb406609181..1d5e5167a24fe 100644 --- a/lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp +++ b/lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp @@ -213,8 +213,7 @@ bool noncopyable::memInstMustInitialize(Operand *memOper) { } case SILInstructionKind::StoreInst: { auto qual = cast(memInst)->getOwnershipQualifier(); - return qual == StoreOwnershipQualifier::Init || - qual == StoreOwnershipQualifier::Trivial; + return qual == StoreOwnershipQualifier::Init; } case SILInstructionKind::BuiltinInst: { auto bi = cast(memInst); @@ -264,7 +263,9 @@ bool noncopyable::memInstMustReinitialize(Operand *memOper) { } case SILInstructionKind::StoreInst: return cast(memInst)->getOwnershipQualifier() == - StoreOwnershipQualifier::Assign; + StoreOwnershipQualifier::Assign + || cast(memInst)->getOwnershipQualifier() == + StoreOwnershipQualifier::Trivial; #define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \ case SILInstructionKind::Store##Name##Inst: \ @@ -507,6 +508,13 @@ struct SimpleTemporaryAllocStackElimVisitor // tell these projections apart from projections from earlier allocations. return state.setFinalUser(op); } + + if (auto *si = dyn_cast(user); + si && si->getOwnershipQualifier() == StoreOwnershipQualifier::Trivial) { + // Bail on trivial stores. + LLVM_DEBUG(llvm::dbgs() << "Found trivial store: " << *user); + return false; + } if (auto *cai = dyn_cast(user)) { // If we already found a copy, bail. We always only visit one of these diff --git a/test/SILGen/inlinearray_reabstraction.swift b/test/SILGen/inlinearray_reabstraction.swift new file mode 100644 index 0000000000000..ffc2de8a7df6d --- /dev/null +++ b/test/SILGen/inlinearray_reabstraction.swift @@ -0,0 +1,5 @@ +// RUN: %target-swift-emit-silgen -disable-availability-checking -verify %s + + +let a: InlineArray<_, (Int)->Int> = [{$0*2}] +print(a[0](3)) diff --git a/test/SILOptimizer/moveonly_addresschecker.sil b/test/SILOptimizer/moveonly_addresschecker.sil index faca43d204b18..a70efbba79612 100644 --- a/test/SILOptimizer/moveonly_addresschecker.sil +++ b/test/SILOptimizer/moveonly_addresschecker.sil @@ -367,9 +367,9 @@ bb0(%0 : @owned $Klass, %1 : @owned $Klass): // CHECK: bb0([[ARG0:%.*]] : ${{.*}}, [[ARG1:%.*]] : // CHECK: debug_value [[ARG0]] // CHECK: debug_value [[ARG1]] -// CHECK: destroy_addr [[ARG1]] // CHECK: [[ACCESS:%.*]] = begin_access [modify] [static] [[ARG1]] // CHECK: [[GEP:%.*]] = struct_element_addr [[ACCESS]] +// CHECK: destroy_addr [[ARG1]] // CHECK: store [[ARG0]] to [trivial] [[GEP]] // CHECK: end_access [[ACCESS]] // CHECK: } // end sil function 'myBufferViewSetter' diff --git a/test/SILOptimizer/moveonly_addresschecker_trivial_member_assign.swift b/test/SILOptimizer/moveonly_addresschecker_trivial_member_assign.swift new file mode 100644 index 0000000000000..56c584ef3e206 --- /dev/null +++ b/test/SILOptimizer/moveonly_addresschecker_trivial_member_assign.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-frontend -emit-sil -verify %s + +final class Bar { + func update() { + foo?.baz = Foo2(baz: 5) + } + var foo: Foo? = Foo() +} + +struct Foo: ~Copyable { + var baz: Foo2 = Foo2(baz: 0) +} + +struct Foo2: ~Copyable { + var baz: Int = 0 +} +