Skip to content

Commit e80c394

Browse files
committed
[cast-opt] Update optimization of unconditional checked cast to use SILDynamicCastInst.
1 parent 1755ac8 commit e80c394

File tree

3 files changed

+35
-38
lines changed

3 files changed

+35
-38
lines changed

include/swift/SIL/DynamicCasts.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ DynamicCastFeasibility classifyDynamicCast(
6363
bool isSourceTypeExact = false,
6464
bool isWholdModuleOpts = false);
6565

66+
SILValue emitSuccessfulScalarUnconditionalCast(SILBuilder &B, SILLocation loc,
67+
SILDynamicCastInst inst);
68+
6669
SILValue emitSuccessfulScalarUnconditionalCast(
6770
SILBuilder &B, ModuleDecl *M, SILLocation loc, SILValue value,
6871
SILType loweredTargetType,
@@ -186,6 +189,7 @@ struct SILDynamicCastInst {
186189
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
187190
return CastConsumptionKind::TakeAlways;
188191
case SILDynamicCastKind::UnconditionalCheckedCastInst:
192+
return CastConsumptionKind::CopyOnSuccess;
189193
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
190194
llvm_unreachable("unsupported");
191195
}
@@ -210,8 +214,8 @@ struct SILDynamicCastInst {
210214
case SILDynamicCastKind::CheckedCastValueBranchInst:
211215
llvm_unreachable("unsupported");
212216
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
213-
return nullptr;
214217
case SILDynamicCastKind::UnconditionalCheckedCastInst:
218+
return nullptr;
215219
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
216220
llvm_unreachable("unsupported");
217221
}
@@ -228,8 +232,8 @@ struct SILDynamicCastInst {
228232
case SILDynamicCastKind::CheckedCastValueBranchInst:
229233
llvm_unreachable("unsupported");
230234
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
231-
return nullptr;
232235
case SILDynamicCastKind::UnconditionalCheckedCastInst:
236+
return nullptr;
233237
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
234238
llvm_unreachable("unsupported");
235239
}
@@ -248,6 +252,7 @@ struct SILDynamicCastInst {
248252
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
249253
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSrc();
250254
case SILDynamicCastKind::UnconditionalCheckedCastInst:
255+
return cast<UnconditionalCheckedCastInst>(inst)->getOperand();
251256
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
252257
llvm_unreachable("unsupported");
253258
}
@@ -263,6 +268,10 @@ struct SILDynamicCastInst {
263268
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
264269
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest();
265270
case SILDynamicCastKind::UnconditionalCheckedCastInst:
271+
// TODO: Why isn't this:
272+
//
273+
// return cast<UnconditionalCheckedCastInst>(inst);
274+
return SILValue();
266275
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
267276
llvm_unreachable("unimplemented");
268277
}
@@ -277,6 +286,7 @@ struct SILDynamicCastInst {
277286
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
278287
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSourceType();
279288
case SILDynamicCastKind::UnconditionalCheckedCastInst:
289+
return cast<UnconditionalCheckedCastInst>(inst)->getSourceType();
280290
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
281291
llvm_unreachable("unsupported");
282292
}
@@ -293,6 +303,7 @@ struct SILDynamicCastInst {
293303
return uccai->getSrc()->getType();
294304
}
295305
case SILDynamicCastKind::UnconditionalCheckedCastInst:
306+
return cast<UnconditionalCheckedCastInst>(inst)->getOperand()->getType();
296307
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
297308
llvm_unreachable("unsupported");
298309
}
@@ -307,6 +318,7 @@ struct SILDynamicCastInst {
307318
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
308319
return cast<UnconditionalCheckedCastAddrInst>(inst)->getTargetType();
309320
case SILDynamicCastKind::UnconditionalCheckedCastInst:
321+
return cast<UnconditionalCheckedCastInst>(inst)->getTargetType();
310322
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
311323
llvm_unreachable("unimplemented");
312324
}
@@ -322,7 +334,9 @@ struct SILDynamicCastInst {
322334
auto *uccai = dyn_cast<UnconditionalCheckedCastAddrInst>(inst);
323335
return uccai->getDest()->getType();
324336
}
325-
case SILDynamicCastKind::UnconditionalCheckedCastInst:
337+
case SILDynamicCastKind::UnconditionalCheckedCastInst: {
338+
return cast<UnconditionalCheckedCastInst>(inst)->getType();
339+
}
326340
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
327341
llvm_unreachable("unsupported");
328342
}
@@ -335,8 +349,8 @@ struct SILDynamicCastInst {
335349
case SILDynamicCastKind::CheckedCastValueBranchInst:
336350
llvm_unreachable("unsupported");
337351
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
338-
return isa<MetatypeInst>(getSource());
339352
case SILDynamicCastKind::UnconditionalCheckedCastInst:
353+
return isa<MetatypeInst>(getSource());
340354
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
341355
llvm_unreachable("unsupported");
342356
}
@@ -368,8 +382,8 @@ struct SILDynamicCastInst {
368382
case SILDynamicCastKind::CheckedCastValueBranchInst:
369383
llvm_unreachable("unsupported");
370384
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
371-
return false;
372385
case SILDynamicCastKind::UnconditionalCheckedCastInst:
386+
return false;
373387
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
374388
llvm_unreachable("unsupported");
375389
}

