@@ -579,9 +579,8 @@ recursivelyCollectInteriorUses(ValueBase *DefInst,
579
579
auto User = Op->getUser ();
580
580
581
581
// Lifetime endpoints that don't allow the address to escape.
582
- if (isa<RefCountingInst>(User) ||
583
- isa<DebugValueInst>(User) ||
584
- isa<FixLifetimeInst>(User)) {
582
+ if (isa<RefCountingInst>(User) || isa<DebugValueInst>(User) ||
583
+ isa<FixLifetimeInst>(User) || isa<DestroyValueInst>(User)) {
585
584
AllUsers.insert (User);
586
585
continue ;
587
586
}
@@ -716,10 +715,7 @@ static void insertReleases(ArrayRef<StoreInst*> Stores,
716
715
// per block, and all release points occur after all stores. Therefore we
717
716
// can simply ask SSAUpdater for the reaching store.
718
717
SILValue RelVal = SSAUp.getValueAtEndOfBlock (RelPoint->getParent ());
719
- if (StVal->getType ().isReferenceCounted (RelPoint->getModule ()))
720
- B.createStrongRelease (Loc, RelVal, B.getDefaultAtomicity ());
721
- else
722
- B.createReleaseValue (Loc, RelVal, B.getDefaultAtomicity ());
718
+ B.emitDestroyValueOperation (Loc, RelVal);
723
719
}
724
720
}
725
721
@@ -1008,10 +1004,11 @@ bool DeadObjectElimination::getDeadInstsAfterInitializerRemoved(
1008
1004
1009
1005
if (auto *ARI = dyn_cast<AllocRefInstBase>(Arg0)) {
1010
1006
if (all_of (ARI->getUses (), [&](Operand *Op) -> bool {
1011
- if (Op->getUser () == AI)
1007
+ auto *user = Op->getUser ();
1008
+ if (user == AI)
1012
1009
return true ;
1013
- if (auto *SRI = dyn_cast <StrongReleaseInst>(Op-> getUser () )) {
1014
- ToDestroy.emplace_back (SRI );
1010
+ if (isa <StrongReleaseInst>(user) || isa<DestroyValueInst>(user )) {
1011
+ ToDestroy.emplace_back (user );
1015
1012
return true ;
1016
1013
}
1017
1014
return false ;
@@ -1039,19 +1036,33 @@ bool DeadObjectElimination::getDeadInstsAfterInitializerRemoved(
1039
1036
// or we could also handle calls to array.init.
1040
1037
bool DeadObjectElimination::removeAndReleaseArray (
1041
1038
SingleValueInstruction *NewArrayValue, DeadEndBlocks &DEBlocks) {
1042
- TupleExtractInst *ArrayDef = nullptr ;
1043
- TupleExtractInst *StorageAddress = nullptr ;
1044
- for (auto *Op : NewArrayValue->getUses ()) {
1045
- auto *TupleElt = dyn_cast<TupleExtractInst>(Op->getUser ());
1046
- if (!TupleElt)
1039
+ SILValue ArrayDef = nullptr ;
1040
+ SILValue StorageAddress = nullptr ;
1041
+
1042
+ if (NewArrayValue->getFunction ()->hasOwnership ()) {
1043
+ auto *destructureTuple =
1044
+ NewArrayValue->getSingleConsumingUserOfType <DestructureTupleInst>();
1045
+ if (!destructureTuple) {
1047
1046
return false ;
1048
- if (TupleElt->getFieldIndex () == 0 && !ArrayDef) {
1049
- ArrayDef = TupleElt;
1050
- } else if (TupleElt->getFieldIndex () == 1 && !StorageAddress) {
1051
- StorageAddress = TupleElt;
1052
- } else {
1047
+ }
1048
+ if (destructureTuple->getNumResults () != 2 ) {
1053
1049
return false ;
1054
1050
}
1051
+ ArrayDef = destructureTuple->getResult (0 );
1052
+ StorageAddress = destructureTuple->getResult (1 );
1053
+ } else {
1054
+ for (auto *Op : NewArrayValue->getUses ()) {
1055
+ auto *TupleElt = dyn_cast<TupleExtractInst>(Op->getUser ());
1056
+ if (!TupleElt)
1057
+ return false ;
1058
+ if (TupleElt->getFieldIndex () == 0 && !ArrayDef) {
1059
+ ArrayDef = TupleElt;
1060
+ } else if (TupleElt->getFieldIndex () == 1 && !StorageAddress) {
1061
+ StorageAddress = TupleElt;
1062
+ } else {
1063
+ return false ;
1064
+ }
1065
+ }
1055
1066
}
1056
1067
if (!ArrayDef)
1057
1068
return false ; // No Array object to delete.
0 commit comments