Skip to content

Commit ddaea41

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 22e7cd6 + c4b459c commit ddaea41

File tree

3 files changed

+61
-9
lines changed

3 files changed

+61
-9
lines changed

lib/SILOptimizer/Analysis/ClassHierarchyAnalysis.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,47 @@
2020
using namespace swift;
2121

2222
void ClassHierarchyAnalysis::init() {
23+
auto module = M->getSwiftModule();
24+
2325
// For each class declaration in our V-table list:
2426
for (auto &VT : M->getVTableList()) {
2527
ClassDecl *C = VT.getClass();
26-
// Ignore classes that are at the top of the class hierarchy:
27-
if (!C->hasSuperclass())
28-
continue;
2928

30-
// Add the superclass to the list of inherited classes.
31-
ClassDecl *Super = C->getSuperclassDecl();
32-
auto &K = DirectSubclassesCache[Super];
33-
assert(std::find(K.begin(), K.end(), C) == K.end() &&
34-
"Class vector must be unique");
35-
K.push_back(C);
29+
while (true) {
30+
// Ignore classes that are at the top of the class hierarchy:
31+
if (!C->hasSuperclass())
32+
break;
33+
34+
ClassDecl *super = C->getSuperclassDecl();
35+
auto superModule = super->getModuleContext();
36+
37+
// Don't bother collecting subclasses for classes from a different module.
38+
// TODO: cross-module WMO
39+
if (superModule != module)
40+
break;
41+
42+
// Find the superclass's list of direct subclasses. If it's non-empty,
43+
// we've previously walked up to the class, so there's no reason to keep
44+
// walking from this point.
45+
auto &list = DirectSubclassesCache[super];
46+
bool shouldVisitSuper = list.empty();
47+
48+
// Check whether C is already in the list, which can happen
49+
// if we had a v-table that was a subclass of C.
50+
// We expect a linear scan to be cheap enough for this.
51+
if (std::find(list.begin(), list.end(), C) != list.end())
52+
break;
53+
54+
list.push_back(C);
55+
56+
// Keep walking if this is the first time we reached this superclass.
57+
// We have to do this because the SILModule might not have v-tables for
58+
// every class in the module.
59+
if (!shouldVisitSuper)
60+
break;
61+
62+
C = super;
63+
}
3664
}
3765
}
3866

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
class Middle : Base { }
3+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -enable-sil-ownership -module-name test -primary-file %s %S/Inputs/mandatory_inlining_devirt_other.swift -emit-sil -o - | %FileCheck %s
2+
3+
// rdar://45110471
4+
5+
// We only generate SIL v-tables for these two classes in this file, but
6+
// class hierarchy analysis needs to walk through the third class in the
7+
// helper file.
8+
9+
class Base {
10+
fileprivate func foo() { print("base") }
11+
func callit() { foo() }
12+
}
13+
14+
class Derived : Middle {
15+
fileprivate override func foo() { print("derived") }
16+
}
17+
18+
// CHECK-LABEL: sil hidden @$s4test4BaseC6callityyF
19+
// CHECK: [[T0:%.*]] = class_method %0 : $Base, #Base.foo!1
20+
// CHECK-NEXT: apply [[T0]](%0)
21+
// CHECK-LABEL: } // end sil function '$s4test4BaseC6callityyF'

0 commit comments

Comments
 (0)