@@ -646,11 +646,17 @@ void swift::deleteDevirtualizedApply(ApplySite old) {
646
646
}
647
647
648
648
SILFunction *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" );
652
652
653
653
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
+
654
660
return module .lookUpFunctionInVTable (cd, member);
655
661
}
656
662
@@ -672,6 +678,7 @@ CanType swift::getSelfInstanceType(CanType classOrMetatypeType) {
672
678
// / \p cd is the class declaration we are devirtualizing for.
673
679
// / return true if it is possible to devirtualize, false - otherwise.
674
680
bool swift::canDevirtualizeClassMethod (FullApplySite applySite, ClassDecl *cd,
681
+ CanType classType,
675
682
OptRemark::Emitter *ore,
676
683
bool isEffectivelyFinalMethod) {
677
684
@@ -683,7 +690,7 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
683
690
auto *mi = cast<MethodInst>(applySite.getCallee ());
684
691
685
692
// 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);
687
694
688
695
// If we do not find any such function, we have no function to devirtualize
689
696
// to... so bail.
@@ -742,15 +749,15 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
742
749
std::pair<FullApplySite, bool /* changedCFG */ >
743
750
swift::devirtualizeClassMethod (FullApplySite applySite,
744
751
SILValue classOrMetatype, ClassDecl *cd,
745
- OptRemark::Emitter *ore) {
752
+ CanType classType, OptRemark::Emitter *ore) {
746
753
bool changedCFG = false ;
747
754
LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
748
755
<< *applySite.getInstruction ());
749
756
750
757
SILModule &module = applySite.getModule ();
751
758
auto *mi = cast<MethodInst>(applySite.getCallee ());
752
759
753
- auto *f = getTargetClassMethod (module , cd, mi);
760
+ auto *f = getTargetClassMethod (module , cd, classType, mi);
754
761
755
762
CanSILFunctionType genCalleeType = f->getLoweredFunctionTypeInContext (
756
763
TypeExpansionContext (*applySite.getFunction ()));
@@ -835,10 +842,11 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
835
842
836
843
std::pair<FullApplySite, bool > swift::tryDevirtualizeClassMethod (
837
844
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))
840
848
return {FullApplySite (), false };
841
- return devirtualizeClassMethod (applySite, classInstance, cd, ore);
849
+ return devirtualizeClassMethod (applySite, classInstance, cd, classType, ore);
842
850
}
843
851
844
852
// ===----------------------------------------------------------------------===//
@@ -1322,7 +1330,7 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
1322
1330
auto *cd = classType.getClassOrBoundGenericClass ();
1323
1331
1324
1332
if (isEffectivelyFinalMethod (fas, classType, cd, cha))
1325
- return tryDevirtualizeClassMethod (fas, instance, cd, ore,
1333
+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore,
1326
1334
true /* isEffectivelyFinalMethod*/ );
1327
1335
1328
1336
// Try to check if the exact dynamic type of the instance is statically
@@ -1333,13 +1341,14 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
1333
1341
CanType classType = getSelfInstanceType (instance->getType ().getASTType ());
1334
1342
// This should never be null - make the check just to be on the safe side.
1335
1343
if (ClassDecl *cd = classType.getClassOrBoundGenericClass ())
1336
- return tryDevirtualizeClassMethod (fas, instance, cd, ore);
1344
+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore);
1337
1345
return {ApplySite (), false };
1338
1346
}
1339
1347
1340
1348
if (auto exactTy = getExactDynamicType (cmi->getOperand (), cha)) {
1341
1349
if (exactTy == cmi->getOperand ()->getType ())
1342
- return tryDevirtualizeClassMethod (fas, cmi->getOperand (), cd, ore);
1350
+ return tryDevirtualizeClassMethod (fas, cmi->getOperand (), cd, classType,
1351
+ ore);
1343
1352
}
1344
1353
}
1345
1354
@@ -1348,7 +1357,7 @@ swift::tryDevirtualizeApply(ApplySite applySite, ClassHierarchyAnalysis *cha,
1348
1357
auto classType = getSelfInstanceType (instance->getType ().getASTType ());
1349
1358
auto *cd = classType.getClassOrBoundGenericClass ();
1350
1359
1351
- return tryDevirtualizeClassMethod (fas, instance, cd, ore);
1360
+ return tryDevirtualizeClassMethod (fas, instance, cd, classType, ore);
1352
1361
}
1353
1362
1354
1363
return {ApplySite (), false };
@@ -1389,20 +1398,21 @@ bool swift::canDevirtualizeApply(FullApplySite applySite,
1389
1398
auto *cd = classType.getClassOrBoundGenericClass ();
1390
1399
1391
1400
if (isEffectivelyFinalMethod (applySite, classType, cd, cha))
1392
- return canDevirtualizeClassMethod (applySite, cd, nullptr /* ore*/ ,
1401
+ return canDevirtualizeClassMethod (applySite, cd, classType,
1402
+ nullptr /* ore*/ ,
1393
1403
true /* isEffectivelyFinalMethod*/ );
1394
1404
1395
1405
// Try to check if the exact dynamic type of the instance is statically
1396
1406
// known.
1397
1407
if (auto instance = getInstanceWithExactDynamicType (cmi->getOperand (), cha)) {
1398
1408
CanType classType = getSelfInstanceType (instance->getType ().getASTType ());
1399
1409
ClassDecl *cd = classType.getClassOrBoundGenericClass ();
1400
- return cd && canDevirtualizeClassMethod (applySite, cd);
1410
+ return cd && canDevirtualizeClassMethod (applySite, cd, classType );
1401
1411
}
1402
1412
1403
1413
if (auto exactTy = getExactDynamicType (cmi->getOperand (), cha)) {
1404
1414
if (exactTy == cmi->getOperand ()->getType ())
1405
- return canDevirtualizeClassMethod (applySite, cd);
1415
+ return canDevirtualizeClassMethod (applySite, cd, classType );
1406
1416
}
1407
1417
}
1408
1418
@@ -1411,7 +1421,7 @@ bool swift::canDevirtualizeApply(FullApplySite applySite,
1411
1421
auto classType = getSelfInstanceType (instance->getType ().getASTType ());
1412
1422
auto *cd = classType.getClassOrBoundGenericClass ();
1413
1423
1414
- return canDevirtualizeClassMethod (applySite, cd);
1424
+ return canDevirtualizeClassMethod (applySite, cd, classType );
1415
1425
}
1416
1426
1417
1427
return false ;
0 commit comments