1212
1313#include " swift/SILOptimizer/Analysis/ArraySemantic.h"
1414#include " swift/SIL/DebugUtils.h"
15+ #include " swift/SIL/InstructionUtils.h"
1516#include " swift/SIL/SILArgument.h"
1617#include " swift/SIL/SILBuilder.h"
1718#include " swift/SIL/SILFunction.h"
@@ -295,6 +296,10 @@ static bool canHoistArrayArgument(ApplyInst *SemanticsCall, SILValue Arr,
295296 if (DT->dominates (SelfBB, InsertBefore->getParent ()))
296297 return true ;
297298
299+ if (auto *Copy = dyn_cast<CopyValueInst>(SelfVal)) {
300+ // look through one level
301+ SelfVal = Copy->getOperand ();
302+ }
298303 if (auto LI = dyn_cast<LoadInst>(SelfVal)) {
299304 // Are we loading a value from an address in a struct defined at a point
300305 // dominating the hoist point.
@@ -354,18 +359,28 @@ bool swift::ArraySemanticsCall::canHoist(SILInstruction *InsertBefore,
354359 return false ;
355360}
356361
357- // / Copy the array load to the insert point.
358- static SILValue copyArrayLoad (SILValue ArrayStructValue,
359- SILInstruction *InsertBefore,
360- DominanceInfo *DT) {
362+ // / Copy the array self value to the insert point.
363+ static SILValue copySelfValue (SILValue ArrayStructValue,
364+ SILInstruction *InsertBefore, DominanceInfo *DT) {
365+ auto *func = InsertBefore-> getFunction ();
361366 if (DT->dominates (ArrayStructValue->getParentBlock (),
362- InsertBefore->getParent ()))
367+ InsertBefore->getParent ())) {
368+ assert (!func->hasOwnership () ||
369+ ArrayStructValue.getOwnershipKind () == OwnershipKind::Owned ||
370+ ArrayStructValue.getOwnershipKind () == OwnershipKind::Guaranteed);
363371 return ArrayStructValue;
372+ }
364373
365- auto *LI = cast<LoadInst>(ArrayStructValue);
374+ assert (!func->hasOwnership () ||
375+ ArrayStructValue.getOwnershipKind () == OwnershipKind::Owned);
366376
367- // Recursively move struct_element_addr.
368- ValueBase *Val = LI->getOperand ();
377+ SILValue Val;
378+ if (auto *Load = dyn_cast<LoadInst>(ArrayStructValue)) {
379+ Val = Load->getOperand ();
380+ } else {
381+ auto *Copy = cast<CopyValueInst>(ArrayStructValue);
382+ Val = cast<LoadInst>(Copy->getOperand ())->getOperand ();
383+ }
369384 auto *InsertPt = InsertBefore;
370385 while (!DT->dominates (Val->getParentBlock (), InsertBefore->getParent ())) {
371386 auto *Inst = cast<StructElementAddrInst>(Val);
@@ -374,7 +389,16 @@ static SILValue copyArrayLoad(SILValue ArrayStructValue,
374389 InsertPt = Inst;
375390 }
376391
377- return cast<LoadInst>(LI->clone (InsertBefore));
392+ if (!ArrayStructValue->getFunction ()->hasOwnership ()) {
393+ return cast<LoadInst>(ArrayStructValue)->clone (InsertBefore);
394+ }
395+ if (auto *Load = dyn_cast<LoadInst>(ArrayStructValue)) {
396+ return Load->clone (InsertBefore);
397+ }
398+ auto *Copy = cast<CopyValueInst>(ArrayStructValue);
399+ auto Addr = cast<LoadInst>(Copy->getOperand ())->getOperand ();
400+ return SILBuilderWithScope (InsertPt).createLoad (InsertPt->getLoc (), Addr,
401+ LoadOwnershipQualifier::Copy);
378402}
379403
380404static ApplyInst *hoistOrCopyCall (ApplyInst *AI, SILInstruction *InsertBefore,
@@ -404,17 +428,16 @@ static SILValue hoistOrCopySelf(ApplyInst *SemanticsCall,
404428
405429 auto Self = SemanticsCall->getSelfArgument ();
406430 bool IsOwnedSelf = SelfConvention == ParameterConvention::Direct_Owned;
431+ auto *Func = SemanticsCall->getFunction ();
407432
408433 // Emit matching release for owned self if we are moving the original call.
409434 if (!LeaveOriginal && IsOwnedSelf) {
410435 SILBuilderWithScope Builder (SemanticsCall);
411- Builder.createReleaseValue (SemanticsCall->getLoc (), Self, Builder. getDefaultAtomicity () );
436+ Builder.emitDestroyValueOperation (SemanticsCall->getLoc (), Self);
412437 }
413-
414- auto NewArrayStructValue = copyArrayLoad (Self, InsertBefore, DT);
415-
416- // Retain the array.
417- if (IsOwnedSelf) {
438+ auto NewArrayStructValue = copySelfValue (Self, InsertBefore, DT);
439+ if (!Func->hasOwnership () && IsOwnedSelf) {
440+ // Retain the array.
418441 SILBuilderWithScope Builder (InsertBefore, SemanticsCall);
419442 Builder.createRetainValue (SemanticsCall->getLoc (), NewArrayStructValue,
420443 Builder.getDefaultAtomicity ());
@@ -512,8 +535,7 @@ void swift::ArraySemanticsCall::removeCall() {
512535 if (getSelfParameterConvention (SemanticsCall) ==
513536 ParameterConvention::Direct_Owned) {
514537 SILBuilderWithScope Builder (SemanticsCall);
515- Builder.createReleaseValue (SemanticsCall->getLoc (), getSelf (),
516- Builder.getDefaultAtomicity ());
538+ Builder.emitDestroyValueOperation (SemanticsCall->getLoc (), getSelf ());
517539 }
518540
519541 switch (getKind ()) {
0 commit comments