Skip to content

Commit 88a69e7

Browse files
committed
---
yaml --- r: 347067 b: refs/heads/master c: 3f5f78e h: refs/heads/master i: 347065: 7d2e7c9 347063: 6b2e51f
1 parent 2e43b70 commit 88a69e7

File tree

4 files changed

+92
-53
lines changed

4 files changed

+92
-53
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 3dd0ede2176b187d2a47ddbe2523bcc02c9e5e13
2+
refs/heads/master: 3f5f78e2c5366031c1b9ce410889fce5baaa8472
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/SIL/DynamicCasts.h

Lines changed: 57 additions & 3 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
}
@@ -206,12 +210,30 @@ struct SILDynamicCastInst {
206210
SILBasicBlock *getSuccessBlock() {
207211
switch (getKind()) {
208212
case SILDynamicCastKind::CheckedCastAddrBranchInst:
213+
llvm_unreachable("unsupported");
209214
case SILDynamicCastKind::CheckedCastBranchInst:
215+
return cast<CheckedCastBranchInst>(inst)->getSuccessBB();
210216
case SILDynamicCastKind::CheckedCastValueBranchInst:
211217
llvm_unreachable("unsupported");
212218
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
219+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
213220
return nullptr;
221+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
222+
llvm_unreachable("unsupported");
223+
}
224+
}
225+
226+
Optional<ProfileCounter> getSuccessBlockCount() {
227+
switch (getKind()) {
228+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
229+
llvm_unreachable("unsupported");
230+
case SILDynamicCastKind::CheckedCastBranchInst:
231+
return cast<CheckedCastBranchInst>(inst)->getTrueBBCount();
232+
case SILDynamicCastKind::CheckedCastValueBranchInst:
233+
llvm_unreachable("unsupported");
234+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
214235
case SILDynamicCastKind::UnconditionalCheckedCastInst:
236+
return None;
215237
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
216238
llvm_unreachable("unsupported");
217239
}
@@ -224,12 +246,30 @@ struct SILDynamicCastInst {
224246
SILBasicBlock *getFailureBlock() {
225247
switch (getKind()) {
226248
case SILDynamicCastKind::CheckedCastAddrBranchInst:
249+
llvm_unreachable("unsupported");
227250
case SILDynamicCastKind::CheckedCastBranchInst:
251+
return cast<CheckedCastBranchInst>(inst)->getFailureBB();
228252
case SILDynamicCastKind::CheckedCastValueBranchInst:
229253
llvm_unreachable("unsupported");
230254
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
255+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
231256
return nullptr;
257+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
258+
llvm_unreachable("unsupported");
259+
}
260+
}
261+
262+
Optional<ProfileCounter> getFailureBlockCount() {
263+
switch (getKind()) {
264+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
265+
llvm_unreachable("unsupported");
266+
case SILDynamicCastKind::CheckedCastBranchInst:
267+
return cast<CheckedCastBranchInst>(inst)->getFalseBBCount();
268+
case SILDynamicCastKind::CheckedCastValueBranchInst:
269+
llvm_unreachable("unsupported");
270+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
232271
case SILDynamicCastKind::UnconditionalCheckedCastInst:
272+
return None;
233273
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
234274
llvm_unreachable("unsupported");
235275
}
@@ -242,12 +282,15 @@ struct SILDynamicCastInst {
242282
SILValue getSource() const {
243283
switch (getKind()) {
244284
case SILDynamicCastKind::CheckedCastAddrBranchInst:
285+
llvm_unreachable("unsupported");
245286
case SILDynamicCastKind::CheckedCastBranchInst:
287+
return cast<CheckedCastBranchInst>(inst)->getOperand();
246288
case SILDynamicCastKind::CheckedCastValueBranchInst:
247289
llvm_unreachable("unsupported");
248290
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
249291
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSrc();
250292
case SILDynamicCastKind::UnconditionalCheckedCastInst:
293+
return cast<UnconditionalCheckedCastInst>(inst)->getOperand();
251294
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
252295
llvm_unreachable("unsupported");
253296
}
@@ -263,6 +306,10 @@ struct SILDynamicCastInst {
263306
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
264307
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest();
265308
case SILDynamicCastKind::UnconditionalCheckedCastInst:
309+
// TODO: Why isn't this:
310+
//
311+
// return cast<UnconditionalCheckedCastInst>(inst);
312+
return SILValue();
266313
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
267314
llvm_unreachable("unimplemented");
268315
}
@@ -277,6 +324,7 @@ struct SILDynamicCastInst {
277324
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
278325
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSourceType();
279326
case SILDynamicCastKind::UnconditionalCheckedCastInst:
327+
return cast<UnconditionalCheckedCastInst>(inst)->getSourceType();
280328
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
281329
llvm_unreachable("unsupported");
282330
}
@@ -293,6 +341,7 @@ struct SILDynamicCastInst {
293341
return uccai->getSrc()->getType();
294342
}
295343
case SILDynamicCastKind::UnconditionalCheckedCastInst:
344+
return cast<UnconditionalCheckedCastInst>(inst)->getOperand()->getType();
296345
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
297346
llvm_unreachable("unsupported");
298347
}
@@ -307,6 +356,7 @@ struct SILDynamicCastInst {
307356
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
308357
return cast<UnconditionalCheckedCastAddrInst>(inst)->getTargetType();
309358
case SILDynamicCastKind::UnconditionalCheckedCastInst:
359+
return cast<UnconditionalCheckedCastInst>(inst)->getTargetType();
310360
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
311361
llvm_unreachable("unimplemented");
312362
}
@@ -315,14 +365,18 @@ struct SILDynamicCastInst {
315365
SILType getLoweredTargetType() const {
316366
switch (getKind()) {
317367
case SILDynamicCastKind::CheckedCastAddrBranchInst:
368+
llvm_unreachable("unsupported");
318369
case SILDynamicCastKind::CheckedCastBranchInst:
370+
return cast<CheckedCastBranchInst>(inst)->getCastType();
319371
case SILDynamicCastKind::CheckedCastValueBranchInst:
320372
llvm_unreachable("unsupported");
321373
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst: {
322374
auto *uccai = dyn_cast<UnconditionalCheckedCastAddrInst>(inst);
323375
return uccai->getDest()->getType();
324376
}
325-
case SILDynamicCastKind::UnconditionalCheckedCastInst:
377+
case SILDynamicCastKind::UnconditionalCheckedCastInst: {
378+
return cast<UnconditionalCheckedCastInst>(inst)->getType();
379+
}
326380
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
327381
llvm_unreachable("unsupported");
328382
}
@@ -335,8 +389,8 @@ struct SILDynamicCastInst {
335389
case SILDynamicCastKind::CheckedCastValueBranchInst:
336390
llvm_unreachable("unsupported");
337391
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
338-
return isa<MetatypeInst>(getSource());
339392
case SILDynamicCastKind::UnconditionalCheckedCastInst:
393+
return isa<MetatypeInst>(getSource());
340394
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
341395
llvm_unreachable("unsupported");
342396
}
@@ -368,8 +422,8 @@ struct SILDynamicCastInst {
368422
case SILDynamicCastKind::CheckedCastValueBranchInst:
369423
llvm_unreachable("unsupported");
370424
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
371-
return false;
372425
case SILDynamicCastKind::UnconditionalCheckedCastInst:
426+
return false;
373427
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
374428
llvm_unreachable("unsupported");
375429
}

trunk/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,

trunk/lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 25 additions & 49 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.
@@ -1111,11 +1098,21 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
11111098
if (Inst->isExact())
11121099
return nullptr;
11131100

1114-
auto LoweredTargetType = Inst->getCastType();
1115-
auto Loc = Inst->getLoc();
1116-
auto *SuccessBB = Inst->getSuccessBB();
1117-
auto *FailureBB = Inst->getFailureBB();
1118-
auto Op = Inst->getOperand();
1101+
// Local helper we use to simplify replacing a checked_cast_branch with an
1102+
// optimized checked cast branch.
1103+
auto replaceCastHelper = [](SILBuilderWithScope &B,
1104+
SILDynamicCastInst dynamicCast,
1105+
MetatypeInst *mi) -> SILInstruction * {
1106+
return B.createCheckedCastBranch(
1107+
dynamicCast.getLocation(), false /*isExact*/, mi,
1108+
dynamicCast.getLoweredTargetType(), dynamicCast.getSuccessBlock(),
1109+
dynamicCast.getFailureBlock(), *dynamicCast.getSuccessBlockCount(),
1110+
*dynamicCast.getFailureBlockCount());
1111+
};
1112+
1113+
SILDynamicCastInst dynamicCast(Inst);
1114+
1115+
auto Op = dynamicCast.getSource();
11191116

11201117
// Try to simplify checked_cond_br instructions using existential
11211118
// metatypes by propagating a concrete type whenever it can be
@@ -1130,9 +1127,7 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
11301127
if (auto *IEMI = dyn_cast<InitExistentialMetatypeInst>(Op)) {
11311128
if (auto *MI = dyn_cast<MetatypeInst>(IEMI->getOperand())) {
11321129
SILBuilderWithScope B(Inst, BuilderContext);
1133-
auto *NewI = B.createCheckedCastBranch(
1134-
Loc, /* isExact */ false, MI, LoweredTargetType, SuccessBB, FailureBB,
1135-
Inst->getTrueBBCount(), Inst->getFalseBBCount());
1130+
auto *NewI = replaceCastHelper(B, dynamicCast, MI);
11361131
EraseInstAction(Inst);
11371132
return NewI;
11381133
}
@@ -1196,10 +1191,7 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
11961191
B.getOpenedArchetypes().addOpenedArchetypeOperands(
11971192
FoundIEI->getTypeDependentOperands());
11981193
auto *MI = B.createMetatype(FoundIEI->getLoc(), SILMetaTy);
1199-
1200-
auto *NewI = B.createCheckedCastBranch(
1201-
Loc, /* isExact */ false, MI, LoweredTargetType, SuccessBB,
1202-
FailureBB, Inst->getTrueBBCount(), Inst->getFalseBBCount());
1194+
auto *NewI = replaceCastHelper(B, dynamicCast, MI);
12031195
EraseInstAction(Inst);
12041196
return NewI;
12051197
}
@@ -1255,10 +1247,7 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
12551247
B.getOpenedArchetypes().addOpenedArchetypeOperands(
12561248
FoundIERI->getTypeDependentOperands());
12571249
auto *MI = B.createMetatype(FoundIERI->getLoc(), SILMetaTy);
1258-
1259-
auto *NewI = B.createCheckedCastBranch(
1260-
Loc, /* isExact */ false, MI, LoweredTargetType, SuccessBB,
1261-
FailureBB, Inst->getTrueBBCount(), Inst->getFalseBBCount());
1250+
auto *NewI = replaceCastHelper(B, dynamicCast, MI);
12621251
EraseInstAction(Inst);
12631252
return NewI;
12641253
}
@@ -1270,18 +1259,12 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
12701259

12711260
ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
12721261
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);
1262+
SILDynamicCastInst dynamicCast(Inst);
1263+
auto Loc = dynamicCast.getLocation();
12801264

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

12861269
if (Feasibility == DynamicCastFeasibility::WillFail) {
12871270
// Remove the cast and insert a trap, followed by an
@@ -1314,12 +1297,7 @@ ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
13141297
SILBuilderWithScope Builder(Inst, BuilderContext);
13151298

13161299
// 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);
1300+
auto NewI = optimizeBridgedCasts(dynamicCast);
13231301
if (NewI) {
13241302
// FIXME: I'm not sure why this is true!
13251303
auto newValue = cast<SingleValueInstruction>(NewI);
@@ -1337,13 +1315,11 @@ ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
13371315

13381316
assert(Feasibility == DynamicCastFeasibility::WillSucceed);
13391317

1340-
if (isBridgingCast(SourceType, TargetType))
1318+
if (dynamicCast.isBridgingCast())
13411319
return nullptr;
13421320

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

13481324
if (!Result) {
13491325
// No optimization was possible.

0 commit comments

Comments
 (0)