Skip to content

Commit 2994415

Browse files
committed
SILOptimizer: Simplify castABIcastValueToABICompatibleType()
1 parent 4ed09b4 commit 2994415

File tree

1 file changed

+47
-105
lines changed

1 file changed

+47
-105
lines changed

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 47 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -483,55 +483,53 @@ SILValue swift::castValueToABICompatibleType(SILBuilder *B, SILLocation Loc,
483483
if (SrcTy == DestTy)
484484
return Value;
485485

486-
SILValue CastedValue;
486+
assert(SrcTy.isAddress() == DestTy.isAddress() &&
487+
"Addresses aren't compatible with values");
487488

488489
if (SrcTy.isAddress() && DestTy.isAddress()) {
489490
// Cast between two addresses and that's it.
490-
CastedValue = B->createUncheckedAddrCast(Loc, Value, DestTy);
491-
return CastedValue;
492-
}
493-
494-
if (SrcTy.isAddress() != DestTy.isAddress()) {
495-
// Addresses aren't compatible with values.
496-
llvm_unreachable("Addresses aren't compatible with values");
491+
return B->createUncheckedAddrCast(Loc, Value, DestTy);
497492
}
498493

499-
auto &M = B->getModule();
500-
501-
// Check if src and dest types are optional.
502-
auto OptionalSrcTy = SrcTy.getSwiftRValueType()
503-
.getAnyOptionalObjectType();
504-
auto OptionalDestTy = DestTy.getSwiftRValueType()
505-
.getAnyOptionalObjectType();
506-
507494
// If both types are classes and dest is the superclass of src,
508495
// simply perform an upcast.
509-
if (SrcTy.getSwiftRValueType()->mayHaveSuperclass() &&
510-
DestTy.getSwiftRValueType()->mayHaveSuperclass() &&
511-
DestTy.isExactSuperclassOf(SrcTy)) {
512-
CastedValue = B->createUpcast(Loc, Value, DestTy);
513-
return CastedValue;
496+
if (DestTy.isExactSuperclassOf(SrcTy)) {
497+
return B->createUpcast(Loc, Value, DestTy);
514498
}
515499

516-
SILType OptionalSrcLoweredTy;
517-
SILType OptionalDestLoweredTy;
500+
if (SrcTy.isHeapObjectReferenceType() &&
501+
DestTy.isHeapObjectReferenceType()) {
502+
return B->createUncheckedRefCast(Loc, Value, DestTy);
503+
}
518504

519-
if (OptionalSrcTy)
520-
OptionalSrcLoweredTy = M.Types.getLoweredType(OptionalSrcTy);
505+
if (auto mt1 = dyn_cast<AnyMetatypeType>(SrcTy.getSwiftRValueType())) {
506+
if (auto mt2 = dyn_cast<AnyMetatypeType>(DestTy.getSwiftRValueType())) {
507+
if (mt1->getRepresentation() == mt2->getRepresentation()) {
508+
// If B.Type needs to be casted to A.Type and
509+
// A is a superclass of B, then it can be done by means
510+
// of a simple upcast.
511+
if (mt2.getInstanceType()->isExactSuperclassOf(
512+
mt1.getInstanceType(), nullptr)) {
513+
return B->createUpcast(Loc, Value, DestTy);
514+
}
515+
516+
// Cast between two metatypes and that's it.
517+
return B->createUncheckedBitCast(Loc, Value, DestTy);
518+
}
519+
}
520+
}
521521

522-
if (OptionalDestTy)
523-
OptionalDestLoweredTy = M.Types.getLoweredType(OptionalDestTy);
522+
// Check if src and dest types are optional.
523+
auto OptionalSrcTy = SrcTy.getAnyOptionalObjectType();
524+
auto OptionalDestTy = DestTy.getAnyOptionalObjectType();
524525

525526
// Both types are optional.
526527
if (OptionalDestTy && OptionalSrcTy) {
527528
// If both wrapped types are classes and dest is the superclass of src,
528529
// simply perform an upcast.
529-
if (OptionalDestTy->mayHaveSuperclass() &&
530-
OptionalSrcTy->mayHaveSuperclass() &&
531-
OptionalDestLoweredTy.isExactSuperclassOf(OptionalSrcLoweredTy)) {
530+
if (OptionalDestTy.isExactSuperclassOf(OptionalSrcTy)) {
532531
// Insert upcast.
533-
CastedValue = B->createUpcast(Loc, Value, DestTy);
534-
return CastedValue;
532+
return B->createUpcast(Loc, Value, DestTy);
535533
}
536534

537535
// Unwrap the original optional value.
@@ -555,10 +553,10 @@ SILValue swift::castValueToABICompatibleType(SILBuilder *B, SILLocation Loc,
555553
// Cast the unwrapped value.
556554
auto CastedUnwrappedValue =
557555
castValueToABICompatibleType(B, Loc, UnwrappedValue,
558-
OptionalSrcLoweredTy,
559-
OptionalDestLoweredTy);
556+
OptionalSrcTy,
557+
OptionalDestTy);
560558
// Wrap into optional.
561-
CastedValue = B->createOptionalSome(Loc, CastedUnwrappedValue, DestTy);
559+
auto CastedValue = B->createOptionalSome(Loc, CastedUnwrappedValue, DestTy);
562560
B->createBranch(Loc, ContBB, {CastedValue});
563561

564562
// Handle the None case.
@@ -567,15 +565,15 @@ SILValue swift::castValueToABICompatibleType(SILBuilder *B, SILLocation Loc,
567565
B->createBranch(Loc, ContBB, {CastedValue});
568566
B->setInsertionPoint(ContBB->begin());
569567

570-
CastedValue = ContBB->getArgument(0);
571-
return CastedValue;
568+
return ContBB->getArgument(0);
572569
}
573570

574571
// Src is not optional, but dest is optional.
575572
if (!OptionalSrcTy && OptionalDestTy) {
576-
auto OptionalSrcCanTy =
577-
OptionalType::get(SrcTy.getSwiftRValueType())->getCanonicalType();
578-
auto LoweredOptionalSrcType = M.Types.getLoweredType(OptionalSrcCanTy);
573+
auto OptionalSrcCanTy = OptionalType::get(SrcTy.getSwiftRValueType())
574+
->getCanonicalType();
575+
auto LoweredOptionalSrcType = SILType::getPrimitiveObjectType(
576+
OptionalSrcCanTy);
579577

580578
// Wrap the source value into an optional first.
581579
SILValue WrappedValue = B->createOptionalSome(Loc, Value,
@@ -586,88 +584,32 @@ SILValue swift::castValueToABICompatibleType(SILBuilder *B, SILLocation Loc,
586584
DestTy);
587585
}
588586

589-
// Both types are not optional.
590-
if (SrcTy.getSwiftRValueType()->mayHaveSuperclass() &&
591-
DestTy.getSwiftRValueType()->mayHaveSuperclass()) {
592-
if (DestTy.isExactSuperclassOf(SrcTy)) {
593-
// Insert upcast.
594-
CastedValue = B->createUpcast(Loc, Value, DestTy);
595-
return CastedValue;
596-
}
597-
598-
// Cast the reference.
599-
CastedValue = B->createUncheckedRefCast(Loc, Value, DestTy);
600-
return CastedValue;
601-
}
602-
603-
// If B.Type needs to be casted to A.Type and
604-
// A is a superclass of B, then it can be done by means
605-
// of a simple upcast.
606-
if (isa<AnyMetatypeType>(SrcTy.getSwiftRValueType()) &&
607-
isa<AnyMetatypeType>(DestTy.getSwiftRValueType()) &&
608-
SrcTy.isClassOrClassMetatype() &&
609-
DestTy.getMetatypeInstanceType(M).isExactSuperclassOf(
610-
SrcTy.getMetatypeInstanceType(M))) {
611-
CastedValue = B->createUpcast(Loc, Value, DestTy);
612-
return CastedValue;
613-
}
614-
615-
if (auto mt1 = dyn_cast<AnyMetatypeType>(SrcTy.getSwiftRValueType())) {
616-
if (auto mt2 = dyn_cast<AnyMetatypeType>(DestTy.getSwiftRValueType())) {
617-
if (mt1->getRepresentation() == mt2->getRepresentation()) {
618-
// Cast between two metatypes and that's it.
619-
CastedValue = B->createUncheckedBitCast(Loc, Value, DestTy);
620-
return CastedValue;
621-
}
622-
}
623-
}
624-
625-
if (SrcTy.isAddress() && DestTy.isAddress()) {
626-
CastedValue = B->createUncheckedAddrCast(Loc, Value, DestTy);
627-
return CastedValue;
628-
}
629-
630-
if (SrcTy.isHeapObjectReferenceType() && DestTy.isHeapObjectReferenceType()) {
631-
CastedValue = B->createUncheckedRefCast(Loc, Value, DestTy);
632-
return CastedValue;
633-
}
634-
635587
// Handle tuple types.
636588
// Extract elements, cast each of them, create a new tuple.
637-
if (auto tup = SrcTy.getAs<TupleType>()) {
638-
SmallVector<CanType, 1> aElements, bElements;
639-
auto atypes = tup.getElementTypes();
640-
aElements.append(atypes.begin(), atypes.end());
641-
auto btypes = DestTy.getAs<TupleType>().getElementTypes();
642-
bElements.append(btypes.begin(), btypes.end());
643-
644-
assert (aElements.size() == bElements.size() &&
645-
"Tuple types should have the same number of elements");
646-
589+
if (auto SrcTupleTy = SrcTy.getAs<TupleType>()) {
647590
SmallVector<SILValue, 8> ExpectedTuple;
648-
for (unsigned i : indices(aElements)) {
649-
auto aa = M.Types.getLoweredType(aElements[i]),
650-
bb = M.Types.getLoweredType(bElements[i]);
651-
591+
for (unsigned i = 0, e = SrcTupleTy->getNumElements(); i < e; i++) {
652592
SILValue Element = B->createTupleExtract(Loc, Value, i);
653593
// Cast the value if necessary.
654-
Element = castValueToABICompatibleType(B, Loc, Element, aa, bb);
594+
Element = castValueToABICompatibleType(B, Loc, Element,
595+
SrcTy.getTupleElementType(i),
596+
DestTy.getTupleElementType(i));
655597
ExpectedTuple.push_back(Element);
656598
}
657599

658-
CastedValue = B->createTuple(Loc, DestTy, ExpectedTuple);
659-
return CastedValue;
600+
return B->createTuple(Loc, DestTy, ExpectedTuple);
660601
}
661602

662603
// Function types are interchangeable if they're also ABI-compatible.
663604
if (SrcTy.getAs<SILFunctionType>()) {
664605
if (DestTy.getAs<SILFunctionType>()) {
665606
// Insert convert_function.
666-
CastedValue = B->createConvertFunction(Loc, Value, DestTy);
667-
return CastedValue;
607+
return B->createConvertFunction(Loc, Value, DestTy);
668608
}
669609
}
670610

611+
llvm::errs() << "Source type: " << SrcTy << "\n";
612+
llvm::errs() << "Destination type: " << DestTy << "\n";
671613
llvm_unreachable("Unknown combination of types for casting");
672614
}
673615

0 commit comments

Comments
 (0)