12
12
13
13
#include " swift/SILOptimizer/Analysis/ArraySemantic.h"
14
14
#include " swift/SIL/DebugUtils.h"
15
+ #include " swift/SIL/InstructionUtils.h"
15
16
#include " swift/SIL/SILArgument.h"
16
17
#include " swift/SIL/SILBuilder.h"
17
18
#include " swift/SIL/SILFunction.h"
@@ -295,6 +296,10 @@ static bool canHoistArrayArgument(ApplyInst *SemanticsCall, SILValue Arr,
295
296
if (DT->dominates (SelfBB, InsertBefore->getParent ()))
296
297
return true ;
297
298
299
+ if (auto *Copy = dyn_cast<CopyValueInst>(SelfVal)) {
300
+ // look through one level
301
+ SelfVal = Copy->getOperand ();
302
+ }
298
303
if (auto LI = dyn_cast<LoadInst>(SelfVal)) {
299
304
// Are we loading a value from an address in a struct defined at a point
300
305
// dominating the hoist point.
@@ -354,18 +359,28 @@ bool swift::ArraySemanticsCall::canHoist(SILInstruction *InsertBefore,
354
359
return false ;
355
360
}
356
361
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 ();
361
366
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);
363
371
return ArrayStructValue;
372
+ }
364
373
365
- auto *LI = cast<LoadInst>(ArrayStructValue);
374
+ assert (!func->hasOwnership () ||
375
+ ArrayStructValue.getOwnershipKind () == OwnershipKind::Owned);
366
376
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
+ }
369
384
auto *InsertPt = InsertBefore;
370
385
while (!DT->dominates (Val->getParentBlock (), InsertBefore->getParent ())) {
371
386
auto *Inst = cast<StructElementAddrInst>(Val);
@@ -374,7 +389,16 @@ static SILValue copyArrayLoad(SILValue ArrayStructValue,
374
389
InsertPt = Inst;
375
390
}
376
391
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);
378
402
}
379
403
380
404
static ApplyInst *hoistOrCopyCall (ApplyInst *AI, SILInstruction *InsertBefore,
@@ -404,17 +428,16 @@ static SILValue hoistOrCopySelf(ApplyInst *SemanticsCall,
404
428
405
429
auto Self = SemanticsCall->getSelfArgument ();
406
430
bool IsOwnedSelf = SelfConvention == ParameterConvention::Direct_Owned;
431
+ auto *Func = SemanticsCall->getFunction ();
407
432
408
433
// Emit matching release for owned self if we are moving the original call.
409
434
if (!LeaveOriginal && IsOwnedSelf) {
410
435
SILBuilderWithScope Builder (SemanticsCall);
411
- Builder.createReleaseValue (SemanticsCall->getLoc (), Self, Builder. getDefaultAtomicity () );
436
+ Builder.emitDestroyValueOperation (SemanticsCall->getLoc (), Self);
412
437
}
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.
418
441
SILBuilderWithScope Builder (InsertBefore, SemanticsCall);
419
442
Builder.createRetainValue (SemanticsCall->getLoc (), NewArrayStructValue,
420
443
Builder.getDefaultAtomicity ());
@@ -512,8 +535,7 @@ void swift::ArraySemanticsCall::removeCall() {
512
535
if (getSelfParameterConvention (SemanticsCall) ==
513
536
ParameterConvention::Direct_Owned) {
514
537
SILBuilderWithScope Builder (SemanticsCall);
515
- Builder.createReleaseValue (SemanticsCall->getLoc (), getSelf (),
516
- Builder.getDefaultAtomicity ());
538
+ Builder.emitDestroyValueOperation (SemanticsCall->getLoc (), getSelf ());
517
539
}
518
540
519
541
switch (getKind ()) {
0 commit comments