@@ -449,34 +449,54 @@ static bool memInstMustConsume(Operand *memOper) {
449
449
// / These are cases where we want to treat the end of the function as a liveness
450
450
// / use to ensure that we reinitialize \p value before the end of the function
451
451
// / if we consume \p value in the function body.
452
- static bool isInOutDefThatNeedsEndOfFunctionLiveness (SILValue value) {
453
- if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
454
- switch (fArg ->getArgumentConvention ()) {
455
- case SILArgumentConvention::Indirect_In:
456
- case SILArgumentConvention::Indirect_Out:
457
- case SILArgumentConvention::Indirect_In_Guaranteed:
458
- case SILArgumentConvention::Direct_Guaranteed:
459
- case SILArgumentConvention::Direct_Owned:
460
- case SILArgumentConvention::Direct_Unowned:
461
- case SILArgumentConvention::Pack_Guaranteed:
462
- case SILArgumentConvention::Pack_Owned:
463
- case SILArgumentConvention::Pack_Out:
464
- return false ;
465
- case SILArgumentConvention::Indirect_Inout:
466
- case SILArgumentConvention::Indirect_InoutAliasable:
467
- case SILArgumentConvention::Pack_Inout:
468
- LLVM_DEBUG (llvm::dbgs () << " Found inout arg: " << *fArg );
469
- return true ;
452
+ static bool isInOutDefThatNeedsEndOfFunctionLiveness (MarkMustCheckInst *markedAddr) {
453
+ SILValue operand = markedAddr->getOperand ();
454
+
455
+ // Check for inout types of arguments that are marked with consumable and
456
+ // assignable.
457
+ if (markedAddr->getCheckKind () ==
458
+ MarkMustCheckInst::CheckKind::ConsumableAndAssignable) {
459
+ if (auto *fArg = dyn_cast<SILFunctionArgument>(operand)) {
460
+ switch (fArg ->getArgumentConvention ()) {
461
+ case SILArgumentConvention::Indirect_In:
462
+ case SILArgumentConvention::Indirect_Out:
463
+ case SILArgumentConvention::Indirect_In_Guaranteed:
464
+ case SILArgumentConvention::Direct_Guaranteed:
465
+ case SILArgumentConvention::Direct_Owned:
466
+ case SILArgumentConvention::Direct_Unowned:
467
+ case SILArgumentConvention::Pack_Guaranteed:
468
+ case SILArgumentConvention::Pack_Owned:
469
+ case SILArgumentConvention::Pack_Out:
470
+ return false ;
471
+ case SILArgumentConvention::Indirect_Inout:
472
+ case SILArgumentConvention::Indirect_InoutAliasable:
473
+ case SILArgumentConvention::Pack_Inout:
474
+ LLVM_DEBUG (llvm::dbgs () << " Found inout arg: " << *fArg );
475
+ return true ;
476
+ }
470
477
}
471
478
}
472
479
473
- if (auto *pbi = dyn_cast<ProjectBoxInst>(value)) {
474
- if (auto *fArg = dyn_cast<SILFunctionArgument>(pbi->getOperand ())) {
475
- if (!fArg ->isClosureCapture ())
476
- return false ;
477
- LLVM_DEBUG (llvm::dbgs () << " Found inout arg: " << *fArg );
478
- return true ;
480
+ // See if we have an assignable_but_not_consumable from a project_box +
481
+ // function_argument. In this case, the value must be live at the end of the
482
+ // use, similar to an inout parameter.
483
+ //
484
+ // TODO: Rather than using a terminator, we might be able to use the
485
+ // end_access of the access marker instead. That would slightly change the
486
+ // model and this is semantically ok today.
487
+ if (markedAddr->getCheckKind () ==
488
+ MarkMustCheckInst::CheckKind::AssignableButNotConsumable) {
489
+ if (auto *pbi = dyn_cast<ProjectBoxInst>(stripAccessMarkers (operand))) {
490
+ if (auto *fArg = dyn_cast<SILFunctionArgument>(pbi->getOperand ())) {
491
+ if (!fArg ->isClosureCapture ())
492
+ return false ;
493
+ LLVM_DEBUG (llvm::dbgs () << " Found inout arg: " << *fArg );
494
+ return true ;
495
+ }
479
496
}
497
+
498
+ if (isa<RefElementAddrInst>(stripAccessMarkers (operand)))
499
+ return true ;
480
500
}
481
501
482
502
return false ;
@@ -592,7 +612,7 @@ struct UseState {
592
612
initializeLiveness (FieldSensitiveMultiDefPrunedLiveRange &prunedLiveness);
593
613
594
614
void initializeInOutTermUsers () {
595
- if (!isInOutDefThatNeedsEndOfFunctionLiveness (address-> getOperand () ))
615
+ if (!isInOutDefThatNeedsEndOfFunctionLiveness (address))
596
616
return ;
597
617
598
618
SmallVector<SILBasicBlock *, 8 > exitBlocks;
0 commit comments