Second part of the cast folding and type-casts re-factoring.

This patch does the following:
- Moves the logic for handling special-case of converting to/from AnyObject.Protocol (and existential.Protocol in general) into DynamicCasts, where all other cases are handled already.
- Moves the peephole which was folding checked_cast_br into an unchecked cast and branch from sil-combine into sil-simplify-cfg, because it is a better place for it, since this peephole affects the CFG. The corresponding test is also moved from sil_combine.sil into simplify_cfg.sil.
- Adds a few checked_cast_br peepholes to sil-combine.   They try to simplify checked_cond_br instructions using existential metatypes by propagating a concrete type whenever it can be determined statically.
- Adds a new test with a lot of test-cases that make sure we are really folding many type-checks at compile-time now.

Swift SVN r25504
This commit is contained in:
Roman Levenstein
2015-02-24 17:31:08 +00:00
parent b347f7eae5
commit c199905a2f
6 changed files with 735 additions and 46 deletions

View File

@@ -191,6 +191,36 @@ swift::classifyDynamicCast(Module *M,
source = sourceMetatype.getInstanceType();
target = targetMetatype.getInstanceType();
// Casts from a metatype of a non-existential type into a metatype
// of an existential type always fail.
if (target.isAnyExistentialType() && !source.isAnyExistentialType())
return DynamicCastFeasibility::WillFail;
// Casts from a metatype of an existential type into a metatype
// of a non-existential type always fail.
if (!target.isAnyExistentialType() && source.isAnyExistentialType() && isSourceTypeExact)
return DynamicCastFeasibility::WillFail;
// Casts from a metatype of an existential type into a metatype
// of an existential type can only succeed if this is the same type.
if (target.isAnyExistentialType() && source.isAnyExistentialType() &&
target != source)
return DynamicCastFeasibility::WillFail;
// Handle casts from AnyObject.
//
// If isSourceTypeExact is true, we know we are casting from AnyObject.protocol.
// %0 = metatype $@thick AnyObject.Protocol
// checked_cast_br %0 : $@thick AnyObject.Protocol to $@thick Target.Type, bb1, bb2
//
// This cast will always fail unless target is AnyObject
if (isSourceTypeExact && source->isAnyObject() && !target->isAnyObject())
return DynamicCastFeasibility::WillFail;
// This cast will always fail unless source is AnyObject
if (isSourceTypeExact && !source->isAnyObject() && target->isAnyObject())
return DynamicCastFeasibility::WillFail;
// TODO: prove that some conversions to existential metatype will
// obviously succeed/fail.
// TODO: prove that some conversions from class existential metatype