@@ -37,38 +37,73 @@ class SILWitnessTable;
37
37
// / allows a client to determine whether the list is incomplete in the
38
38
// / sense that there may be unrepresented callees.
39
39
class CalleeList {
40
- llvm::TinyPtrVector<SILFunction *> CalleeFunctions;
41
- bool IsIncomplete;
40
+ friend class CalleeCache ;
41
+
42
+ using Callees = llvm::SmallVector<SILFunction *, 16 >;
43
+
44
+ void *functionOrCallees;
45
+
46
+ enum class Kind : uint8_t {
47
+ empty,
48
+ singleFunction,
49
+ multipleCallees
50
+ } kind;
51
+
52
+ bool incomplete;
53
+
54
+ CalleeList (void *ptr, Kind kind, bool isIncomplete) :
55
+ functionOrCallees (ptr), kind(kind), incomplete(isIncomplete) {}
42
56
43
57
public:
44
58
// / Constructor for when we know nothing about the callees and must
45
59
// / assume the worst.
46
- CalleeList () : IsIncomplete( true ) {}
60
+ CalleeList () : CalleeList( nullptr , Kind::empty, /* incomplete */ true ) {}
47
61
48
62
// / Constructor for the case where we know an apply can target only
49
63
// / a single function.
50
- CalleeList (SILFunction *F) : CalleeFunctions(F), IsIncomplete(false ) {}
64
+ CalleeList (SILFunction *F)
65
+ : CalleeList(F, Kind::singleFunction, /* incomplete*/ false ) {}
51
66
52
67
// / Constructor for arbitrary lists of callees.
53
- CalleeList (llvm::SmallVectorImpl<SILFunction *> &List, bool IsIncomplete)
54
- : CalleeFunctions(llvm::makeArrayRef(List.begin(), List.end())),
55
- IsIncomplete (IsIncomplete) {}
68
+ CalleeList (Callees *callees, bool IsIncomplete)
69
+ : CalleeList(callees, Kind::multipleCallees, IsIncomplete) {}
70
+
71
+ static CalleeList fromOpaque (void *ptr, unsigned char kind, unsigned char isComplete) {
72
+ return CalleeList (ptr, (Kind)kind, (bool )isComplete);
73
+ }
74
+
75
+ void *getOpaquePtr () const { return functionOrCallees; }
76
+ unsigned char getOpaqueKind () const { return (unsigned char )kind; }
56
77
57
78
SWIFT_DEBUG_DUMP;
58
79
59
80
void print (llvm::raw_ostream &os) const ;
60
81
61
82
// / Return an iterator for the beginning of the list.
62
83
ArrayRef<SILFunction *>::iterator begin () const {
63
- return CalleeFunctions.begin ();
84
+ switch (kind) {
85
+ case Kind::empty:
86
+ return nullptr ;
87
+ case Kind::singleFunction:
88
+ return (SILFunction * const *)&functionOrCallees;
89
+ case Kind::multipleCallees:
90
+ return ((Callees *)functionOrCallees)->begin ();
91
+ }
64
92
}
65
93
66
94
// / Return an iterator for the end of the list.
67
95
ArrayRef<SILFunction *>::iterator end () const {
68
- return CalleeFunctions.end ();
96
+ switch (kind) {
97
+ case Kind::empty:
98
+ return nullptr ;
99
+ case Kind::singleFunction:
100
+ return (SILFunction * const *)&functionOrCallees + 1 ;
101
+ case Kind::multipleCallees:
102
+ return ((Callees *)functionOrCallees)->end ();
103
+ }
69
104
}
70
105
71
- bool isIncomplete () const { return IsIncomplete ; }
106
+ bool isIncomplete () const { return incomplete ; }
72
107
73
108
// / Returns true if all callees are known and not external.
74
109
bool allCalleesVisible () const ;
@@ -80,14 +115,13 @@ class CalleeList {
80
115
// / any function application site (including those that are simple
81
116
// / function_ref, thin_to_thick, or partial_apply callees).
82
117
class CalleeCache {
83
- using Callees = llvm::SmallVector<SILFunction *, 16 >;
84
- using CalleesAndCanCallUnknown = llvm::PointerIntPair<Callees *, 1 >;
118
+ using CalleesAndCanCallUnknown = llvm::PointerIntPair<CalleeList::Callees *, 1 >;
85
119
using CacheType = llvm::DenseMap<SILDeclRef, CalleesAndCanCallUnknown>;
86
120
87
121
SILModule &M;
88
122
89
123
// Allocator for the SmallVectors that we will be allocating.
90
- llvm::SpecificBumpPtrAllocator<Callees> Allocator;
124
+ llvm::SpecificBumpPtrAllocator<CalleeList:: Callees> Allocator;
91
125
92
126
// The cache of precomputed callee lists for function decls appearing
93
127
// in class virtual dispatch tables and witness tables.
@@ -106,6 +140,11 @@ class CalleeCache {
106
140
// / Return the list of callees that can potentially be called at the
107
141
// / given apply site.
108
142
CalleeList getCalleeList (FullApplySite FAS) const ;
143
+
144
+ CalleeList getCalleeListOfValue (SILValue callee) const {
145
+ return getCalleeListForCalleeKind (callee);
146
+ }
147
+
109
148
// / Return the list of callees that can potentially be called at the
110
149
// / given instruction. E.g. it could be destructors.
111
150
CalleeList getCalleeList (SILInstruction *I) const ;
@@ -180,6 +219,11 @@ class BasicCalleeAnalysis : public SILAnalysis {
180
219
return Cache->getCalleeList (FAS);
181
220
}
182
221
222
+ CalleeList getCalleeListOfValue (SILValue callee) {
223
+ updateCache ();
224
+ return Cache->getCalleeListOfValue (callee);
225
+ }
226
+
183
227
CalleeList getCalleeList (SILInstruction *I) {
184
228
updateCache ();
185
229
return Cache->getCalleeList (I);
0 commit comments