1212
1313#include " swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
1414#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
15+ #include " swift/SILOptimizer/Utils/InstOptUtils.h"
1516#include " swift/SIL/SILInstruction.h"
1617#include " swift/SIL/DynamicCasts.h"
1718#include " llvm/Support/CommandLine.h"
@@ -79,26 +80,29 @@ static SILValue stripRCIdentityPreservingInsts(SILValue V) {
7980 // the struct is equivalent to a ref count operation on the extracted
8081 // member. Strip off the extract.
8182 if (auto *SEI = dyn_cast<StructExtractInst>(V))
82- if (SEI->isFieldOnlyNonTrivialField ())
83+ if (SEI->isFieldOnlyNonTrivialField () && ! hasValueDeinit (SEI-> getOperand ()) )
8384 return SEI->getOperand ();
8485
8586 // If we have a struct instruction with only one non-trivial stored field, the
8687 // only reference count that can be modified is the non-trivial field. Return
8788 // the non-trivial field.
88- if (auto *SI = dyn_cast<StructInst>(V))
89- if (SILValue NewValue = SI->getUniqueNonTrivialFieldValue ())
90- return NewValue;
91-
89+ if (auto *SI = dyn_cast<StructInst>(V)) {
90+ if (!hasValueDeinit (SI)) {
91+ if (SILValue NewValue = SI->getUniqueNonTrivialFieldValue ())
92+ return NewValue;
93+ }
94+ }
9295 // If we have an unchecked_enum_data, strip off the unchecked_enum_data.
93- if (auto *UEDI = dyn_cast<UncheckedEnumDataInst>(V))
94- return UEDI->getOperand ();
95-
96+ if (auto *UEDI = dyn_cast<UncheckedEnumDataInst>(V)) {
97+ if (!hasValueDeinit (UEDI->getOperand ()))
98+ return UEDI->getOperand ();
99+ }
96100 // If we have an enum instruction with a payload, strip off the enum to
97101 // expose the enum's payload.
98- if (auto *EI = dyn_cast<EnumInst>(V))
99- if (EI->hasOperand ())
102+ if (auto *EI = dyn_cast<EnumInst>(V)) {
103+ if (EI->hasOperand () && ! hasValueDeinit (EI) )
100104 return EI->getOperand ();
101-
105+ }
102106 // If we have a tuple_extract that is extracting the only non trivial member
103107 // of a tuple, a retain_value on the tuple is equivalent to a retain_value on
104108 // the extracted value.
@@ -114,8 +118,10 @@ static SILValue stripRCIdentityPreservingInsts(SILValue V) {
114118 return NewValue;
115119
116120 if (auto *result = SILArgument::isTerminatorResult (V)) {
117- if (auto *forwardedOper = result->forwardedTerminatorResultOperand ())
118- return forwardedOper->get ();
121+ if (auto *forwardedOper = result->forwardedTerminatorResultOperand ()) {
122+ if (!hasValueDeinit (forwardedOper->get ()))
123+ return forwardedOper->get ();
124+ }
119125 }
120126
121127 // Handle useless single-predecessor phis for legacy reasons. (Although these
@@ -307,7 +313,7 @@ static SILValue allIncomingValuesEqual(
307313SILValue RCIdentityFunctionInfo::stripRCIdentityPreservingArgs (SILValue V,
308314 unsigned RecursionDepth) {
309315 auto *A = dyn_cast<SILPhiArgument>(V);
310- if (!A) {
316+ if (!A || !A-> isPhi () ) {
311317 return SILValue ();
312318 }
313319
@@ -503,7 +509,7 @@ static bool isNonOverlappingTrivialAccess(SILValue value) {
503509 if (auto *SEI = dyn_cast<StructExtractInst>(value)) {
504510 // If the struct we are extracting from only has one non trivial element and
505511 // we are not extracting from that element, this is an ARC escape.
506- return SEI->isTrivialFieldOfOneRCIDStruct ();
512+ return SEI->isTrivialFieldOfOneRCIDStruct () && ! hasValueDeinit (SEI) ;
507513 }
508514
509515 return false ;
0 commit comments