Skip to content

Commit e3acbd0

Browse files
committed
[cast-opt] Perform initial argument/cast replacement with an inline constructor in optimizeBridgedObjCToSwiftCast.
This makes it easier to read and understand the control flow by using early returns.
1 parent 19a7978 commit e3acbd0

File tree

1 file changed

+43
-39
lines changed

1 file changed

+43
-39
lines changed

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,9 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
108108
return nullptr;
109109

110110
CanType CanBridgedTy = BridgedTargetTy->getCanonicalType();
111-
SILType SILBridgedTy = SILType::getPrimitiveObjectType(CanBridgedTy);
111+
SILType silBridgedTy = SILType::getPrimitiveObjectType(CanBridgedTy);
112112

113113
SILBuilderWithScope Builder(Inst, BuilderContext);
114-
SILValue SrcOp;
115-
SILInstruction *NewI = nullptr;
116114

117115
// If this is a conditional cast:
118116
// We need a new fail BB in order to add a dealloc_stack to it
@@ -136,38 +134,44 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
136134
return nullptr;
137135
}
138136

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+
}
143160

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.
148161
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};
156169
}
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+
}();
171175

172176
// Now emit the a cast from the casted ObjC object into a target type.
173177
// This is done by means of calling _forceBridgeFromObjectiveC or
@@ -217,33 +221,33 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
217221
"Parameter should be @guaranteed");
218222

219223
// Emit a retain.
220-
Builder.createRetainValue(Loc, SrcOp, Builder.getDefaultAtomicity());
224+
Builder.createRetainValue(Loc, srcOp, Builder.getDefaultAtomicity());
221225

222226
Args.push_back(InOutOptionalParam);
223-
Args.push_back(SrcOp);
227+
Args.push_back(srcOp);
224228
Args.push_back(MetaTyVal);
225229

226230
auto *AI = Builder.createApply(Loc, FuncRef, SubMap, Args, false);
227231

228232
// If we have guaranteed normal arguments, insert the destroy.
229233
//
230234
// TODO: Is it safe to just eliminate the initial retain?
231-
Builder.createReleaseValue(Loc, SrcOp, Builder.getDefaultAtomicity());
235+
Builder.createReleaseValue(Loc, srcOp, Builder.getDefaultAtomicity());
232236

233237
// If the source of a cast should be destroyed, emit a release.
234238
if (isa<UnconditionalCheckedCastAddrInst>(Inst)) {
235-
Builder.createReleaseValue(Loc, SrcOp, Builder.getDefaultAtomicity());
239+
Builder.createReleaseValue(Loc, srcOp, Builder.getDefaultAtomicity());
236240
}
237241

238242
if (auto *CCABI = dyn_cast<CheckedCastAddrBranchInst>(Inst)) {
239243
switch (CCABI->getConsumptionKind()) {
240244
case CastConsumptionKind::TakeAlways:
241-
Builder.createReleaseValue(Loc, SrcOp, Builder.getDefaultAtomicity());
245+
Builder.createReleaseValue(Loc, srcOp, Builder.getDefaultAtomicity());
242246
break;
243247
case CastConsumptionKind::TakeOnSuccess:
244248
// Insert a release in the success BB.
245249
Builder.setInsertionPoint(SuccessBB->begin());
246-
Builder.createReleaseValue(Loc, SrcOp, Builder.getDefaultAtomicity());
250+
Builder.createReleaseValue(Loc, srcOp, Builder.getDefaultAtomicity());
247251
break;
248252
case CastConsumptionKind::BorrowAlways:
249253
llvm_unreachable("checked_cast_addr_br never has BorrowAlways");
@@ -281,7 +285,7 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
281285
}
282286

283287
EraseInstAction(Inst);
284-
return (NewI) ? NewI : AI;
288+
return (newI) ? newI : AI;
285289
}
286290

287291
static bool canOptimizeCast(const swift::Type &BridgedTargetTy,

0 commit comments

Comments
 (0)