@@ -346,27 +346,27 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
346
346
// If we have guaranteed normal arguments, insert the destroy.
347
347
//
348
348
// TODO: Is it safe to just eliminate the initial retain?
349
- Builder.emitDestroyValueOperation (Loc, srcArg);
349
+ Builder.emitDestroyOperation (Loc, srcArg);
350
350
351
351
// If we have an unconditional_checked_cast_addr, return early. We do not need
352
352
// to handle any conditional code.
353
353
if (isa<UnconditionalCheckedCastAddrInst>(Inst)) {
354
354
// Destroy the source value as unconditional_checked_cast_addr would.
355
- Builder.emitDestroyValueOperation (Loc, srcOp);
355
+ Builder.emitDestroyOperation (Loc, srcOp);
356
356
eraseInstAction (Inst);
357
357
return (newI) ? newI : AI;
358
358
}
359
359
360
360
auto *CCABI = cast<CheckedCastAddrBranchInst>(Inst);
361
361
switch (CCABI->getConsumptionKind ()) {
362
362
case CastConsumptionKind::TakeAlways:
363
- Builder.emitDestroyValueOperation (Loc, srcOp);
363
+ Builder.emitDestroyOperation (Loc, srcOp);
364
364
break ;
365
365
case CastConsumptionKind::TakeOnSuccess: {
366
366
{
367
367
// Insert a release in the success BB.
368
368
SILBuilderWithScope successBuilder (SuccessBB->begin ());
369
- successBuilder.emitDestroyValueOperation (Loc, srcOp);
369
+ successBuilder.emitDestroyOperation (Loc, srcOp);
370
370
}
371
371
{
372
372
// And a store in the failure BB.
@@ -590,7 +590,7 @@ static SILValue computeFinalCastedValue(SILBuilderWithScope &builder,
590
590
return failureBB->createPhiArgument (newAI->getType (),
591
591
ValueOwnershipKind::Owned);
592
592
}());
593
- innerBuilder.emitDestroyValueOperation (loc, valueToDestroy);
593
+ innerBuilder.emitDestroyOperation (loc, valueToDestroy);
594
594
}
595
595
596
596
auto *condBrSuccessBB =
@@ -651,23 +651,25 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
651
651
SILType SubstFnTy = bridgedFunc->getLoweredType ().substGenericArgs (M, subMap);
652
652
SILFunctionConventions substConv (SubstFnTy.castTo <SILFunctionType>(), M);
653
653
654
- // check that we can go through with the optimization
654
+ // Check that this is a case that the authors of this code thought it could
655
+ // handle.
655
656
if (!canOptimizeCast (BridgedTargetTy, M, substConv)) {
656
657
return nullptr ;
657
658
}
658
659
659
660
SILBuilderWithScope Builder (Inst, builderContext);
660
661
auto FnRef = Builder.createFunctionRefFor (Loc, bridgedFunc);
661
662
auto ParamTypes = SubstFnTy.castTo <SILFunctionType>()->getParameters ();
663
+ SILValue oldSrc;
662
664
if (Src->getType ().isAddress () && !substConv.isSILIndirect (ParamTypes[0 ])) {
663
665
// Create load
666
+ oldSrc = Src;
664
667
Src =
665
668
Builder.emitLoadValueOperation (Loc, Src, LoadOwnershipQualifier::Take);
666
669
}
667
670
668
671
// Compensate different owning conventions of the replaced cast instruction
669
672
// and the inserted conversion function.
670
- bool needRetainBeforeCall = false ;
671
673
bool needReleaseAfterCall = false ;
672
674
bool needReleaseInSuccess = false ;
673
675
switch (ParamTypes[0 ].getConvention ()) {
@@ -681,21 +683,10 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
681
683
needReleaseInSuccess = true ;
682
684
break ;
683
685
case CastConsumptionKind::BorrowAlways:
686
+ llvm_unreachable (" Should never hit this" );
684
687
case CastConsumptionKind::CopyOnSuccess:
685
- // Conservatively insert a retain/release pair around the conversion
686
- // function because the conversion function could decrement the
687
- // (global) reference count of the source object.
688
- //
689
- // %src = load %global_var
690
- // apply %conversion_func(@guaranteed %src)
691
- //
692
- // sil conversion_func {
693
- // %old_value = load %global_var
694
- // store %something_else, %global_var
695
- // strong_release %old_value
696
- // }
697
- needRetainBeforeCall = true ;
698
- needReleaseAfterCall = true ;
688
+ // We assume that our caller is correct and will treat our argument as
689
+ // being immutable, so we do not need to do anything here.
699
690
break ;
700
691
}
701
692
break ;
@@ -733,53 +724,35 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
733
724
return nullptr ;
734
725
}
735
726
736
- bool needStackAllocatedTemporary = false ;
737
- if (needRetainBeforeCall) {
738
- if (AddressOnlyType) {
739
- needStackAllocatedTemporary = true ;
740
- auto NewSrc = Builder.createAllocStack (Loc, Src->getType ());
741
- Builder.createCopyAddr (Loc, Src, NewSrc, IsNotTake, IsInitialization);
742
- Src = NewSrc;
743
- } else {
744
- Builder.createRetainValue (Loc, Src, Builder.getDefaultAtomicity ());
745
- }
746
- }
747
-
748
727
// Generate a code to invoke the bridging function.
749
728
auto *NewAI = Builder.createApply (Loc, FnRef, subMap, Src);
750
729
751
- auto releaseSrc = [&](SILBuilder &Builder) {
752
- if (AddressOnlyType) {
753
- Builder.createDestroyAddr (Loc, Src);
754
- } else {
755
- Builder.emitDestroyValueOperation (Loc, Src);
756
- }
757
- };
758
-
759
- Optional<SILBuilder> SuccBuilder;
760
- if (needReleaseInSuccess || needStackAllocatedTemporary)
761
- SuccBuilder.emplace (SuccessBB->begin ());
762
-
730
+ // First if we are going to destroy the value unconditionally, just insert the
731
+ // destroy right after the call. This handles some of the conditional cases
732
+ // and /all/ of the consuming unconditional cases.
763
733
if (needReleaseAfterCall) {
764
- releaseSrc (Builder);
765
- } else if (needReleaseInSuccess) {
766
- if (SuccessBB) {
767
- releaseSrc (*SuccBuilder);
768
- } else {
769
- // For an unconditional cast, success is the only defined path
770
- releaseSrc (Builder);
771
- }
772
- }
773
-
774
- // Pop the temporary stack slot for a copied temporary.
775
- if (needStackAllocatedTemporary) {
776
- assert ((bool )SuccessBB == (bool )FailureBB);
734
+ Builder.emitDestroyOperation (Loc, Src);
735
+ } else {
777
736
if (SuccessBB) {
778
- SuccBuilder->createDeallocStack (Loc, Src);
779
- SILBuilderWithScope FailBuilder (&*FailureBB->begin (), Builder);
780
- FailBuilder.createDeallocStack (Loc, Src);
737
+ SILBuilderWithScope succBuilder (&*SuccessBB->begin (), Builder);
738
+ if (needReleaseInSuccess) {
739
+ succBuilder.emitDestroyOperation (Loc, Src);
740
+ } else {
741
+ if (oldSrc) {
742
+ succBuilder.emitStoreValueOperation (Loc, Src, oldSrc,
743
+ StoreOwnershipQualifier::Init);
744
+ }
745
+ }
746
+ SILBuilderWithScope failBuilder (&*FailureBB->begin (), Builder);
747
+ if (oldSrc) {
748
+ failBuilder.emitStoreValueOperation (Loc, Src, oldSrc,
749
+ StoreOwnershipQualifier::Init);
750
+ }
781
751
} else {
782
- Builder.createDeallocStack (Loc, Src);
752
+ if (oldSrc) {
753
+ Builder.emitStoreValueOperation (Loc, Src, oldSrc,
754
+ StoreOwnershipQualifier::Init);
755
+ }
783
756
}
784
757
}
785
758
0 commit comments