Skip to content

Commit 3ab4d87

Browse files
authored
Merge pull request #23995 from gottesmm/pr-65355143ec1eb896e83dddb893f91fada57d816d
[cast-opt] Combine two blocks with the same condition and invert that…
2 parents fec837a + b6611ee commit 3ab4d87

File tree

1 file changed

+64
-54
lines changed

1 file changed

+64
-54
lines changed

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 64 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,61 @@ findBridgeToObjCFunc(SILOptFunctionBuilder &functionBuilder,
468468
return std::make_pair(bridgedFunc, subMap);
469469
}
470470

471+
static SILValue computeFinalCastedValue(SILBuilderWithScope &builder,
472+
SILDynamicCastInst dynamicCast,
473+
ApplyInst *newAI) {
474+
SILValue dest = dynamicCast.getDest();
475+
SILBasicBlock *failureBB = dynamicCast.getFailureBlock();
476+
auto loc = dynamicCast.getLocation();
477+
auto convTy = newAI->getType();
478+
bool isConditional = dynamicCast.isConditional();
479+
auto destTy = dest->getType().getObjectType();
480+
assert(destTy == dynamicCast.getLoweredBridgedTargetObjectType() &&
481+
"Expected Dest Type to be the same as BridgedTargetTy");
482+
483+
auto &m = dynamicCast.getModule();
484+
if (convTy == destTy) {
485+
return newAI;
486+
}
487+
488+
if (destTy.isExactSuperclassOf(convTy)) {
489+
return builder.createUpcast(loc, newAI, destTy);
490+
}
491+
492+
if (convTy.isExactSuperclassOf(destTy)) {
493+
// If we are not conditional, we are ok with the downcast via checked cast
494+
// fails since we will trap.
495+
if (!isConditional) {
496+
return builder.createUnconditionalCheckedCast(loc, newAI, destTy);
497+
}
498+
499+
// Otherwise if we /are/ emitting a conditional cast, make sure that we
500+
// handle the failure gracefully.
501+
auto *condBrSuccessBB =
502+
newAI->getFunction()->createBasicBlockAfter(newAI->getParent());
503+
condBrSuccessBB->createPhiArgument(destTy, ValueOwnershipKind::Owned,
504+
nullptr);
505+
builder.createCheckedCastBranch(loc, /* isExact*/ false, newAI, destTy,
506+
condBrSuccessBB, failureBB);
507+
builder.setInsertionPoint(condBrSuccessBB, condBrSuccessBB->begin());
508+
return condBrSuccessBB->getArgument(0);
509+
}
510+
511+
if (convTy.getASTType() ==
512+
getNSBridgedClassOfCFClass(m.getSwiftModule(), destTy.getASTType()) ||
513+
destTy.getASTType() ==
514+
getNSBridgedClassOfCFClass(m.getSwiftModule(), convTy.getASTType())) {
515+
// Handle NS <-> CF toll-free bridging here.
516+
return SILValue(builder.createUncheckedRefCast(loc, newAI, destTy));
517+
}
518+
519+
llvm_unreachable(
520+
"optimizeBridgedSwiftToObjCCast: should never reach this condition: if "
521+
"the Destination does not have the same type, is not a bridgeable CF "
522+
"type and isn't a superclass/subclass of the source operand we should "
523+
"have bailed earlier.");
524+
}
525+
471526
/// Create a call of _bridgeToObjectiveC which converts an _ObjectiveCBridgeable
472527
/// instance into a bridged ObjC type.
473528
SILInstruction *
@@ -632,63 +687,18 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
632687
}
633688
}
634689

635-
SILInstruction *NewI = NewAI;
636-
637-
if (Dest) {
638-
// If it is addr cast then store the result.
639-
auto ConvTy = NewAI->getType();
640-
auto DestTy = Dest->getType().getObjectType();
641-
assert(DestTy == SILType::getPrimitiveObjectType(
642-
BridgedTargetTy->getCanonicalType()) &&
643-
"Expected Dest Type to be the same as BridgedTargetTy");
644-
SILValue CastedValue;
645-
if (ConvTy == DestTy) {
646-
CastedValue = NewAI;
647-
} else if (DestTy.isExactSuperclassOf(ConvTy)) {
648-
CastedValue = Builder.createUpcast(Loc, NewAI, DestTy);
649-
} else if (ConvTy.isExactSuperclassOf(DestTy)) {
650-
// The downcast from a base class to derived class may fail.
651-
if (isConditional) {
652-
// In case of a conditional cast, we should handle it gracefully.
653-
auto CondBrSuccessBB =
654-
NewAI->getFunction()->createBasicBlockAfter(NewAI->getParent());
655-
CondBrSuccessBB->createPhiArgument(DestTy, ValueOwnershipKind::Owned,
656-
nullptr);
657-
Builder.createCheckedCastBranch(Loc, /* isExact*/ false, NewAI, DestTy,
658-
CondBrSuccessBB, FailureBB);
659-
Builder.setInsertionPoint(CondBrSuccessBB, CondBrSuccessBB->begin());
660-
CastedValue = CondBrSuccessBB->getArgument(0);
661-
} else {
662-
CastedValue = SILValue(
663-
Builder.createUnconditionalCheckedCast(Loc, NewAI, DestTy));
664-
}
665-
} else if (ConvTy.getASTType() ==
666-
getNSBridgedClassOfCFClass(M.getSwiftModule(),
667-
DestTy.getASTType()) ||
668-
DestTy.getASTType() ==
669-
getNSBridgedClassOfCFClass(M.getSwiftModule(),
670-
ConvTy.getASTType())) {
671-
// Handle NS <-> CF toll-free bridging here.
672-
CastedValue =
673-
SILValue(Builder.createUncheckedRefCast(Loc, NewAI, DestTy));
674-
} else {
675-
llvm_unreachable("optimizeBridgedSwiftToObjCCast: should never reach "
676-
"this condition: if the Destination does not have the "
677-
"same type, is not a bridgeable CF type and isn't a "
678-
"superclass/subclass of the source operand we should "
679-
"have bailed earlier");
680-
}
681-
NewI = Builder.createStore(Loc, CastedValue, Dest,
682-
StoreOwnershipQualifier::Unqualified);
683-
if (isConditional && NewI->getParent() != NewAI->getParent()) {
684-
Builder.createBranch(Loc, SuccessBB);
685-
}
686-
}
690+
if (!Dest)
691+
return NewAI;
687692

688-
if (Dest) {
689-
eraseInstAction(Inst);
693+
// If it is addr cast then store the result.
694+
SILValue castedValue = computeFinalCastedValue(Builder, dynamicCast, NewAI);
695+
SILInstruction *NewI = Builder.createStore(
696+
Loc, castedValue, Dest, StoreOwnershipQualifier::Unqualified);
697+
if (isConditional && NewI->getParent() != NewAI->getParent()) {
698+
Builder.createBranch(Loc, SuccessBB);
690699
}
691700

701+
eraseInstAction(Inst);
692702
return NewI;
693703
}
694704

0 commit comments

Comments
 (0)