@@ -108,11 +108,9 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
108
108
return nullptr ;
109
109
110
110
CanType CanBridgedTy = BridgedTargetTy->getCanonicalType ();
111
- SILType SILBridgedTy = SILType::getPrimitiveObjectType (CanBridgedTy);
111
+ SILType silBridgedTy = SILType::getPrimitiveObjectType (CanBridgedTy);
112
112
113
113
SILBuilderWithScope Builder (Inst, BuilderContext);
114
- SILValue SrcOp;
115
- SILInstruction *NewI = nullptr ;
116
114
117
115
// If this is a conditional cast:
118
116
// We need a new fail BB in order to add a dealloc_stack to it
@@ -136,38 +134,44 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
136
134
return nullptr ;
137
135
}
138
136
139
- // Generate a load for the source argument.
140
- auto *Load =
141
- Builder.createLoad (Loc, Src, LoadOwnershipQualifier::Unqualified);
142
- // Try to convert the source into the expected ObjC type first.
137
+ // Inline constructor.
138
+ SILValue srcOp;
139
+ SILInstruction *newI;
140
+ std::tie (srcOp, newI) = [&]() -> std::pair<SILValue, SILInstruction *> {
141
+ // Generate a load for the source argument.
142
+ SILValue load =
143
+ Builder.createLoad (Loc, Src, LoadOwnershipQualifier::Unqualified);
144
+
145
+ // If type of the source and the expected ObjC type are equal, there is no
146
+ // need to generate the conversion from ObjCTy to
147
+ // _ObjectiveCBridgeable._ObjectiveCType.
148
+ if (load->getType () == silBridgedTy) {
149
+ if (isConditional) {
150
+ SILBasicBlock *castSuccessBB = F->createBasicBlock ();
151
+ castSuccessBB->createPhiArgument (silBridgedTy,
152
+ ValueOwnershipKind::Owned);
153
+ Builder.createBranch (Loc, castSuccessBB, load);
154
+ Builder.setInsertionPoint (castSuccessBB);
155
+ return {castSuccessBB->getArgument (0 ), nullptr };
156
+ }
157
+
158
+ return {load, nullptr };
159
+ }
143
160
144
- if (Load->getType () == SILBridgedTy) {
145
- // If type of the source and the expected ObjC type are
146
- // equal, there is no need to generate the conversion
147
- // from ObjCTy to _ObjectiveCBridgeable._ObjectiveCType.
148
161
if (isConditional) {
149
- SILBasicBlock *CastSuccessBB = F->createBasicBlock ();
150
- CastSuccessBB ->createPhiArgument (SILBridgedTy , ValueOwnershipKind::Owned);
151
- Builder.createBranch (Loc, CastSuccessBB, SILValue (Load));
152
- Builder. setInsertionPoint (CastSuccessBB );
153
- SrcOp = CastSuccessBB-> getArgument ( 0 );
154
- } else {
155
- SrcOp = Load ;
162
+ SILBasicBlock *castSuccessBB = F->createBasicBlock ();
163
+ castSuccessBB ->createPhiArgument (silBridgedTy , ValueOwnershipKind::Owned);
164
+ auto *ccbi = Builder.createCheckedCastBranch (
165
+ Loc, false , load, silBridgedTy, castSuccessBB, ConvFailBB );
166
+ splitEdge (ccbi, /* EdgeIdx to ConvFailBB */ 1 );
167
+ Builder. setInsertionPoint (castSuccessBB);
168
+ return {castSuccessBB-> getArgument ( 0 ), ccbi} ;
156
169
}
157
- } else if (isConditional) {
158
- SILBasicBlock *CastSuccessBB = F->createBasicBlock ();
159
- CastSuccessBB->createPhiArgument (SILBridgedTy, ValueOwnershipKind::Owned);
160
- auto *CCBI = Builder.createCheckedCastBranch (Loc, false , Load, SILBridgedTy,
161
- CastSuccessBB, ConvFailBB);
162
- NewI = CCBI;
163
- splitEdge (CCBI, /* EdgeIdx to ConvFailBB */ 1 );
164
- Builder.setInsertionPoint (CastSuccessBB);
165
- SrcOp = CastSuccessBB->getArgument (0 );
166
- } else {
167
- auto cast = Builder.createUnconditionalCheckedCast (Loc, Load, SILBridgedTy);
168
- NewI = cast;
169
- SrcOp = cast;
170
- }
170
+
171
+ auto *cast =
172
+ Builder.createUnconditionalCheckedCast (Loc, load, silBridgedTy);
173
+ return {cast, cast};
174
+ }();
171
175
172
176
// Now emit the a cast from the casted ObjC object into a target type.
173
177
// This is done by means of calling _forceBridgeFromObjectiveC or
@@ -217,33 +221,33 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
217
221
" Parameter should be @guaranteed" );
218
222
219
223
// Emit a retain.
220
- Builder.createRetainValue (Loc, SrcOp , Builder.getDefaultAtomicity ());
224
+ Builder.createRetainValue (Loc, srcOp , Builder.getDefaultAtomicity ());
221
225
222
226
Args.push_back (InOutOptionalParam);
223
- Args.push_back (SrcOp );
227
+ Args.push_back (srcOp );
224
228
Args.push_back (MetaTyVal);
225
229
226
230
auto *AI = Builder.createApply (Loc, FuncRef, SubMap, Args, false );
227
231
228
232
// If we have guaranteed normal arguments, insert the destroy.
229
233
//
230
234
// TODO: Is it safe to just eliminate the initial retain?
231
- Builder.createReleaseValue (Loc, SrcOp , Builder.getDefaultAtomicity ());
235
+ Builder.createReleaseValue (Loc, srcOp , Builder.getDefaultAtomicity ());
232
236
233
237
// If the source of a cast should be destroyed, emit a release.
234
238
if (isa<UnconditionalCheckedCastAddrInst>(Inst)) {
235
- Builder.createReleaseValue (Loc, SrcOp , Builder.getDefaultAtomicity ());
239
+ Builder.createReleaseValue (Loc, srcOp , Builder.getDefaultAtomicity ());
236
240
}
237
241
238
242
if (auto *CCABI = dyn_cast<CheckedCastAddrBranchInst>(Inst)) {
239
243
switch (CCABI->getConsumptionKind ()) {
240
244
case CastConsumptionKind::TakeAlways:
241
- Builder.createReleaseValue (Loc, SrcOp , Builder.getDefaultAtomicity ());
245
+ Builder.createReleaseValue (Loc, srcOp , Builder.getDefaultAtomicity ());
242
246
break ;
243
247
case CastConsumptionKind::TakeOnSuccess:
244
248
// Insert a release in the success BB.
245
249
Builder.setInsertionPoint (SuccessBB->begin ());
246
- Builder.createReleaseValue (Loc, SrcOp , Builder.getDefaultAtomicity ());
250
+ Builder.createReleaseValue (Loc, srcOp , Builder.getDefaultAtomicity ());
247
251
break ;
248
252
case CastConsumptionKind::BorrowAlways:
249
253
llvm_unreachable (" checked_cast_addr_br never has BorrowAlways" );
@@ -281,7 +285,7 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
281
285
}
282
286
283
287
EraseInstAction (Inst);
284
- return (NewI ) ? NewI : AI;
288
+ return (newI ) ? newI : AI;
285
289
}
286
290
287
291
static bool canOptimizeCast (const swift::Type &BridgedTargetTy,
0 commit comments