@@ -159,17 +159,10 @@ class FunctionSignatureTransform {
159
159
void OwnedToGuaranteedTransformFunctionParameters ();
160
160
161
161
// / Find any owned to guaranteed opportunities.
162
- bool OwnedToGuaranteedAnalyze () {
163
- bool Result = OwnedToGuaranteedAnalyzeResults ();
164
- bool Params = OwnedToGuaranteedAnalyzeParameters ();
165
- return Params || Result;
166
- }
162
+ bool OwnedToGuaranteedAnalyze ();
167
163
168
164
// / Do the actual owned to guaranteed transformations.
169
- void OwnedToGuaranteedTransform () {
170
- OwnedToGuaranteedTransformFunctionResults ();
171
- OwnedToGuaranteedTransformFunctionParameters ();
172
- }
165
+ void OwnedToGuaranteedTransform ();
173
166
174
167
// / Set up epilogue work for the thunk result based in the given argument.
175
168
void OwnedToGuaranteedAddResultRelease (ResultDescriptor &RD,
@@ -197,25 +190,8 @@ class FunctionSignatureTransform {
197
190
// / Every transformation must defines this interface. Default implementation
198
191
// / simply passes it through.
199
192
void addThunkArgument (ArgumentDescriptor &AD, SILBuilder &Builder,
200
- SILBasicBlock *BB,
201
- llvm::SmallVectorImpl<SILValue> &NewArgs) {
202
- // Dead argument.
203
- if (AD.IsEntirelyDead ) {
204
- return ;
205
- }
206
-
207
- // Explode the argument.
208
- if (AD.Explode ) {
209
- llvm::SmallVector<SILValue, 4 > LeafValues;
210
- AD.ProjTree .createTreeFromValue (Builder, BB->getParent ()->getLocation (),
211
- BB->getArgument (AD.Index ), LeafValues);
212
- NewArgs.append (LeafValues.begin (), LeafValues.end ());
213
- return ;
214
- }
215
-
216
- // All other arguments get pushed as what they are.
217
- NewArgs.push_back (BB->getArgument (AD.Index ));
218
- }
193
+ SILBasicBlock *BB,
194
+ llvm::SmallVectorImpl<SILValue> &NewArgs);
219
195
220
196
// / Take ArgumentDescList and ResultDescList and create an optimized function
221
197
// / based on the current function we are analyzing. This also has the side effect
@@ -241,105 +217,35 @@ class FunctionSignatureTransform {
241
217
}
242
218
243
219
// / Run the optimization.
244
- bool run (bool hasCaller) {
245
- bool Changed = false ;
246
- SILFunction *F = TransformDescriptor.OriginalFunction ;
247
-
248
- if (!hasCaller && canBeCalledIndirectly (F->getRepresentation ())) {
249
- DEBUG (llvm::dbgs () << " function has no caller -> abort\n " );
250
- return false ;
251
- }
252
-
253
- // Run OwnedToGuaranteed optimization.
254
- if (OwnedToGuaranteedAnalyze ()) {
255
- Changed = true ;
256
- DEBUG (llvm::dbgs () << " transform owned-to-guaranteed\n " );
257
- OwnedToGuaranteedTransform ();
258
- }
259
-
260
- // Run DeadArgument elimination transformation. We only specialize
261
- // if this function has a caller inside the current module or we have
262
- // already created a thunk.
263
- if ((hasCaller || Changed) && DeadArgumentAnalyzeParameters ()) {
264
- Changed = true ;
265
- DEBUG (llvm::dbgs () << " remove dead arguments\n " );
266
- DeadArgumentTransformFunction ();
267
- }
268
-
269
- // Run ArgumentExplosion transformation. We only specialize
270
- // if this function has a caller inside the current module or we have
271
- // already created a thunk.
272
- //
273
- // NOTE: we run argument explosion last because we've already initialized
274
- // the ArgumentDescList to have unexploded number of arguments. Exploding
275
- // it without changing the argument count is not going to help with
276
- // owned-to-guaranteed transformation.
277
- //
278
- // In order to not miss any opportunity, we send the optimized function
279
- // to the passmanager to optimize any opportunities exposed by argument
280
- // explosion.
281
- if ((hasCaller || Changed) && ArgumentExplosionAnalyzeParameters ()) {
282
- Changed = true ;
283
- }
284
-
285
- // Check if generic signature of the function could be changed by
286
- // removed some unused generic arguments.
287
- if (F->getLoweredFunctionType ()->isPolymorphic () &&
288
- createOptimizedSILFunctionType () != F->getLoweredFunctionType ()) {
289
- Changed = true ;
290
- }
291
-
292
- // Create the specialized function and invalidate the old function.
293
- if (Changed) {
294
- createFunctionSignatureOptimizedFunction ();
295
- }
296
- return Changed;
297
- }
220
+ bool run (bool hasCaller);
298
221
299
222
// / Run dead argument elimination of partially applied functions.
223
+ // /
300
224
// / After this optimization CapturePropagation can replace the partial_apply
301
225
// / by a direct reference to the specialized function.
302
- bool removeDeadArgs (int minPartialAppliedArgs) {
303
- if (minPartialAppliedArgs < 1 )
304
- return false ;
305
-
306
- if (!DeadArgumentAnalyzeParameters ())
307
- return false ;
308
-
309
- SILFunction *F = TransformDescriptor.OriginalFunction ;
310
- auto ArgumentDescList = TransformDescriptor.ArgumentDescList ;
311
-
312
- // Check if at least the minimum number of partially applied arguments
313
- // are dead. Otherwise no partial_apply can be removed anyway.
314
- unsigned Size = ArgumentDescList.size ();
315
- for (unsigned Idx : range (Size)) {
316
- if (Idx < Size - minPartialAppliedArgs) {
317
- // Don't remove arguments other than the partial applied ones, even if
318
- // they are dead.
319
- ArgumentDescList[Idx].IsEntirelyDead = false ;
320
- continue ;
321
- }
322
-
323
- // Is the partially applied argument dead?
324
- if (!ArgumentDescList[Idx].IsEntirelyDead )
325
- return false ;
226
+ bool removeDeadArgs (int minPartialAppliedArgs);
227
+ };
326
228
327
- // Currently we require that all dead parameters have trivial types. The
328
- // reason is that it's very hard to find places where we can release those
329
- // parameters (as a replacement for the removed partial_apply).
330
- //
331
- // TODO: Maybe we can skip this restriction when we have semantic ARC.
332
- if (ArgumentDescList[Idx].Arg ->getType ().isTrivial (F->getModule ()))
333
- continue ;
334
- return false ;
335
- }
229
+ void FunctionSignatureTransform::addThunkArgument (
230
+ ArgumentDescriptor &AD, SILBuilder &Builder, SILBasicBlock *BB,
231
+ llvm::SmallVectorImpl<SILValue> &NewArgs) {
232
+ // Dead argument.
233
+ if (AD.IsEntirelyDead ) {
234
+ return ;
235
+ }
336
236
337
- DEBUG (llvm::dbgs () << " remove dead arguments for partial_apply\n " );
338
- DeadArgumentTransformFunction ();
339
- createFunctionSignatureOptimizedFunction ();
340
- return true ;
237
+ // Explode the argument.
238
+ if (AD.Explode ) {
239
+ llvm::SmallVector<SILValue, 4 > LeafValues;
240
+ AD.ProjTree .createTreeFromValue (Builder, BB->getParent ()->getLocation (),
241
+ BB->getArgument (AD.Index ), LeafValues);
242
+ NewArgs.append (LeafValues.begin (), LeafValues.end ());
243
+ return ;
341
244
}
342
- };
245
+
246
+ // All other arguments get pushed as what they are.
247
+ NewArgs.push_back (BB->getArgument (AD.Index ));
248
+ }
343
249
344
250
std::string FunctionSignatureTransform::createOptimizedSILFunctionName () {
345
251
SILFunction *F = TransformDescriptor.OriginalFunction ;
@@ -790,6 +696,107 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
790
696
assert (F->getDebugScope ()->Parent != NewF->getDebugScope ()->Parent );
791
697
}
792
698
699
+ // Run the optimization.
700
+ bool FunctionSignatureTransform::run (bool hasCaller) {
701
+ bool Changed = false ;
702
+ SILFunction *F = TransformDescriptor.OriginalFunction ;
703
+
704
+ if (!hasCaller && canBeCalledIndirectly (F->getRepresentation ())) {
705
+ DEBUG (llvm::dbgs () << " function has no caller -> abort\n " );
706
+ return false ;
707
+ }
708
+
709
+ // Run OwnedToGuaranteed optimization.
710
+ if (OwnedToGuaranteedAnalyze ()) {
711
+ Changed = true ;
712
+ DEBUG (llvm::dbgs () << " transform owned-to-guaranteed\n " );
713
+ OwnedToGuaranteedTransform ();
714
+ }
715
+
716
+ // Run DeadArgument elimination transformation. We only specialize
717
+ // if this function has a caller inside the current module or we have
718
+ // already created a thunk.
719
+ if ((hasCaller || Changed) && DeadArgumentAnalyzeParameters ()) {
720
+ Changed = true ;
721
+ DEBUG (llvm::dbgs () << " remove dead arguments\n " );
722
+ DeadArgumentTransformFunction ();
723
+ }
724
+
725
+ // Run ArgumentExplosion transformation. We only specialize
726
+ // if this function has a caller inside the current module or we have
727
+ // already created a thunk.
728
+ //
729
+ // NOTE: we run argument explosion last because we've already initialized
730
+ // the ArgumentDescList to have unexploded number of arguments. Exploding
731
+ // it without changing the argument count is not going to help with
732
+ // owned-to-guaranteed transformation.
733
+ //
734
+ // In order to not miss any opportunity, we send the optimized function
735
+ // to the passmanager to optimize any opportunities exposed by argument
736
+ // explosion.
737
+ if ((hasCaller || Changed) && ArgumentExplosionAnalyzeParameters ()) {
738
+ Changed = true ;
739
+ }
740
+
741
+ // Check if generic signature of the function could be changed by
742
+ // removed some unused generic arguments.
743
+ if (F->getLoweredFunctionType ()->isPolymorphic () &&
744
+ createOptimizedSILFunctionType () != F->getLoweredFunctionType ()) {
745
+ Changed = true ;
746
+ }
747
+
748
+ // Create the specialized function and invalidate the old function.
749
+ if (Changed) {
750
+ createFunctionSignatureOptimizedFunction ();
751
+ }
752
+ return Changed;
753
+ }
754
+
755
+ // Run dead argument elimination of partially applied functions.
756
+ //
757
+ // After this optimization CapturePropagation can replace the partial_apply by a
758
+ // direct reference to the specialized function.
759
+ bool FunctionSignatureTransform::removeDeadArgs (int minPartialAppliedArgs) {
760
+ if (minPartialAppliedArgs < 1 )
761
+ return false ;
762
+
763
+ if (!DeadArgumentAnalyzeParameters ())
764
+ return false ;
765
+
766
+ SILFunction *F = TransformDescriptor.OriginalFunction ;
767
+ auto ArgumentDescList = TransformDescriptor.ArgumentDescList ;
768
+
769
+ // Check if at least the minimum number of partially applied arguments
770
+ // are dead. Otherwise no partial_apply can be removed anyway.
771
+ unsigned Size = ArgumentDescList.size ();
772
+ for (unsigned Idx : range (Size)) {
773
+ if (Idx < Size - minPartialAppliedArgs) {
774
+ // Don't remove arguments other than the partial applied ones, even if
775
+ // they are dead.
776
+ ArgumentDescList[Idx].IsEntirelyDead = false ;
777
+ continue ;
778
+ }
779
+
780
+ // Is the partially applied argument dead?
781
+ if (!ArgumentDescList[Idx].IsEntirelyDead )
782
+ return false ;
783
+
784
+ // Currently we require that all dead parameters have trivial types. The
785
+ // reason is that it's very hard to find places where we can release those
786
+ // parameters (as a replacement for the removed partial_apply).
787
+ //
788
+ // TODO: Maybe we can skip this restriction when we have semantic ARC.
789
+ if (ArgumentDescList[Idx].Arg ->getType ().isTrivial (F->getModule ()))
790
+ continue ;
791
+ return false ;
792
+ }
793
+
794
+ DEBUG (llvm::dbgs () << " remove dead arguments for partial_apply\n " );
795
+ DeadArgumentTransformFunction ();
796
+ createFunctionSignatureOptimizedFunction ();
797
+ return true ;
798
+ }
799
+
793
800
// ===----------------------------------------------------------------------===//
794
801
// Dead Argument Elimination
795
802
// ===----------------------------------------------------------------------===//
@@ -1076,6 +1083,17 @@ OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD, SILBuilder &Builder,
1076
1083
}
1077
1084
}
1078
1085
1086
+ bool FunctionSignatureTransform::OwnedToGuaranteedAnalyze () {
1087
+ bool Result = OwnedToGuaranteedAnalyzeResults ();
1088
+ bool Params = OwnedToGuaranteedAnalyzeParameters ();
1089
+ return Params || Result;
1090
+ }
1091
+
1092
+ void FunctionSignatureTransform::OwnedToGuaranteedTransform () {
1093
+ OwnedToGuaranteedTransformFunctionResults ();
1094
+ OwnedToGuaranteedTransformFunctionParameters ();
1095
+ }
1096
+
1079
1097
// ===----------------------------------------------------------------------===//
1080
1098
// Argument Explosion Transformation
1081
1099
// ===----------------------------------------------------------------------===//
0 commit comments