lib/SIL/DynamicCasts.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,15 @@ namespace {
10361036
};
10371037
} // end anonymous namespace
10381038

1039+
SILValue
1040+
swift::emitSuccessfulScalarUnconditionalCast(SILBuilder &B, SILLocation loc,
1041+
SILDynamicCastInst dynamicCast) {
1042+
return emitSuccessfulScalarUnconditionalCast(
1043+
B, B.getModule().getSwiftModule(), loc, dynamicCast.getSource(),
1044+
dynamicCast.getLoweredTargetType(), dynamicCast.getSourceType(),
1045+
dynamicCast.getTargetType(), dynamicCast.getInstruction());
1046+
}
1047+
10391048
/// Emit an unconditional scalar cast that's known to succeed.
10401049
SILValue
10411050
swift::emitSuccessfulScalarUnconditionalCast(SILBuilder &B, ModuleDecl *M,

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,6 @@
4545

4646
using namespace swift;
4747

48-
/// Check if is a bridging cast, i.e. one of the sides is
49-
/// a bridged type.
50-
static bool isBridgingCast(CanType SourceType, CanType TargetType) {
51-
// Bridging casts cannot be further simplified.
52-
auto TargetIsBridgeable = TargetType->isBridgeableObjectType();
53-
auto SourceIsBridgeable = SourceType->isBridgeableObjectType();
54-
55-
if (TargetIsBridgeable != SourceIsBridgeable)
56-
return true;
57-
58-
return false;
59-
}
60-
6148
/// If target is a Swift type bridging to an ObjC type,
6249
/// return the ObjC type it bridges to.
6350
/// If target is an ObjC type, return this type.
@@ -1270,18 +1257,12 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
12701257

12711258
ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
12721259
UnconditionalCheckedCastInst *Inst) {
1273-
auto LoweredSourceType = Inst->getOperand()->getType();
1274-
auto LoweredTargetType = Inst->getType();
1275-
auto Loc = Inst->getLoc();
1276-
auto Op = Inst->getOperand();
1277-
auto &Mod = Inst->getModule();
1278-
1279-
bool isSourceTypeExact = isa<MetatypeInst>(Op);
1260+
SILDynamicCastInst dynamicCast(Inst);
1261+
auto Loc = dynamicCast.getLocation();
12801262

12811263
// Check if we can statically predict the outcome of the cast.
12821264
auto Feasibility =
1283-
classifyDynamicCast(Mod.getSwiftModule(), Inst->getSourceType(),
1284-
Inst->getTargetType(), isSourceTypeExact);
1265+
dynamicCast.classifyFeasibility(false /*allowWholeModule*/);
12851266

12861267
if (Feasibility == DynamicCastFeasibility::WillFail) {
12871268
// Remove the cast and insert a trap, followed by an
@@ -1314,12 +1295,7 @@ ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
13141295
SILBuilderWithScope Builder(Inst, BuilderContext);
13151296

13161297
// Try to apply the bridged casts optimizations
1317-
auto SourceType = LoweredSourceType.getASTType();
1318-
auto TargetType = LoweredTargetType.getASTType();
1319-
auto Src = Inst->getOperand();
1320-
auto NewI = optimizeBridgedCasts(Inst, CastConsumptionKind::CopyOnSuccess,
1321-
false, Src, SILValue(), SourceType,
1322-
TargetType, nullptr, nullptr);
1298+
auto NewI = optimizeBridgedCasts(dynamicCast);
13231299
if (NewI) {
13241300
// FIXME: I'm not sure why this is true!
13251301
auto newValue = cast<SingleValueInstruction>(NewI);
@@ -1337,13 +1313,11 @@ ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
13371313

13381314
assert(Feasibility == DynamicCastFeasibility::WillSucceed);
13391315

1340-
if (isBridgingCast(SourceType, TargetType))
1316+
if (dynamicCast.isBridgingCast())
13411317
return nullptr;
13421318

1343-
auto Result = emitSuccessfulScalarUnconditionalCast(
1344-
Builder, Mod.getSwiftModule(), Loc, Op, LoweredTargetType,
1345-
LoweredSourceType.getASTType(),
1346-
LoweredTargetType.getASTType(), Inst);
1319+
auto Result =
1320+
emitSuccessfulScalarUnconditionalCast(Builder, Loc, dynamicCast);
13471321

13481322
if (!Result) {
13491323
// No optimization was possible.

0 commit comments

Comments
 (0)