Skip to content

Commit e2e73d2

Browse files
committed
SILGen: Clean up some duplication in getConstantAtUncurryLevel() and getTypeInfoAtUncurryLevel()
1 parent dcf6e2b commit e2e73d2

File tree

1 file changed

+64
-108
lines changed

1 file changed

+64
-108
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 64 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -498,21 +498,62 @@ class Callee {
498498
return result;
499499
}
500500

501+
SILDeclRef getConstantAtUncurryLevel(unsigned level) const {
502+
unsigned uncurryLevel = Constant.getUncurryLevel();
503+
assert(level <= uncurryLevel &&
504+
"uncurrying past natural uncurry level of standalone function");
505+
if (level < uncurryLevel) {
506+
assert(level == 0);
507+
auto constant = Constant.asCurried();
508+
509+
// If we're currying a direct reference to a class-dispatched method,
510+
// make sure we emit the right set of thunks.
511+
if (kind == Kind::StandaloneFunction) {
512+
if (auto func = Constant.getAbstractFunctionDecl()) {
513+
if (getMethodDispatch(func) == MethodDispatch::Class) {
514+
return constant.asDirectReference(true);
515+
}
516+
}
517+
}
518+
519+
return constant;
520+
}
521+
522+
return Constant;
523+
}
524+
525+
SILType getDynamicMethodType(SILGenFunction &SGF) const {
526+
// Lower the substituted type from the AST, which should have any generic
527+
// parameters in the original signature erased to their upper bounds.
528+
auto substFormalType = getSubstFormalType();
529+
auto objcFormalType = substFormalType.withExtInfo(
530+
substFormalType->getExtInfo().withSILRepresentation(
531+
SILFunctionTypeRepresentation::ObjCMethod));
532+
auto fnType = SGF.SGM.M.Types.getUncachedSILFunctionTypeForConstant(
533+
Constant, objcFormalType);
534+
535+
auto closureType = replaceSelfTypeForDynamicLookup(
536+
SGF.getASTContext(), fnType,
537+
SelfValue.getValue().getSILSubstType(SGF).getSwiftRValueType(),
538+
Constant);
539+
540+
return SILType::getPrimitiveObjectType(closureType);
541+
}
542+
501543
ManagedValue getFnValueAtUncurryLevel(SILGenFunction &SGF,
502544
unsigned level) const & {
503545
Optional<SILDeclRef> constant = None;
504546

505547
if (!Constant) {
506548
assert(level == 0 && "can't curry indirect function");
507549
} else {
508-
unsigned uncurryLevel = Constant.getUncurryLevel();
509-
assert(level <= uncurryLevel &&
510-
"uncurrying past natural uncurry level of standalone function");
511-
if (level < uncurryLevel) {
512-
assert(level == 0);
513-
constant = Constant.asCurried();
514-
} else {
515-
constant = Constant;
550+
constant = getConstantAtUncurryLevel(level);
551+
552+
// If the call is curried, emit a direct call to the curry thunk.
553+
if (constant->isCurried) {
554+
auto constantInfo = SGF.getConstantInfo(*constant);
555+
SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
556+
return ManagedValue::forUnmanaged(ref);
516557
}
517558
}
518559

@@ -522,36 +563,13 @@ class Callee {
522563
return IndirectValue;
523564

524565
case Kind::StandaloneFunction: {
525-
// If we're currying a direct reference to a class-dispatched method,
526-
// make sure we emit the right set of thunks.
527-
if (constant->isCurried && Constant.hasDecl())
528-
if (auto func = Constant.getAbstractFunctionDecl())
529-
if (getMethodDispatch(func) == MethodDispatch::Class)
530-
constant = constant->asDirectReference(true);
531-
532-
auto constantInfo = SGF.getConstantInfo(*constant);
533-
SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
534-
return ManagedValue::forUnmanaged(ref);
535-
}
536-
case Kind::EnumElement: {
537566
auto constantInfo = SGF.getConstantInfo(*constant);
538-
539-
// We should not end up here if the enum constructor call is fully
540-
// applied.
541-
assert(constant->isCurried);
542-
543567
SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
544568
return ManagedValue::forUnmanaged(ref);
545569
}
570+
case Kind::EnumElement:
571+
llvm_unreachable("Should have been curried");
546572
case Kind::ClassMethod: {
547-
auto constantInfo = SGF.getConstantInfo(*constant);
548-
549-
// If the call is curried, emit a direct call to the curry thunk.
550-
if (constant->isCurried) {
551-
SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
552-
return ManagedValue::forUnmanaged(ref);
553-
}
554-
555573
auto methodTy = SGF.SGM.Types.getConstantOverrideType(*constant);
556574

557575
// Otherwise, do the dynamic dispatch inline.
@@ -594,15 +612,8 @@ class Callee {
594612
case Kind::WitnessMethod: {
595613
auto constantInfo = SGF.getConstantInfo(*constant);
596614

597-
// If the call is curried, emit a direct call to the curry thunk.
598-
if (constant->isCurried) {
599-
SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
600-
return ManagedValue::forUnmanaged(ref);
601-
}
602-
603-
auto proto = Constant.getDecl()
604-
->getDeclContext()
605-
->getAsProtocolOrProtocolExtensionContext();
615+
auto proto = cast<ProtocolDecl>(
616+
Constant.getDecl()->getDeclContext());
606617
auto lookupType = getSubstFormalType()
607618
.getInput()
608619
->getRValueInstanceType()
@@ -612,32 +623,17 @@ class Callee {
612623
Loc, lookupType, ProtocolConformanceRef(proto), *constant,
613624
constantInfo.getSILType(), constant->isForeign);
614625
return ManagedValue::forUnmanaged(fn);
615-
;
616626
}
617627
case Kind::DynamicMethod: {
618-
assert(!constant->isCurried);
619628
assert(constant->isForeign);
620-
621-
// Lower the substituted type from the AST, which should have any generic
622-
// parameters in the original signature erased to their upper bounds.
623-
auto substFormalType = getSubstFormalType();
624-
auto objcFormalType = substFormalType.withExtInfo(
625-
substFormalType->getExtInfo().withSILRepresentation(
626-
SILFunctionTypeRepresentation::ObjCMethod));
627-
auto fnType = SGF.SGM.M.Types.getUncachedSILFunctionTypeForConstant(
628-
*constant, objcFormalType);
629-
630-
auto closureType = replaceSelfTypeForDynamicLookup(
631-
SGF.getASTContext(), fnType,
632-
SelfValue.getValue().getSILSubstType(SGF).getSwiftRValueType(),
633-
Constant);
629+
auto closureType = getDynamicMethodType(SGF);
634630

635631
Scope S(SGF, Loc);
636632
ManagedValue self =
637633
SelfValue.getValue().borrow(SGF).getAsSingleValue(SGF);
638634
SILValue fn = SGF.B.createObjCMethod(
639635
Loc, self.getValue(), *constant,
640-
SILType::getPrimitiveObjectType(closureType));
636+
closureType);
641637
return ManagedValue::forUnmanaged(fn);
642638
}
643639
}
@@ -650,14 +646,12 @@ class Callee {
650646
if (!Constant) {
651647
assert(level == 0 && "can't curry indirect function");
652648
} else {
653-
unsigned uncurryLevel = Constant.getUncurryLevel();
654-
assert(level <= uncurryLevel &&
655-
"uncurrying past natural uncurry level of standalone function");
656-
if (level < uncurryLevel) {
657-
assert(level == 0);
658-
constant = Constant.asCurried();
659-
} else {
660-
constant = Constant;
649+
constant = getConstantAtUncurryLevel(level);
650+
651+
// If the call is curried, emit a direct call to the curry thunk.
652+
if (constant->isCurried) {
653+
auto constantInfo = SGF.getConstantInfo(*constant);
654+
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
661655
}
662656
}
663657

@@ -667,38 +661,16 @@ class Callee {
667661
return createCalleeTypeInfo(SGF, constant, IndirectValue.getType());
668662

669663
case Kind::StandaloneFunction: {
670-
// If we're currying a direct reference to a class-dispatched method,
671-
// make sure we emit the right set of thunks.
672-
if (constant->isCurried && Constant.hasDecl())
673-
if (auto func = Constant.getAbstractFunctionDecl())
674-
if (getMethodDispatch(func) == MethodDispatch::Class)
675-
constant = constant->asDirectReference(true);
676-
677664
auto constantInfo = SGF.getConstantInfo(*constant);
678665
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
679-
;
680-
}
681-
case Kind::EnumElement: {
682-
auto constantInfo = SGF.getConstantInfo(*constant);
683-
684-
// We should not end up here if the enum constructor call is fully
685-
// applied.
686-
assert(constant->isCurried);
687-
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
688666
}
667+
case Kind::EnumElement:
668+
llvm_unreachable("Should have been curried");
689669
case Kind::ClassMethod: {
690-
// If the call is curried, emit a direct call to the curry thunk.
691-
if (constant->isCurried) {
692-
auto constantInfo = SGF.getConstantInfo(*constant);
693-
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
694-
}
695-
696-
// Otherwise, grab the override info.
697670
auto constantInfo = SGF.SGM.Types.getConstantOverrideInfo(*constant);
698671
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
699672
}
700673
case Kind::SuperMethod: {
701-
assert(!constant->isCurried);
702674
auto base = SGF.SGM.Types.getOverriddenVTableEntry(*constant);
703675
auto constantInfo =
704676
SGF.SGM.Types.getConstantOverrideInfo(*constant, base);
@@ -709,23 +681,7 @@ class Callee {
709681
return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
710682
}
711683
case Kind::DynamicMethod: {
712-
assert(!constant->isCurried);
713-
714-
// Lower the substituted type from the AST, which should have any generic
715-
// parameters in the original signature erased to their upper bounds.
716-
auto substFormalType = getSubstFormalType();
717-
auto objcFormalType = substFormalType.withExtInfo(
718-
substFormalType->getExtInfo().withSILRepresentation(
719-
SILFunctionTypeRepresentation::ObjCMethod));
720-
auto fnType = SGF.SGM.M.Types.getUncachedSILFunctionTypeForConstant(
721-
*constant, objcFormalType);
722-
723-
auto closureType = replaceSelfTypeForDynamicLookup(
724-
SGF.getASTContext(), fnType,
725-
SelfValue.getValue().getSILSubstType(SGF).getSwiftRValueType(),
726-
Constant);
727-
728-
SILType formalType = SILType::getPrimitiveObjectType(closureType);
684+
auto formalType = getDynamicMethodType(SGF);
729685
return createCalleeTypeInfo(SGF, constant, formalType);
730686
}
731687
}

0 commit comments

Comments
 (0)