@@ -646,11 +646,17 @@ void swift::deleteDevirtualizedApply(ApplySite old) {
646646}
647647
648648SILFunction *swift::getTargetClassMethod (SILModule &module , ClassDecl *cd,
649- MethodInst *mi) {
650- assert ((isa<ClassMethodInst>(mi) || isa<SuperMethodInst>(mi))
651- && " Only class_method and super_method instructions are supported" );
649+ CanType classType, MethodInst *mi) {
650+ assert ((isa<ClassMethodInst>(mi) || isa<SuperMethodInst>(mi)) &&
651+ " Only class_method and super_method instructions are supported" );
652652
653653 SILDeclRef member = mi->getMember ();
654+
655+ SILType silType = SILType::getPrimitiveObjectType (classType);
656+ if (auto *vtable = module .lookUpSpecializedVTable (silType)) {
657+ return vtable->getEntry (module , member)->getImplementation ();
658+ }
659+
654660 return module .lookUpFunctionInVTable (cd, member);
655661}
656662
@@ -672,6 +678,7 @@ CanType swift::getSelfInstanceType(CanType classOrMetatypeType) {
672678// / \p cd is the class declaration we are devirtualizing for.
673679// / return true if it is possible to devirtualize, false - otherwise.
674680bool swift::canDevirtualizeClassMethod (FullApplySite applySite, ClassDecl *cd,
681+ CanType classType,
675682 OptRemark::Emitter *ore,
676683 bool isEffectivelyFinalMethod) {
677684
@@ -683,7 +690,7 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
683690 auto *mi = cast<MethodInst>(applySite.getCallee ());
684691
685692 // Find the implementation of the member which should be invoked.
686- auto *f = getTargetClassMethod (module , cd, mi);
693+ auto *f = getTargetClassMethod (module , cd, classType, mi);
687694
688695 // If we do not find any such function, we have no function to devirtualize
689696 // to... so bail.
@@ -742,15 +749,15 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
742749std::pair<FullApplySite, bool /* changedCFG */ >
743750swift::devirtualizeClassMethod (FullApplySite applySite,
744751 SILValue classOrMetatype, ClassDecl *cd,
745- OptRemark::Emitter *ore) {
752+ CanType classType, OptRemark::Emitter *ore) {
746753 bool changedCFG = false ;
747754 LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
748755 << *applySite.getInstruction ());
749756
750757 SILModule &module = applySite.getModule ();
751758 auto *mi = cast<MethodInst>(applySite.getCallee ());
752759
753- auto *f = getTargetClassMethod (module , cd, mi);
760+ auto *f = getTargetClassMethod (module , cd, classType, mi);
754761
755762 CanSILFunctionType genCalleeType = f->getLoweredFunctionTypeInContext (
756763 TypeExpansionContext (*applySite.getFunction ()));
@@ -835,10 +842,11 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
835842
836843std::pair<FullApplySite, bool > swift::tryDevirtualizeClassMethod (
837844 FullApplySite applySite, SILValue classInstance, ClassDecl *cd,
838- OptRemark::Emitter *ore, bool isEffectivelyFinalMethod) {
839- if (!canDevirtualizeClassMethod (applySite, cd, ore, isEffectivelyFinalMethod))
845+ CanType classType, OptRemark::Emitter *ore, bool isEffectivelyFinalMethod) {
846+ if (!canDevirtualizeClassMethod (applySite, cd, classType, ore,
847+ isEffectivelyFinalMethod))
840848 return {FullApplySite (), false };
841- return devirtualizeClassMethod (applySite, classInstance, cd, ore);
849+ return devirtualizeClassMethod (applySite, classInstance, cd, classType, ore);
842850}
843851
844852// ===----------------------------------------------------------------------===//
@@ -1322,7 +1330,7 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
13221330 auto *cd = classType.getClassOrBoundGenericClass ();
13231331
13241332 if (isEffectivelyFinalMethod (fas, classType, cd, cha))
1325- return tryDevirtualizeClassMethod (fas, instance, cd, ore,
1333+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore,
13261334 true /* isEffectivelyFinalMethod*/ );
13271335
13281336 // Try to check if the exact dynamic type of the instance is statically
@@ -1333,13 +1341,14 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
13331341 CanType classType = getSelfInstanceType (instance->getType ().getASTType ());
13341342 // This should never be null - make the check just to be on the safe side.
13351343 if (ClassDecl *cd = classType.getClassOrBoundGenericClass ())
1336- return tryDevirtualizeClassMethod (fas, instance, cd, ore);
1344+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore);
13371345 return {ApplySite (), false };
13381346 }
13391347
13401348 if (auto exactTy = getExactDynamicType (cmi->getOperand (), cha)) {
13411349 if (exactTy == cmi->getOperand ()->getType ())
1342- return tryDevirtualizeClassMethod (fas, cmi->getOperand (), cd, ore);
1350+ return tryDevirtualizeClassMethod (fas, cmi->getOperand (), cd, classType,
1351+ ore);
13431352 }
13441353 }
13451354
@@ -1348,7 +1357,7 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
13481357 auto classType = getSelfInstanceType (instance->getType ().getASTType ());
13491358 auto *cd = classType.getClassOrBoundGenericClass ();
13501359
1351- return tryDevirtualizeClassMethod (fas, instance, cd, ore);
1360+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore);
13521361 }
13531362
13541363 return {ApplySite (), false };
@@ -1389,20 +1398,21 @@ bool swift::canDevirtualizeApply(FullApplySite applySite,
13891398 auto *cd = classType.getClassOrBoundGenericClass ();
13901399
13911400 if (isEffectivelyFinalMethod (applySite, classType, cd, cha))
1392- return canDevirtualizeClassMethod (applySite, cd, nullptr /* ore*/ ,
1401+ return canDevirtualizeClassMethod (applySite, cd, classType,
1402+ nullptr /* ore*/ ,
13931403 true /* isEffectivelyFinalMethod*/ );
13941404
13951405 // Try to check if the exact dynamic type of the instance is statically
13961406 // known.
13971407 if (auto instance = getInstanceWithExactDynamicType (cmi->getOperand (), cha)) {
13981408 CanType classType = getSelfInstanceType (instance->getType ().getASTType ());
13991409 ClassDecl *cd = classType.getClassOrBoundGenericClass ();
1400- return cd && canDevirtualizeClassMethod (applySite, cd);
1410+ return cd && canDevirtualizeClassMethod (applySite, cd, classType );
14011411 }
14021412
14031413 if (auto exactTy = getExactDynamicType (cmi->getOperand (), cha)) {
14041414 if (exactTy == cmi->getOperand ()->getType ())
1405- return canDevirtualizeClassMethod (applySite, cd);
1415+ return canDevirtualizeClassMethod (applySite, cd, classType );
14061416 }
14071417 }
14081418
@@ -1411,7 +1421,7 @@ bool swift::canDevirtualizeApply(FullApplySite applySite,
14111421 auto classType = getSelfInstanceType (instance->getType ().getASTType ());
14121422 auto *cd = classType.getClassOrBoundGenericClass ();
14131423
1414- return canDevirtualizeClassMethod (applySite, cd);
1424+ return canDevirtualizeClassMethod (applySite, cd, classType );
14151425 }
14161426
14171427 return false ;
0 commit comments