13
13
#include " swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
14
14
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
15
15
#include " swift/SIL/SILInstruction.h"
16
+ #include " swift/SIL/DynamicCasts.h"
16
17
#include " llvm/Support/CommandLine.h"
17
18
18
19
using namespace swift ;
@@ -34,21 +35,6 @@ static bool isNoPayloadEnum(SILValue V) {
34
35
return !EI->hasOperand ();
35
36
}
36
37
37
- // / Returns true if V is a valid operand of a cast which preserves RC identity.
38
- // /
39
- // / V is a valid operand if it has a non-trivial type.
40
- // / RCIdentityAnalysis must not look through casts which cast from a trivial
41
- // / type, like a metatype, to something which is retainable, like an AnyObject.
42
- // / On some platforms such casts dynamically allocate a ref-counted box for the
43
- // / metatype. Naturally that is the place where a new rc-identity begins.
44
- // / Therefore such a cast is introducing a new rc identical object.
45
- // /
46
- // / If we would look through such a cast, ARC optimizations would get confused
47
- // / and might eliminate a retain of such an object completely.
48
- static bool isValidRCIdentityCastOperand (SILValue V, SILFunction *F) {
49
- return !V->getType ().isTrivial (*F);
50
- }
51
-
52
38
// / RC identity is more than a guarantee that references refer to the same
53
39
// / object. It also means that reference counting operations on those references
54
40
// / have the same semantics. If the types on either side of a cast do not have
@@ -61,16 +47,16 @@ static SILValue getRCIdentityPreservingCastOperand(SILValue V) {
61
47
switch (V->getKind ()) {
62
48
case ValueKind::UpcastInst:
63
49
case ValueKind::UncheckedRefCastInst:
64
- case ValueKind::UnconditionalCheckedCastInst:
65
50
case ValueKind::InitExistentialRefInst:
66
51
case ValueKind::OpenExistentialRefInst:
67
52
case ValueKind::RefToBridgeObjectInst:
68
53
case ValueKind::BridgeObjectToRefInst:
69
- case ValueKind::ConvertFunctionInst: {
70
- auto *inst = cast<SingleValueInstruction>(V);
71
- SILValue castOp = inst->getOperand (0 );
72
- if (isValidRCIdentityCastOperand (castOp, inst->getFunction ()))
73
- return castOp;
54
+ case ValueKind::ConvertFunctionInst:
55
+ return cast<SingleValueInstruction>(V)->getOperand (0 );
56
+ case ValueKind::UnconditionalCheckedCastInst: {
57
+ auto *castInst = cast<UnconditionalCheckedCastInst>(V);
58
+ if (SILDynamicCastInst (castInst).isRCIdentityPreserving ())
59
+ return castInst->getOperand ();
74
60
break ;
75
61
}
76
62
default :
@@ -141,8 +127,10 @@ static SILValue stripRCIdentityPreservingInsts(SILValue V) {
141
127
if (SILValue Result = A->getSingleTerminatorOperand ()) {
142
128
// In case the terminator is a conditional cast, Result is the source of
143
129
// the cast.
144
- if (isValidRCIdentityCastOperand (Result, A->getFunction ()))
145
- return Result;
130
+ auto dynCast = SILDynamicCastInst::getAs (A->getSingleTerminator ());
131
+ if (dynCast && !dynCast.isRCIdentityPreserving ())
132
+ return SILValue ();
133
+ return Result;
146
134
}
147
135
}
148
136
@@ -347,12 +335,15 @@ SILValue RCIdentityFunctionInfo::stripRCIdentityPreservingArgs(SILValue V,
347
335
}
348
336
349
337
unsigned IVListSize = IncomingValues.size ();
350
- if (IVListSize == 1 &&
351
- !isValidRCIdentityCastOperand (IncomingValues[0 ].second , A->getFunction ()))
352
- return SILValue ();
353
-
354
- assert (IVListSize != 1 && " Should have been handled in "
355
- " stripRCIdentityPreservingInsts" );
338
+ if (IVListSize == 1 ) {
339
+ #ifndef NDEBUG
340
+ auto dynCast = SILDynamicCastInst::getAs (A->getSingleTerminator ());
341
+ assert ((dynCast && !dynCast.isRCIdentityPreserving ())
342
+ && " Should have been handled in stripRCIdentityPreservingInsts" );
343
+ #endif
344
+ return SILValue ();
345
+
346
+ }
356
347
357
348
// Ok, we have multiple predecessors. See if all of them are the same
358
349
// value. If so, just return that value.
0 commit comments