Skip to content

Commit 8521601

Browse files
committed
[silgen] Move ResultPlan from SILGenApply.cpp -> ResultPlan.{h,cpp}
ResultPlan and related constructs have already been written in a type erased fashion. This commit takes advantage of this by moving the details of the code to ResultPlan.{cpp,h}. This slims down SILGenApply.cpp in a NFC way and ensures that other code in SILGenApply can not depend on the details of ResultPlan. Also it is my hope that this can become the beginning of the merging of the ResultPlan from SILGenApply and from SILGenPoly. We should only have 1 way in SILGen to build applies and create apply results. rdar://29791263
1 parent 03a7e16 commit 8521601

File tree

6 files changed

+503
-419
lines changed

6 files changed

+503
-419
lines changed

include/swift/SIL/SILType.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,11 @@ class SILType {
481481
/// Type.
482482
SILType getReferentType(SILModule &M) const;
483483

484+
/// Given two SIL types which are representations of the same type,
485+
/// check whether they have an abstraction difference.
486+
bool hasAbstractionDifference(SILFunctionTypeRepresentation rep,
487+
SILType type2);
488+
484489
/// Returns the hash code for the SILType.
485490
llvm::hash_code getHashCode() const {
486491
return llvm::hash_combine(*this);

lib/SIL/SILType.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,81 @@ SILType SILType::wrapAnyOptionalType(SILFunction &F) const {
630630
BoundEnumDecl->getCanonicalType());
631631
return M.Types.getLoweredType(Pattern, BoundEnumDecl);
632632
}
633+
634+
#ifndef NDEBUG
635+
static bool areOnlyAbstractionDifferent(CanType type1, CanType type2) {
636+
assert(type1->isLegalSILType());
637+
assert(type2->isLegalSILType());
638+
639+
// Exact equality is fine.
640+
if (type1 == type2)
641+
return true;
642+
643+
// Either both types should be optional or neither should be.
644+
if (auto object1 = type1.getAnyOptionalObjectType()) {
645+
auto object2 = type2.getAnyOptionalObjectType();
646+
if (!object2)
647+
return false;
648+
return areOnlyAbstractionDifferent(object1, object2);
649+
}
650+
if (type2.getAnyOptionalObjectType())
651+
return false;
652+
653+
// Either both types should be tuples or neither should be.
654+
if (auto tuple1 = dyn_cast<TupleType>(type1)) {
655+
auto tuple2 = dyn_cast<TupleType>(type2);
656+
if (!tuple2)
657+
return false;
658+
if (tuple1->getNumElements() != tuple2->getNumElements())
659+
return false;
660+
for (auto i : indices(tuple2->getElementTypes()))
661+
if (!areOnlyAbstractionDifferent(tuple1.getElementType(i),
662+
tuple2.getElementType(i)))
663+
return false;
664+
return true;
665+
}
666+
if (isa<TupleType>(type2))
667+
return false;
668+
669+
// Either both types should be metatypes or neither should be.
670+
if (auto meta1 = dyn_cast<AnyMetatypeType>(type1)) {
671+
auto meta2 = dyn_cast<AnyMetatypeType>(type2);
672+
if (!meta2)
673+
return false;
674+
if (meta1.getInstanceType() != meta2.getInstanceType())
675+
return false;
676+
return true;
677+
}
678+
679+
// Either both types should be functions or neither should be.
680+
if (auto fn1 = dyn_cast<SILFunctionType>(type1)) {
681+
auto fn2 = dyn_cast<SILFunctionType>(type2);
682+
if (!fn2)
683+
return false;
684+
// TODO: maybe there are checks we can do here?
685+
(void)fn1;
686+
(void)fn2;
687+
return true;
688+
}
689+
if (isa<SILFunctionType>(type2))
690+
return false;
691+
692+
llvm_unreachable("no other types should differ by abstraction");
693+
}
694+
#endif
695+
696+
/// Given two SIL types which are representations of the same type,
697+
/// check whether they have an abstraction difference.
698+
bool SILType::hasAbstractionDifference(SILFunctionTypeRepresentation rep,
699+
SILType type2) {
700+
CanType ct1 = getSwiftRValueType();
701+
CanType ct2 = type2.getSwiftRValueType();
702+
assert(getSILFunctionLanguage(rep) == SILFunctionLanguage::C ||
703+
areOnlyAbstractionDifferent(ct1, ct2));
704+
(void)ct1;
705+
(void)ct2;
706+
707+
// Assuming that we've applied the same substitutions to both types,
708+
// abstraction equality should equal type equality.
709+
return (*this != type2);
710+
}

lib/SILGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_swift_library(swiftSILGen STATIC
44
Condition.cpp
55
FormalEvaluation.cpp
66
ManagedValue.cpp
7+
ResultPlan.cpp
78
RValue.cpp
89
SwitchCaseFullExpr.cpp
910
SILGen.cpp

0 commit comments

Comments
 (0)