@@ -38,12 +38,12 @@ class ExistentialSpecializer : public SILFunctionTransform {
38
38
// / Determine if the current function is a target for existential
39
39
// / specialization of args.
40
40
bool canSpecializeExistentialArgsInFunction (
41
- ApplySite &Apply,
41
+ FullApplySite &Apply,
42
42
llvm::SmallDenseMap<int , ExistentialTransformArgumentDescriptor>
43
43
&ExistentialArgDescriptor);
44
44
45
45
// / Can Callee be specialized?
46
- bool canSpecializeCalleeFunction (ApplySite &Apply);
46
+ bool canSpecializeCalleeFunction (FullApplySite &Apply);
47
47
48
48
// / Specialize existential args in function F.
49
49
void specializeExistentialArgsInAppliesWithinFunction (SILFunction &F);
@@ -70,82 +70,6 @@ class ExistentialSpecializer : public SILFunctionTransform {
70
70
};
71
71
} // namespace
72
72
73
- // / Find concrete type from init_existential_refs/addrs.
74
- static bool findConcreteTypeFromInitExistential (SILValue Arg,
75
- CanType &ConcreteType) {
76
- if (auto *IER = dyn_cast<InitExistentialRefInst>(Arg)) {
77
- ConcreteType = IER->getFormalConcreteType ();
78
- return true ;
79
- } else if (auto *IE = dyn_cast<InitExistentialAddrInst>(Arg)) {
80
- ConcreteType = IE->getFormalConcreteType ();
81
- return true ;
82
- }
83
- return false ;
84
- }
85
-
86
- // / Find the concrete type of the existential argument. Wrapper
87
- // / for findInitExistential in Local.h/cpp. In future, this code
88
- // / can move to Local.h/cpp.
89
- static bool findConcreteType (ApplySite AI, int ArgIdx, CanType &ConcreteType) {
90
- bool isCopied = false ;
91
- auto Arg = AI.getArgument (ArgIdx);
92
-
93
- // / Ignore any unconditional cast instructions. Is it Safe? Do we need to
94
- // / also add UnconditionalCheckedCastAddrInst? TODO.
95
- if (auto *Instance = dyn_cast<UnconditionalCheckedCastInst>(Arg)) {
96
- Arg = Instance->getOperand ();
97
- }
98
-
99
- // / Return init_existential if the Arg is global_addr.
100
- if (auto *GAI = dyn_cast<GlobalAddrInst>(Arg)) {
101
- SILValue InitExistential =
102
- findInitExistentialFromGlobalAddrAndApply (GAI, AI, ArgIdx);
103
- // / If the Arg is already init_existential, return the concrete type.
104
- if (InitExistential &&
105
- findConcreteTypeFromInitExistential (InitExistential, ConcreteType)) {
106
- return true ;
107
- }
108
- }
109
-
110
- // / Handle AllocStack instruction separately.
111
- if (auto *Instance = dyn_cast<AllocStackInst>(Arg)) {
112
- if (SILValue Src =
113
- getAddressOfStackInit (Instance, AI.getInstruction (), isCopied)) {
114
- Arg = Src;
115
- }
116
- }
117
-
118
- // / If the Arg is already init_existential after getAddressofStackInit
119
- // / call, return the concrete type.
120
- if (findConcreteTypeFromInitExistential (Arg, ConcreteType)) {
121
- return true ;
122
- }
123
-
124
- // / Call findInitExistential and determine the init_existential.
125
- ArchetypeType *OpenedArchetype = nullptr ;
126
- SILValue OpenedArchetypeDef;
127
- auto FAS = FullApplySite::isa (AI.getInstruction ());
128
- if (!FAS)
129
- return false ;
130
- SILInstruction *InitExistential =
131
- findInitExistential (FAS.getArgumentOperands ()[ArgIdx], OpenedArchetype,
132
- OpenedArchetypeDef, isCopied);
133
- if (!InitExistential) {
134
- LLVM_DEBUG (llvm::dbgs () << " ExistentialSpecializer Pass: Bail! Due to "
135
- " findInitExistential\n " ;);
136
- return false ;
137
- }
138
-
139
- // / Return the concrete type from init_existential returned from
140
- // / findInitExistential.
141
- if (auto *SingleVal = InitExistential->castToSingleValueInstruction ()) {
142
- if (findConcreteTypeFromInitExistential (SingleVal, ConcreteType)) {
143
- return true ;
144
- }
145
- }
146
- return false ;
147
- }
148
-
149
73
// / Check if the argument Arg is used in a destroy_use instruction.
150
74
static void
151
75
findIfCalleeUsesArgInDestroyUse (SILValue Arg,
@@ -162,17 +86,21 @@ findIfCalleeUsesArgInDestroyUse(SILValue Arg,
162
86
// / Check if any apply argument meets the criteria for existential
163
87
// / specialization.
164
88
bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction (
165
- ApplySite &Apply,
89
+ FullApplySite &Apply,
166
90
llvm::SmallDenseMap<int , ExistentialTransformArgumentDescriptor>
167
91
&ExistentialArgDescriptor) {
168
92
auto *F = Apply.getReferencedFunction ();
169
- auto Args = F->begin ()->getFunctionArguments ();
93
+ auto CalleeArgs = F->begin ()->getFunctionArguments ();
170
94
bool returnFlag = false ;
171
95
172
- // / Analyze the argument for protocol conformance.
173
- for (unsigned Idx = 0 , Num = Args.size (); Idx < Num; ++Idx) {
174
- auto Arg = Args[Idx];
175
- auto ArgType = Arg->getType ();
96
+ // / Analyze the argument for protocol conformance. Iterator over the callee's
97
+ // / function arguments. The same SIL argument index is used for both caller
98
+ // / and callee side arguments.
99
+ auto origCalleeConv = Apply.getOrigCalleeConv ();
100
+ assert (Apply.getCalleeArgIndexOfFirstAppliedArg () == 0 );
101
+ for (unsigned Idx = 0 , Num = CalleeArgs.size (); Idx < Num; ++Idx) {
102
+ auto CalleeArg = CalleeArgs[Idx];
103
+ auto ArgType = CalleeArg->getType ();
176
104
auto SwiftArgType = ArgType.getASTType ();
177
105
178
106
// / Checking for AnyObject and Any is added to ensure that we do not blow up
@@ -184,18 +112,21 @@ bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
184
112
continue ;
185
113
186
114
auto ExistentialRepr =
187
- Arg->getType ().getPreferredExistentialRepresentation (F->getModule ());
115
+ CalleeArg->getType ().getPreferredExistentialRepresentation (
116
+ F->getModule ());
188
117
if (ExistentialRepr != ExistentialRepresentation::Opaque &&
189
118
ExistentialRepr != ExistentialRepresentation::Class)
190
119
continue ;
191
120
192
121
// / Find the concrete type.
193
- CanType ConcreteType;
194
- if (!findConcreteType (Apply, Idx, ConcreteType)) {
122
+ Operand &ArgOper = Apply.getArgumentRef (Idx);
123
+ CanType ConcreteType =
124
+ ConcreteExistentialInfo (ArgOper.get (), ArgOper.getUser ()).ConcreteType ;
125
+ if (!ConcreteType) {
195
126
LLVM_DEBUG (
196
127
llvm::dbgs ()
197
- << " ExistentialSpecializer Pass: Bail! Due to findConcreteType "
198
- " for callee :"
128
+ << " ExistentialSpecializer Pass: Bail! cannot find ConcreteType "
129
+ " for call argument to :"
199
130
<< F->getName () << " in caller:"
200
131
<< Apply.getInstruction ()->getParent ()->getParent ()->getName ()
201
132
<< " \n " ;);
@@ -205,15 +136,15 @@ bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
205
136
// / Determine attributes of the existential addr arguments such as
206
137
// / destroy_use, immutable_access.
207
138
ExistentialTransformArgumentDescriptor ETAD;
208
- ETAD.AccessType =
209
- Apply.getOrigCalleeType ()->getParameters ()[Idx].isIndirectMutating () ||
210
- Apply.getOrigCalleeType ()->getParameters ()[Idx].isConsumed ()
211
- ? OpenedExistentialAccess::Mutable
212
- : OpenedExistentialAccess::Immutable;
139
+ auto paramInfo = origCalleeConv.getParamInfoForSILArg (Idx);
140
+ ETAD.AccessType = (paramInfo.isIndirectMutating () || paramInfo.isConsumed ())
141
+ ? OpenedExistentialAccess::Mutable
142
+ : OpenedExistentialAccess::Immutable;
213
143
ETAD.DestroyAddrUse = false ;
214
- if ((Args[Idx]->getType ().getPreferredExistentialRepresentation (
215
- F->getModule ())) != ExistentialRepresentation::Class)
216
- findIfCalleeUsesArgInDestroyUse (Arg, ETAD);
144
+ if ((CalleeArgs[Idx]->getType ().getPreferredExistentialRepresentation (
145
+ F->getModule ()))
146
+ != ExistentialRepresentation::Class)
147
+ findIfCalleeUsesArgInDestroyUse (CalleeArg, ETAD);
217
148
218
149
// / Save the attributes
219
150
ExistentialArgDescriptor[Idx] = ETAD;
@@ -226,12 +157,7 @@ bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
226
157
}
227
158
228
159
// / Determine if this callee function can be specialized or not.
229
- bool ExistentialSpecializer::canSpecializeCalleeFunction (ApplySite &Apply) {
230
-
231
- // / Do not handle partial applies.
232
- if (isa<PartialApplyInst>(Apply.getInstruction ())) {
233
- return false ;
234
- }
160
+ bool ExistentialSpecializer::canSpecializeCalleeFunction (FullApplySite &Apply) {
235
161
236
162
// / Determine the caller of the apply.
237
163
auto *Callee = Apply.getReferencedFunction ();
@@ -285,7 +211,7 @@ void ExistentialSpecializer::specializeExistentialArgsInAppliesWithinFunction(
285
211
auto *I = &*It;
286
212
287
213
// / Is it an apply site?
288
- ApplySite Apply = ApplySite ::isa (I);
214
+ FullApplySite Apply = FullApplySite ::isa (I);
289
215
if (!Apply)
290
216
continue ;
291
217
0 commit comments