@@ -37,38 +37,73 @@ class SILWitnessTable;
3737// / allows a client to determine whether the list is incomplete in the
3838// / sense that there may be unrepresented callees.
3939class 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) {}
4256
4357public:
4458 // / Constructor for when we know nothing about the callees and must
4559 // / assume the worst.
46- CalleeList () : IsIncomplete( true ) {}
60+ CalleeList () : CalleeList( nullptr , Kind::empty, /* incomplete */ true ) {}
4761
4862 // / Constructor for the case where we know an apply can target only
4963 // / a single function.
50- CalleeList (SILFunction *F) : CalleeFunctions(F), IsIncomplete(false ) {}
64+ CalleeList (SILFunction *F)
65+ : CalleeList(F, Kind::singleFunction, /* incomplete*/ false ) {}
5166
5267 // / 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; }
5677
5778 SWIFT_DEBUG_DUMP;
5879
5980 void print (llvm::raw_ostream &os) const ;
6081
6182 // / Return an iterator for the beginning of the list.
6283 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+ }
6492 }
6593
6694 // / Return an iterator for the end of the list.
6795 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+ }
69104 }
70105
71- bool isIncomplete () const { return IsIncomplete ; }
106+ bool isIncomplete () const { return incomplete ; }
72107
73108 // / Returns true if all callees are known and not external.
74109 bool allCalleesVisible () const ;
@@ -80,14 +115,13 @@ class CalleeList {
80115// / any function application site (including those that are simple
81116// / function_ref, thin_to_thick, or partial_apply callees).
82117class CalleeCache {
83- using Callees = llvm::SmallVector<SILFunction *, 16 >;
84- using CalleesAndCanCallUnknown = llvm::PointerIntPair<Callees *, 1 >;
118+ using CalleesAndCanCallUnknown = llvm::PointerIntPair<CalleeList::Callees *, 1 >;
85119 using CacheType = llvm::DenseMap<SILDeclRef, CalleesAndCanCallUnknown>;
86120
87121 SILModule &M;
88122
89123 // Allocator for the SmallVectors that we will be allocating.
90- llvm::SpecificBumpPtrAllocator<Callees> Allocator;
124+ llvm::SpecificBumpPtrAllocator<CalleeList:: Callees> Allocator;
91125
92126 // The cache of precomputed callee lists for function decls appearing
93127 // in class virtual dispatch tables and witness tables.
@@ -106,6 +140,11 @@ class CalleeCache {
106140 // / Return the list of callees that can potentially be called at the
107141 // / given apply site.
108142 CalleeList getCalleeList (FullApplySite FAS) const ;
143+
144+ CalleeList getCalleeListOfValue (SILValue callee) const {
145+ return getCalleeListForCalleeKind (callee);
146+ }
147+
109148 // / Return the list of callees that can potentially be called at the
110149 // / given instruction. E.g. it could be destructors.
111150 CalleeList getCalleeList (SILInstruction *I) const ;
@@ -180,6 +219,11 @@ class BasicCalleeAnalysis : public SILAnalysis {
180219 return Cache->getCalleeList (FAS);
181220 }
182221
222+ CalleeList getCalleeListOfValue (SILValue callee) {
223+ updateCache ();
224+ return Cache->getCalleeListOfValue (callee);
225+ }
226+
183227 CalleeList getCalleeList (SILInstruction *I) {
184228 updateCache ();
185229 return Cache->getCalleeList (I);
0 commit comments