Move the logic for folding type casts using statically known protocol conformances into DynamicCasts.cpp.

The logic for different special cases of type casting is spread over multiple places currently. This patch simply re-factors some of that  code (folding of of type casts using statically known protocol conformances) and moves it into one central place, which makes it easier to maintain. Plus, it allows other clients of DynamicCasts benefit from it as well, e.g. the inliner can use this now. NFC.

Swift SVN r25486
This commit is contained in:
Roman Levenstein
2015-02-23 21:30:48 +00:00
parent 3d23935d39
commit c97f748fb9
4 changed files with 154 additions and 107 deletions

View File

@@ -44,7 +44,9 @@ enum class DynamicCastFeasibility {
/// types should be unlowered formal types.
DynamicCastFeasibility classifyDynamicCast(Module *context,
CanType sourceType,
CanType targetType);
CanType targetType,
bool isSourceTypeExact = false,
bool isWholdModuleOpts = false);
SILValue emitSuccessfulScalarUnconditionalCast(SILBuilder &B, Module *M,
SILLocation loc, SILValue value,

View File

@@ -248,8 +248,11 @@ protected:
CanType formalTargetType = targetType.getSwiftRValueType();
SILValue operand = getOpValue(inst->getOperand());
bool isSourceTypeExact = isa<MetatypeInst>(inst->getOperand());
switch (classifyDynamicCast(SwiftMod, formalSourceType, formalTargetType)) {
switch (classifyDynamicCast(SwiftMod, formalSourceType,
formalTargetType, isSourceTypeExact,
inst->getModule().isWholeModule())) {
case DynamicCastFeasibility::WillSucceed: {
SILValue result =
emitSuccessfulScalarUnconditionalCast(B, SwiftMod, loc, operand,
@@ -288,7 +291,8 @@ protected:
CanType sourceType = getOpASTType(inst->getSourceType());
CanType targetType = getOpASTType(inst->getTargetType());
switch (classifyDynamicCast(SwiftMod, sourceType, targetType)) {
switch (classifyDynamicCast(SwiftMod, sourceType, targetType,
false, inst->getModule().isWholeModule())) {
case DynamicCastFeasibility::WillSucceed: {
emitSuccessfulIndirectUnconditionalCast(B, SwiftMod, loc,
inst->getConsumptionKind(),
@@ -337,7 +341,8 @@ protected:
SILBasicBlock *failBB = getOpBasicBlock(inst->getFailureBB());
SILBuilderWithPostProcess<TypeSubstCloner, 16> B(this, inst);
switch (classifyDynamicCast(SwiftMod, sourceType, targetType)) {
switch (classifyDynamicCast(SwiftMod, sourceType, targetType,
false, inst->getModule().isWholeModule())) {
case DynamicCastFeasibility::WillSucceed: {
emitSuccessfulIndirectUnconditionalCast(B, SwiftMod, loc,
inst->getConsumptionKind(),
@@ -393,13 +398,16 @@ protected:
SILBuilderWithPostProcess<TypeSubstCloner, 16> B(this, inst);
SILValue operand = getOpValue(inst->getOperand());
bool isSourceTypeExact = isa<MetatypeInst>(inst->getOperand());
// The non-addr CheckedCastInsts can currently only be used for
// types that don't have abstraction differences, so this is okay.
CanType sourceType = loweredSourceType.getSwiftRValueType();
CanType targetType = loweredTargetType.getSwiftRValueType();
switch (classifyDynamicCast(SwiftMod, sourceType, targetType)) {
switch (classifyDynamicCast(SwiftMod, sourceType,
targetType, isSourceTypeExact,
inst->getModule().isWholeModule())) {
case DynamicCastFeasibility::WillSucceed: {
// FIXME: this is a temporary workaround to the fact that
// we're still using checked_cast_branch for address-only stuff.