@@ -395,195 +395,4 @@ SILInstruction *findReleaseToMatchUnsafeGuaranteedValue(
395
395
396
396
} // end namespace swift
397
397
398
-
399
- namespace swift {
400
-
401
- // / EpilogueARCBlockState - Keep track of whether an epilogue ARC instruction
402
- // / has been found.
403
- struct EpilogueARCBlockState {
404
- // / Keep track of whether an epilogue release has been found before and after
405
- // / this basic block.
406
- bool BBSetIn;
407
- // / The basic block local SILValue we are interested to find epilogue ARC in.
408
- SILValue LocalArg;
409
- // / Constructor, we only compute epilogue ARC instruction for 1 argument at
410
- // / a time.
411
- // / Optimistic data flow.
412
- EpilogueARCBlockState () { BBSetIn = true ; LocalArg = SILValue (); }
413
- };
414
-
415
- // / EpilogueARCContext - This class implements a data flow with which epilogue
416
- // / retains or releases for a SILValue are found.
417
- // /
418
- // / NOTE:
419
- // / In case of release finder, this function assumes the SILArgument has
420
- // / @owned semantic.
421
- // / In case of retain finder, this class assumes Arg is one of the return value
422
- // / of the function.
423
- class EpilogueARCContext {
424
- public:
425
- enum EpilogueARCKind { Retain = 0 , Release = 1 };
426
-
427
- private:
428
- // Are we finding retains or releases.
429
- EpilogueARCKind Kind;
430
-
431
- // The argument we are looking for epilogue ARC instruction for.
432
- SILValue Arg;
433
-
434
- // / The allocator we are currently using.
435
- llvm::SpecificBumpPtrAllocator<EpilogueARCBlockState> BPA;
436
-
437
- // / Current function we are analyzing.
438
- SILFunction *F;
439
-
440
- // / Current post-order we are using.
441
- PostOrderFunctionInfo *PO;
442
-
443
- // / Current alias analysis we are using.
444
- AliasAnalysis *AA;
445
-
446
- // / Current rc-identity we are using.
447
- RCIdentityFunctionInfo *RCFI;
448
-
449
- // / The epilogue retains or releases.
450
- llvm::SmallSetVector<SILInstruction *, 1 > EpilogueARCInsts;
451
-
452
- // / All the retain/release block state for all the basic blocks in the function.
453
- llvm::DenseMap<SILBasicBlock *, EpilogueARCBlockState *> EpilogueARCBlockStates;
454
-
455
- // / The exit blocks of the function.
456
- llvm::SmallPtrSet<SILBasicBlock *, 2 > ExitBlocks;
457
-
458
- // / Return true if this is a function exitting block this epilogue ARC
459
- // / matcher is interested in.
460
- bool isInterestedFunctionExitingBlock (SILBasicBlock *BB) {
461
- if (EpilogueARCKind::Release == Kind)
462
- return BB->getTerminator ()->isFunctionExiting ();
463
-
464
- return BB->getTerminator ()->isFunctionExiting () &&
465
- BB->getTerminator ()->getTermKind () != TermKind::ThrowInst;
466
- }
467
-
468
- // / Return true if this is a function exit block.
469
- bool isExitBlock (SILBasicBlock *BB) {
470
- return ExitBlocks.count (BB);
471
- }
472
-
473
- // / Return true if this is a retain instruction.
474
- bool isRetainInstruction (SILInstruction *II) {
475
- return isa<RetainValueInst>(II) || isa<StrongRetainInst>(II);
476
- }
477
-
478
- // / Return true if this is a release instruction.
479
- bool isReleaseInstruction (SILInstruction *II) {
480
- return isa<ReleaseValueInst>(II) || isa<StrongReleaseInst>(II);
481
- }
482
-
483
- SILValue getArg (SILBasicBlock *B) {
484
- SILValue A = EpilogueARCBlockStates[B]->LocalArg ;
485
- if (A)
486
- return A;
487
- return Arg;
488
- }
489
-
490
- public:
491
- // / Constructor.
492
- EpilogueARCContext (EpilogueARCKind Kind, SILValue Arg, SILFunction *F,
493
- PostOrderFunctionInfo *PO, AliasAnalysis *AA,
494
- RCIdentityFunctionInfo *RCFI)
495
- : Kind(Kind), Arg(Arg), F(F), PO(PO), AA(AA), RCFI(RCFI) {}
496
-
497
- // / Run the data flow to find the epilogue retains or releases.
498
- bool run () {
499
- // Initialize the epilogue arc data flow context.
500
- initializeDataflow ();
501
- // Converge the data flow.
502
- if (!convergeDataflow ())
503
- return false ;
504
- // Lastly, find the epilogue ARC instructions.
505
- return computeEpilogueARC ();
506
- }
507
-
508
- // / Reset the epilogue arc instructions.
509
- void resetEpilogueARCInsts () { EpilogueARCInsts.clear (); }
510
- llvm::SmallSetVector<SILInstruction *, 1 > getEpilogueARCInsts () {
511
- return EpilogueARCInsts;
512
- }
513
-
514
- // / Initialize the data flow.
515
- void initializeDataflow ();
516
-
517
- // / Keep iterating until the data flow is converged.
518
- bool convergeDataflow ();
519
-
520
- // / Find the epilogue ARC instructions.
521
- bool computeEpilogueARC ();
522
-
523
- // / This instruction prevents looking further for epilogue retains on the
524
- // / current path.
525
- bool mayBlockEpilogueRetain (SILInstruction *II, SILValue Ptr) {
526
- // reference decrementing instruction prevents any retain to be identified as
527
- // epilogue retains.
528
- if (mayDecrementRefCount (II, Ptr, AA))
529
- return true ;
530
- // Handle self-recursion. A self-recursion can be considered a +1 on the
531
- // current argument.
532
- if (ApplyInst *AI = dyn_cast<ApplyInst>(II))
533
- if (AI->getCalleeFunction () == II->getParent ()->getParent ())
534
- return true ;
535
- return false ;
536
- }
537
-
538
- // / This instruction prevents looking further for epilogue releases on the
539
- // / current path.
540
- bool mayBlockEpilogueRelease (SILInstruction *II, SILValue Ptr) {
541
- // Check whether this instruction read reference count, i.e. uniqueness
542
- // check. Moving release past that may result in additional COW.
543
- if (II->mayReleaseOrReadRefCount ())
544
- return true ;
545
- return false ;
546
- }
547
-
548
- // / Does this instruction block the interested ARC instruction ?
549
- bool mayBlockEpilogueARC (SILInstruction *II, SILValue Ptr) {
550
- if (Kind == EpilogueARCKind::Retain)
551
- return mayBlockEpilogueRetain (II, Ptr);
552
- return mayBlockEpilogueRelease (II, Ptr);
553
- }
554
-
555
- // / This is the type of instructions the data flow is interested in.
556
- bool isInterestedInstruction (SILInstruction *II) {
557
- // We are checking for release.
558
- if (Kind == EpilogueARCKind::Release)
559
- return isReleaseInstruction (II) &&
560
- RCFI->getRCIdentityRoot (II->getOperand (0 )) ==
561
- RCFI->getRCIdentityRoot (getArg (II->getParent ()));
562
- // We are checking for retain. If this is a self-recursion. call
563
- // to the function (which returns an owned value) can be treated as
564
- // the retain instruction.
565
- if (ApplyInst *AI = dyn_cast<ApplyInst>(II))
566
- if (AI->getCalleeFunction () == II->getParent ()->getParent ())
567
- return true ;
568
- // Check whether this is a retain instruction and the argument it
569
- // retains.
570
- return isRetainInstruction (II) &&
571
- RCFI->getRCIdentityRoot (II->getOperand (0 )) ==
572
- RCFI->getRCIdentityRoot (getArg (II->getParent ()));
573
- }
574
- };
575
-
576
- // / Compute the epilogue ARC instructions for a given SILValue. Return an
577
- // / empty set if no epilogue ARC instructions can be found.
578
- // /
579
- // / NOTE: This function assumes Arg is has @owned semantic.
580
- llvm::SmallSetVector<SILInstruction *, 1 >
581
- computeEpilogueARCInstructions (EpilogueARCContext::EpilogueARCKind Kind,
582
- SILValue Arg, SILFunction *F,
583
- PostOrderFunctionInfo *PO, AliasAnalysis *AA,
584
- RCIdentityFunctionInfo *RCFI);
585
-
586
- } // end namespace swift
587
-
588
-
589
398
#endif
0 commit comments