Skip to content

Commit 2e43b70

Browse files
committed
---
yaml --- r: 347066 b: refs/heads/master c: 3dd0ede h: refs/heads/master
1 parent 7d2e7c9 commit 2e43b70

File tree

4 files changed

+82
-45
lines changed

4 files changed

+82
-45
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: 852c245b64c4039b68c0d0f34d1c1bff67673205
2+
refs/heads/master: 3dd0ede2176b187d2a47ddbe2523bcc02c9e5e13
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: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SILLocation;
3232
class SILModule;
3333
class SILType;
3434
enum class CastConsumptionKind : unsigned char;
35+
struct SILDynamicCastInst;
3536

3637
enum class DynamicCastFeasibility {
3738
/// The cast will always succeed.
@@ -74,6 +75,9 @@ bool emitSuccessfulIndirectUnconditionalCast(
7475
SILValue dest, CanType targetType,
7576
SILInstruction *existingCast = nullptr);
7677

78+
bool emitSuccessfulIndirectUnconditionalCast(SILBuilder &B, SILLocation loc,
79+
SILDynamicCastInst dynamicCast);
80+
7781
/// Can the given cast be performed by the scalar checked-cast
7882
/// instructions, or does we need to use the indirect instructions?
7983
bool canUseScalarCheckedCastInstructions(SILModule &M,
@@ -173,6 +177,20 @@ struct SILDynamicCastInst {
173177

174178
SILInstruction *getInstruction() const { return inst; }
175179

180+
CastConsumptionKind getBridgedConsumptionKind() const {
181+
switch (getKind()) {
182+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
183+
case SILDynamicCastKind::CheckedCastBranchInst:
184+
case SILDynamicCastKind::CheckedCastValueBranchInst:
185+
llvm_unreachable("unsupported");
186+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
187+
return CastConsumptionKind::TakeAlways;
188+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
189+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
190+
llvm_unreachable("unsupported");
191+
}
192+
}
193+
176194
CastConsumptionKind getConsumptionKind() const {
177195
switch (getKind()) {
178196
case SILDynamicCastKind::CheckedCastAddrBranchInst:
@@ -181,7 +199,7 @@ struct SILDynamicCastInst {
181199
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
182200
case SILDynamicCastKind::UnconditionalCheckedCastInst:
183201
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
184-
llvm_unreachable("unsupported query");
202+
llvm_unreachable("unsupported");
185203
}
186204
}
187205

@@ -190,10 +208,12 @@ struct SILDynamicCastInst {
190208
case SILDynamicCastKind::CheckedCastAddrBranchInst:
191209
case SILDynamicCastKind::CheckedCastBranchInst:
192210
case SILDynamicCastKind::CheckedCastValueBranchInst:
211+
llvm_unreachable("unsupported");
193212
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
213+
return nullptr;
194214
case SILDynamicCastKind::UnconditionalCheckedCastInst:
195215
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
196-
llvm_unreachable("Unsupported query");
216+
llvm_unreachable("unsupported");
197217
}
198218
}
199219

@@ -206,10 +226,12 @@ struct SILDynamicCastInst {
206226
case SILDynamicCastKind::CheckedCastAddrBranchInst:
207227
case SILDynamicCastKind::CheckedCastBranchInst:
208228
case SILDynamicCastKind::CheckedCastValueBranchInst:
229+
llvm_unreachable("unsupported");
209230
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
231+
return nullptr;
210232
case SILDynamicCastKind::UnconditionalCheckedCastInst:
211233
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
212-
llvm_unreachable("Unsupported query");
234+
llvm_unreachable("unsupported");
213235
}
214236
}
215237

@@ -222,7 +244,9 @@ struct SILDynamicCastInst {
222244
case SILDynamicCastKind::CheckedCastAddrBranchInst:
223245
case SILDynamicCastKind::CheckedCastBranchInst:
224246
case SILDynamicCastKind::CheckedCastValueBranchInst:
247+
llvm_unreachable("unsupported");
225248
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
249+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSrc();
226250
case SILDynamicCastKind::UnconditionalCheckedCastInst:
227251
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
228252
llvm_unreachable("unsupported");
@@ -235,7 +259,9 @@ struct SILDynamicCastInst {
235259
case SILDynamicCastKind::CheckedCastAddrBranchInst:
236260
case SILDynamicCastKind::CheckedCastBranchInst:
237261
case SILDynamicCastKind::CheckedCastValueBranchInst:
262+
llvm_unreachable("unsupported");
238263
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
264+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getDest();
239265
case SILDynamicCastKind::UnconditionalCheckedCastInst:
240266
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
241267
llvm_unreachable("unimplemented");
@@ -247,7 +273,9 @@ struct SILDynamicCastInst {
247273
case SILDynamicCastKind::CheckedCastAddrBranchInst:
248274
case SILDynamicCastKind::CheckedCastBranchInst:
249275
case SILDynamicCastKind::CheckedCastValueBranchInst:
276+
llvm_unreachable("unsupported");
250277
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
278+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getSourceType();
251279
case SILDynamicCastKind::UnconditionalCheckedCastInst:
252280
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
253281
llvm_unreachable("unsupported");
@@ -259,7 +287,11 @@ struct SILDynamicCastInst {
259287
case SILDynamicCastKind::CheckedCastAddrBranchInst:
260288
case SILDynamicCastKind::CheckedCastBranchInst:
261289
case SILDynamicCastKind::CheckedCastValueBranchInst:
262-
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
290+
llvm_unreachable("unsupported");
291+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst: {
292+
auto *uccai = cast<UnconditionalCheckedCastAddrInst>(inst);
293+
return uccai->getSrc()->getType();
294+
}
263295
case SILDynamicCastKind::UnconditionalCheckedCastInst:
264296
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
265297
llvm_unreachable("unsupported");
@@ -271,7 +303,9 @@ struct SILDynamicCastInst {
271303
case SILDynamicCastKind::CheckedCastAddrBranchInst:
272304
case SILDynamicCastKind::CheckedCastBranchInst:
273305
case SILDynamicCastKind::CheckedCastValueBranchInst:
306+
llvm_unreachable("unsupported");
274307
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
308+
return cast<UnconditionalCheckedCastAddrInst>(inst)->getTargetType();
275309
case SILDynamicCastKind::UnconditionalCheckedCastInst:
276310
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
277311
llvm_unreachable("unimplemented");
@@ -283,7 +317,11 @@ struct SILDynamicCastInst {
283317
case SILDynamicCastKind::CheckedCastAddrBranchInst:
284318
case SILDynamicCastKind::CheckedCastBranchInst:
285319
case SILDynamicCastKind::CheckedCastValueBranchInst:
286-
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
320+
llvm_unreachable("unsupported");
321+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst: {
322+
auto *uccai = dyn_cast<UnconditionalCheckedCastAddrInst>(inst);
323+
return uccai->getDest()->getType();
324+
}
287325
case SILDynamicCastKind::UnconditionalCheckedCastInst:
288326
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
289327
llvm_unreachable("unsupported");
@@ -295,7 +333,9 @@ struct SILDynamicCastInst {
295333
case SILDynamicCastKind::CheckedCastAddrBranchInst:
296334
case SILDynamicCastKind::CheckedCastBranchInst:
297335
case SILDynamicCastKind::CheckedCastValueBranchInst:
336+
llvm_unreachable("unsupported");
298337
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
338+
return isa<MetatypeInst>(getSource());
299339
case SILDynamicCastKind::UnconditionalCheckedCastInst:
300340
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
301341
llvm_unreachable("unsupported");
@@ -305,11 +345,12 @@ struct SILDynamicCastInst {
305345
SILLocation getLocation() const { return inst->getLoc(); }
306346

307347
SILModule &getModule() const { return inst->getModule(); }
348+
SILFunction *getFunction() const { return inst->getFunction(); }
308349

309-
DynamicCastFeasibility classifyDynamicCast() const {
350+
DynamicCastFeasibility classifyFeasibility(bool allowWholeModule) const {
310351
return swift::classifyDynamicCast(
311352
getModule().getSwiftModule(), getSourceType(), getTargetType(),
312-
isSourceTypeExact(), getModule().isWholeModule());
353+
isSourceTypeExact(), allowWholeModule && getModule().isWholeModule());
313354
}
314355

315356
bool isBridgingCast() const {
@@ -320,12 +361,14 @@ struct SILDynamicCastInst {
320361
return TargetIsBridgeable != SourceIsBridgeable;
321362
}
322363

323-
bool isConditionalCast() const {
364+
bool isConditional() const {
324365
switch (getKind()) {
325366
case SILDynamicCastKind::CheckedCastAddrBranchInst:
326367
case SILDynamicCastKind::CheckedCastBranchInst:
327368
case SILDynamicCastKind::CheckedCastValueBranchInst:
369+
llvm_unreachable("unsupported");
328370
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
371+
return false;
329372
case SILDynamicCastKind::UnconditionalCheckedCastInst:
330373
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
331374
llvm_unreachable("unsupported");

trunk/lib/SIL/DynamicCasts.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,14 @@ swift::emitSuccessfulScalarUnconditionalCast(SILBuilder &B, ModuleDecl *M,
10691069
return result.Value;
10701070
}
10711071

1072+
bool swift::emitSuccessfulIndirectUnconditionalCast(
1073+
SILBuilder &B, SILLocation loc, SILDynamicCastInst dynamicCast) {
1074+
return emitSuccessfulIndirectUnconditionalCast(
1075+
B, B.getModule().getSwiftModule(), loc, dynamicCast.getSource(),
1076+
dynamicCast.getSourceType(), dynamicCast.getDest(),
1077+
dynamicCast.getTargetType(), dynamicCast.getInstruction());
1078+
}
1079+
10721080
bool swift::emitSuccessfulIndirectUnconditionalCast(
10731081
SILBuilder &B, ModuleDecl *M, SILLocation loc, SILValue src,
10741082
CanType sourceType, SILValue dest, CanType targetType,

trunk/lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -610,15 +610,11 @@ SILInstruction *CastOptimizer::optimizeBridgedSwiftToObjCCast(
610610
}
611611

612612
SILInstruction *CastOptimizer::optimizeBridgedCasts(SILDynamicCastInst cast) {
613-
switch (cast.getKind()) {
614-
case SILDynamicCastKind::CheckedCastAddrBranchInst:
615-
case SILDynamicCastKind::CheckedCastBranchInst:
616-
case SILDynamicCastKind::CheckedCastValueBranchInst:
617-
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
618-
case SILDynamicCastKind::UnconditionalCheckedCastInst:
619-
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
620-
llvm_unreachable("unsupported");
621-
}
613+
return optimizeBridgedCasts(
614+
cast.getInstruction(), cast.getBridgedConsumptionKind(),
615+
cast.isConditional(), cast.getSource(), cast.getDest(),
616+
cast.getSourceType(), cast.getTargetType(), cast.getSuccessBlock(),
617+
cast.getFailureBlock());
622618
}
623619

624620
/// Make use of the fact that some of these casts cannot fail.
@@ -1477,24 +1473,17 @@ static bool optimizeStaticallyKnownProtocolConformance(
14771473

14781474
SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
14791475
UnconditionalCheckedCastAddrInst *Inst) {
1480-
auto Loc = Inst->getLoc();
1481-
auto Src = Inst->getSrc();
1482-
auto Dest = Inst->getDest();
1483-
auto SourceType = Inst->getSourceType();
1484-
auto TargetType = Inst->getTargetType();
1485-
auto &Mod = Inst->getModule();
1486-
auto *F = Inst->getFunction();
1487-
1488-
bool isSourceTypeExact = isa<MetatypeInst>(Src);
1476+
SILDynamicCastInst dynamicCast(Inst);
1477+
auto Loc = dynamicCast.getLocation();
14891478

14901479
// Check if we can statically predict the outcome of the cast.
1491-
auto Feasibility = classifyDynamicCast(Mod.getSwiftModule(), SourceType,
1492-
TargetType, isSourceTypeExact);
1480+
auto Feasibility =
1481+
dynamicCast.classifyFeasibility(false /*allow whole module*/);
14931482

14941483
if (Feasibility == DynamicCastFeasibility::MaySucceed) {
14951484
// Forced bridged casts can be still simplified here.
14961485
// If they fail, they fail inside the conversion function.
1497-
if (!isBridgingCast(SourceType, TargetType))
1486+
if (!dynamicCast.isBridgingCast())
14981487
return nullptr;
14991488
}
15001489

@@ -1504,12 +1493,12 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15041493
SILBuilderWithScope Builder(Inst, BuilderContext);
15051494
// mem2reg's invariants get unhappy if we don't try to
15061495
// initialize a loadable result.
1507-
auto DestType = Dest->getType();
1508-
auto &resultTL = F->getTypeLowering(DestType);
1509-
if (!resultTL.isAddressOnly()) {
1496+
if (!dynamicCast.getLoweredTargetType().isAddressOnly(
1497+
Builder.getModule())) {
15101498
auto undef = SILValue(
1511-
SILUndef::get(DestType.getObjectType(), Builder.getModule()));
1512-
Builder.emitStoreValueOperation(Loc, undef, Dest,
1499+
SILUndef::get(dynamicCast.getLoweredTargetType().getObjectType(),
1500+
Builder.getModule()));
1501+
Builder.emitStoreValueOperation(Loc, undef, dynamicCast.getDest(),
15131502
StoreOwnershipQualifier::Init);
15141503
}
15151504
auto *TrapI = Builder.createBuiltinTrap(Loc);
@@ -1531,10 +1520,11 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15311520
// Check if a result of a cast is unused. If this is the case, the cast can
15321521
// be removed even if the cast may fail at runtime.
15331522
// Swift optimizer does not claim to be crash-preserving.
1534-
bool ResultNotUsed = isa<AllocStackInst>(Dest);
1523+
SILValue dest = dynamicCast.getDest();
1524+
bool ResultNotUsed = isa<AllocStackInst>(dest);
15351525
DestroyAddrInst *DestroyDestInst = nullptr;
15361526
if (ResultNotUsed) {
1537-
for (auto Use : Dest->getUses()) {
1527+
for (auto Use : dest->getUses()) {
15381528
auto *User = Use->getUser();
15391529
if (isa<DeallocStackInst>(User) || User == Inst)
15401530
continue;
@@ -1550,7 +1540,7 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15501540

15511541
if (ResultNotUsed) {
15521542
SILBuilderWithScope B(Inst, BuilderContext);
1553-
B.createDestroyAddr(Inst->getLoc(), Inst->getSrc());
1543+
B.createDestroyAddr(Loc, dynamicCast.getSource());
15541544
if (DestroyDestInst)
15551545
EraseInstAction(DestroyDestInst);
15561546
EraseInstAction(Inst);
@@ -1559,9 +1549,7 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15591549
}
15601550

15611551
// Try to apply the bridged casts optimizations.
1562-
auto NewI =
1563-
optimizeBridgedCasts(Inst, CastConsumptionKind::TakeAlways, false, Src,
1564-
Dest, SourceType, TargetType, nullptr, nullptr);
1552+
auto NewI = optimizeBridgedCasts(dynamicCast);
15651553
if (NewI) {
15661554
WillSucceedAction();
15671555
return nullptr;
@@ -1578,13 +1566,11 @@ SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
15781566
return nullptr;
15791567
}
15801568

1581-
if (isBridgingCast(SourceType, TargetType))
1569+
if (dynamicCast.isBridgingCast())
15821570
return nullptr;
15831571

15841572
SILBuilderWithScope Builder(Inst, BuilderContext);
1585-
if (!emitSuccessfulIndirectUnconditionalCast(Builder, Mod.getSwiftModule(),
1586-
Loc, Src, SourceType, Dest,
1587-
TargetType, Inst)) {
1573+
if (!emitSuccessfulIndirectUnconditionalCast(Builder, Loc, dynamicCast)) {
15881574
// No optimization was possible.
15891575
return nullptr;
15901576
}

0 commit comments

Comments
 (0)