11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#define DEBUG_TYPE " capture-prop"
14
- #include " swift/AST/GenericEnvironment.h"
15
14
#include " swift/SILOptimizer/PassManager/Passes.h"
16
- #include " swift/SILOptimizer/Utils/Generics.h"
17
15
#include " swift/SILOptimizer/Utils/SpecializationMangler.h"
18
16
#include " swift/Demangling/Demangle.h"
19
17
#include " swift/SIL/Mangle.h"
20
18
#include " swift/SIL/SILCloner.h"
21
19
#include " swift/SIL/SILInstruction.h"
22
- #include " swift/SIL/TypeSubstCloner.h"
23
20
#include " swift/SILOptimizer/Analysis/ColdBlockInfo.h"
24
21
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
25
22
#include " swift/SILOptimizer/PassManager/Transforms.h"
@@ -102,17 +99,16 @@ namespace {
102
99
// / caller, so the cloned function will have a mix of locations from different
103
100
// / functions.
104
101
class CapturePropagationCloner
105
- : public TypeSubstCloner <CapturePropagationCloner> {
106
- using SuperTy = TypeSubstCloner <CapturePropagationCloner>;
102
+ : public SILClonerWithScopes <CapturePropagationCloner> {
103
+ using SuperTy = SILClonerWithScopes <CapturePropagationCloner>;
107
104
friend class SILVisitor <CapturePropagationCloner>;
108
105
friend class SILCloner <CapturePropagationCloner>;
109
106
110
107
SILFunction *OrigF;
111
108
bool IsCloningConstant;
112
109
public:
113
- CapturePropagationCloner (SILFunction *OrigF, SILFunction *NewF,
114
- SubstitutionList Subs)
115
- : SuperTy(*NewF, *OrigF, Subs), OrigF(OrigF), IsCloningConstant(false ) {}
110
+ CapturePropagationCloner (SILFunction *OrigF, SILFunction *NewF)
111
+ : SuperTy(*NewF), OrigF(OrigF), IsCloningConstant(false ) {}
116
112
117
113
void cloneBlocks (OperandValueArrayRef Args);
118
114
@@ -223,20 +219,6 @@ void CapturePropagationCloner::cloneBlocks(
223
219
}
224
220
}
225
221
226
- CanSILFunctionType getPartialApplyInterfaceResultType (PartialApplyInst *PAI) {
227
- SILFunction *OrigF = PAI->getReferencedFunction ();
228
- // The new partial_apply will no longer take any arguments--they are all
229
- // expressed as literals. So its callee signature will be the same as its
230
- // return signature.
231
- auto FTy = PAI->getType ().castTo <SILFunctionType>();
232
- CanGenericSignature CanGenericSig;
233
- assert (!PAI->hasSubstitutions () || !hasArchetypes (PAI->getSubstitutions ()));
234
- FTy = cast<SILFunctionType>(
235
- OrigF->mapTypeOutOfContext (FTy)->getCanonicalType ());
236
- auto NewFTy = FTy;
237
- return NewFTy;
238
- }
239
-
240
222
// / Given a partial_apply instruction, create a specialized callee by removing
241
223
// / all constant arguments and adding constant literals to the specialized
242
224
// / function body.
@@ -261,16 +243,12 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI,
261
243
// The new partial_apply will no longer take any arguments--they are all
262
244
// expressed as literals. So its callee signature will be the same as its
263
245
// return signature.
264
- auto NewFTy = getPartialApplyInterfaceResultType (PAI);
265
- NewFTy = Lowering::adjustFunctionType (NewFTy,
266
- SILFunctionType::Representation::Thin);
267
-
268
- GenericEnvironment *GenericEnv = nullptr ;
269
- if (NewFTy->getGenericSignature ())
270
- GenericEnv = OrigF->getGenericEnvironment ();
246
+ CanSILFunctionType NewFTy =
247
+ Lowering::adjustFunctionType (PAI->getType ().castTo <SILFunctionType>(),
248
+ SILFunctionType::Representation::Thin);
271
249
SILFunction *NewF = OrigF->getModule ().createFunction (
272
250
SILLinkage::Shared, Name, NewFTy,
273
- GenericEnv , OrigF->getLocation (), OrigF->isBare (),
251
+ OrigF-> getGenericEnvironment () , OrigF->getLocation (), OrigF->isBare (),
274
252
OrigF->isTransparent (), Fragile, OrigF->isThunk (),
275
253
OrigF->getClassVisibility (), OrigF->getInlineStrategy (),
276
254
OrigF->getEffectsKind (),
@@ -281,28 +259,18 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI,
281
259
DEBUG (llvm::dbgs () << " Specialize callee as " ;
282
260
NewF->printName (llvm::dbgs ()); llvm::dbgs () << " " << NewFTy << " \n " );
283
261
284
- DEBUG (if (PAI->hasSubstitutions ()) {
285
- llvm::dbgs () << " CapturePropagation of generic partial_apply:\n " ;
286
- PAI->dumpInContext ();
287
- });
288
- CapturePropagationCloner cloner (OrigF, NewF, PAI->getSubstitutions ());
262
+ CapturePropagationCloner cloner (OrigF, NewF);
289
263
cloner.cloneBlocks (PAI->getArguments ());
290
264
assert (OrigF->getDebugScope ()->Parent != NewF->getDebugScope ()->Parent );
291
265
return NewF;
292
266
}
293
267
294
268
void CapturePropagation::rewritePartialApply (PartialApplyInst *OrigPAI,
295
269
SILFunction *SpecialF) {
296
- DEBUG (llvm::dbgs () << " \n Rewriting a partial apply:\n " ;
297
- OrigPAI->dumpInContext (); llvm::dbgs () << " with special function: "
298
- << SpecialF->getName () << " \n " ;
299
- llvm::dbgs () << " \n The function being rewritten is:\n " ;
300
- OrigPAI->getFunction ()->dump ());
301
-
302
270
SILBuilderWithScope Builder (OrigPAI);
303
271
auto FuncRef = Builder.createFunctionRef (OrigPAI->getLoc (), SpecialF);
304
- auto *T2TF = Builder.createThinToThickFunction (OrigPAI->getLoc (), FuncRef,
305
- OrigPAI->getType ());
272
+ auto *T2TF = Builder.createThinToThickFunction (OrigPAI->getLoc (),
273
+ FuncRef, OrigPAI->getType ());
306
274
OrigPAI->replaceAllUsesWith (T2TF);
307
275
recursivelyDeleteTriviallyDeadInstructions (OrigPAI, true );
308
276
DEBUG (llvm::dbgs () << " Rewrote caller:\n " << *T2TF);
@@ -343,13 +311,12 @@ static bool onlyContainsReturnOrThrowOfArg(SILBasicBlock *BB) {
343
311
344
312
// / Checks if \p Orig is a thunk which calls another function but without
345
313
// / passing the trailing \p numDeadParams dead parameters.
346
- static SILFunction *getSpecializedWithDeadParams (
347
- PartialApplyInst *PAI, SILFunction *Orig, int numDeadParams,
348
- std::pair<SILFunction *, SILFunction *> &GenericSpecialized) {
314
+ static SILFunction *getSpecializedWithDeadParams (SILFunction *Orig,
315
+ int numDeadParams) {
349
316
SILBasicBlock &EntryBB = *Orig->begin ();
350
317
unsigned NumArgs = EntryBB.getNumArguments ();
351
318
SILModule &M = Orig->getModule ();
352
-
319
+
353
320
// Check if all dead parameters have trivial types. We don't support non-
354
321
// trivial types because it's very hard to find places where we can release
355
322
// those parameters (as a replacement for the removed partial_apply).
@@ -361,20 +328,20 @@ static SILFunction *getSpecializedWithDeadParams(
361
328
}
362
329
SILFunction *Specialized = nullptr ;
363
330
SILValue RetValue;
364
-
331
+
365
332
// Check all instruction of the entry block.
366
333
for (SILInstruction &I : EntryBB) {
367
334
if (auto FAS = FullApplySite::isa (&I)) {
335
+
368
336
// Check if this is the call of the specialized function.
369
- // If the original partial_apply didn't have substitutions,
370
- // also the specialized function must be not generic.
371
- if (!PAI-> hasSubstitutions () && FAS.hasSubstitutions ())
337
+ // As the original function is not generic, also the specialized function
338
+ // must be not generic.
339
+ if (FAS.hasSubstitutions ())
372
340
return nullptr ;
373
-
374
341
// Is it the only call?
375
342
if (Specialized)
376
343
return nullptr ;
377
-
344
+
378
345
Specialized = FAS.getReferencedFunction ();
379
346
if (!Specialized)
380
347
return nullptr ;
@@ -409,55 +376,29 @@ static SILFunction *getSpecializedWithDeadParams(
409
376
if (I.mayHaveSideEffects () || isa<TermInst>(&I))
410
377
return nullptr ;
411
378
}
412
-
413
- GenericSpecialized = std::make_pair (nullptr , nullptr );
414
-
415
- if (PAI->hasSubstitutions ()) {
416
- if (Specialized->isExternalDeclaration ())
417
- return nullptr ;
418
- // Perform a generic specialization of the Specialized function.
419
- ReabstractionInfo ReInfo (ApplySite (), Specialized, PAI->getSubstitutions (),
420
- /* ConvertIndirectToDirect */ false );
421
- GenericFuncSpecializer FuncSpecializer (Specialized,
422
- ReInfo.getClonerParamSubstitutions (),
423
- Specialized->isFragile (), ReInfo);
424
-
425
- SILFunction *GenericSpecializedFunc = FuncSpecializer.trySpecialization ();
426
- if (!GenericSpecializedFunc)
427
- return nullptr ;
428
- GenericSpecialized = std::make_pair (GenericSpecializedFunc, Specialized);
429
- return GenericSpecializedFunc;
430
- }
431
379
return Specialized;
432
380
}
433
381
434
382
bool CapturePropagation::optimizePartialApply (PartialApplyInst *PAI) {
383
+ // Check if the partial_apply has generic substitutions.
384
+ // FIXME: We could handle generic thunks if it's worthwhile.
385
+ if (PAI->hasSubstitutions ())
386
+ return false ;
387
+
435
388
SILFunction *SubstF = PAI->getReferencedFunction ();
436
389
if (!SubstF)
437
390
return false ;
438
391
if (SubstF->isExternalDeclaration ())
439
392
return false ;
440
393
441
- if (PAI->hasSubstitutions () && hasArchetypes (PAI->getSubstitutions ())) {
442
- DEBUG (llvm::dbgs ()
443
- << " CapturePropagation: cannot handle partial specialization "
444
- " of partial_apply:\n " ;
445
- PAI->dumpInContext ());
446
- return false ;
447
- }
448
-
394
+ assert (!SubstF->getLoweredFunctionType ()->isPolymorphic () &&
395
+ " cannot specialize generic partial apply" );
449
396
450
397
// First possibility: Is it a partial_apply where all partially applied
451
398
// arguments are dead?
452
- std::pair<SILFunction *, SILFunction *> GenericSpecialized;
453
- if (auto *NewFunc = getSpecializedWithDeadParams (
454
- PAI, SubstF, PAI->getNumArguments (), GenericSpecialized)) {
399
+ if (SILFunction *NewFunc = getSpecializedWithDeadParams (SubstF,
400
+ PAI->getNumArguments ())) {
455
401
rewritePartialApply (PAI, NewFunc);
456
- if (GenericSpecialized.first ) {
457
- // Notify the pass manager about the new function.
458
- notifyPassManagerOfFunction (GenericSpecialized.first ,
459
- GenericSpecialized.second );
460
- }
461
402
return true ;
462
403
}
463
404
@@ -470,8 +411,7 @@ bool CapturePropagation::optimizePartialApply(PartialApplyInst *PAI) {
470
411
return false ;
471
412
472
413
DEBUG (llvm::dbgs () << " Specializing closure for constant arguments:\n "
473
- << " " << SubstF->getName () << " \n "
474
- << *PAI);
414
+ << " " << SubstF->getName () << " \n " << *PAI);
475
415
++NumCapturesPropagated;
476
416
SILFunction *NewF = specializeConstClosure (PAI, SubstF);
477
417
rewritePartialApply (PAI, NewF);
0 commit comments