657 assert(!
EHStack.empty() &&
"cleanup stack is empty!");
660 assert(
Scope.getFixupDepth() <=
EHStack.getNumBranchFixups());
664 CGBuilderTy::InsertPoint NormalDeactivateOrigIP;
666 NormalDeactivateOrigIP =
Builder.saveAndClearIP();
669 bool IsActive =
Scope.isActive();
671 Scope.shouldTestFlagInNormalCleanup() ?
Scope.getActiveFlag()
674 Scope.shouldTestFlagInEHCleanup() ?
Scope.getActiveFlag()
679 llvm::BasicBlock *EHEntry =
Scope.getCachedEHDispatchBlock();
680 assert(
Scope.hasEHBranches() == (EHEntry !=
nullptr));
681 bool RequiresEHCleanup = (EHEntry !=
nullptr);
687 unsigned FixupDepth =
Scope.getFixupDepth();
688 bool HasFixups =
EHStack.getNumBranchFixups() != FixupDepth;
691 bool HasExistingBranches =
Scope.hasBranches();
694 llvm::BasicBlock *FallthroughSource =
Builder.GetInsertBlock();
695 bool HasFallthrough =
696 FallthroughSource !=
nullptr && (IsActive || HasExistingBranches);
702 bool HasPrebranchedFallthrough =
703 (FallthroughSource && FallthroughSource->hasTerminator());
708 assert(!
Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||
709 (
Scope.getNormalBlock() &&
710 FallthroughSource->getTerminator()->getSuccessor(0)
711 ==
Scope.getNormalBlock()));
713 bool RequiresNormalCleanup =
false;
714 if (
Scope.isNormalCleanup() &&
715 (HasFixups || HasExistingBranches || HasFallthrough)) {
716 RequiresNormalCleanup =
true;
721 if (
Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
722 !RequiresNormalCleanup) {
726 llvm::BasicBlock *prebranchDest;
731 if (FallthroughIsBranchThrough) {
744 llvm::BasicBlock *normalEntry =
Scope.getNormalBlock();
745 assert(normalEntry && !normalEntry->use_empty());
748 normalEntry, prebranchDest);
752 if (!RequiresNormalCleanup && !RequiresEHCleanup) {
755 assert(
EHStack.getNumBranchFixups() == 0 ||
757 if (NormalDeactivateOrigIP.isSet())
758 Builder.restoreIP(NormalDeactivateOrigIP);
767 auto *CleanupSource =
reinterpret_cast<char *
>(
Scope.getCleanupBuffer());
769 CleanupBufferStack[8 *
sizeof(
void *)];
770 std::unique_ptr<char[]> CleanupBufferHeap;
771 size_t CleanupSize =
Scope.getCleanupSize();
772 EHScopeStack::Cleanup *Fn;
774 if (CleanupSize <=
sizeof(CleanupBufferStack)) {
775 memcpy(CleanupBufferStack, CleanupSource, CleanupSize);
776 Fn =
reinterpret_cast<EHScopeStack::Cleanup *
>(CleanupBufferStack);
778 CleanupBufferHeap.reset(
new char[CleanupSize]);
779 memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize);
780 Fn =
reinterpret_cast<EHScopeStack::Cleanup *
>(CleanupBufferHeap.get());
783 EHScopeStack::Cleanup::Flags cleanupFlags;
784 if (
Scope.isNormalCleanup())
785 cleanupFlags.setIsNormalCleanupKind();
786 if (
Scope.isEHCleanup())
787 cleanupFlags.setIsEHCleanupKind();
791 bool IsSEHFinallyCleanup =
Scope.isSEHFinallyCleanup();
792 if (!RequiresNormalCleanup) {
799 if (NormalDeactivateOrigIP.isSet())
800 Builder.restoreIP(NormalDeactivateOrigIP);
801 if (
Builder.GetInsertBlock() && !IsSEHFinallyCleanup)
803 if (NormalDeactivateOrigIP.isSet())
804 NormalDeactivateOrigIP =
Builder.saveAndClearIP();
812 if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups &&
813 !HasExistingBranches) {
817 if (
Scope.isSEHFinallyCleanup())
827 EmitCleanup(*
this, Fn, cleanupFlags, NormalActiveFlag);
837 CGBuilderTy::InsertPoint savedInactiveFallthroughIP;
841 if (HasFallthrough) {
842 if (!HasPrebranchedFallthrough)
847 }
else if (FallthroughSource) {
848 assert(!IsActive &&
"source without fallthrough for active cleanup");
849 savedInactiveFallthroughIP =
Builder.saveAndClearIP();
859 if (
Scope.isSEHFinallyCleanup())
868 bool HasEnclosingCleanups =
869 (
Scope.getEnclosingNormalCleanup() !=
EHStack.stable_end());
876 llvm::BasicBlock *BranchThroughDest =
nullptr;
877 if (
Scope.hasBranchThroughs() ||
878 (FallthroughSource && FallthroughIsBranchThrough) ||
879 (HasFixups && HasEnclosingCleanups)) {
880 assert(HasEnclosingCleanups);
885 llvm::BasicBlock *FallthroughDest =
nullptr;
895 if (!
Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough &&
897 assert(!BranchThroughDest || !IsActive);
900 llvm::Instruction *NormalCleanupDestSlot =
902 if (NormalCleanupDestSlot->hasOneUse()) {
903 NormalCleanupDestSlot->user_back()->eraseFromParent();
904 NormalCleanupDestSlot->eraseFromParent();
908 llvm::BasicBlock *BranchAfter =
Scope.getBranchAfterBlock(0);
909 InstsToAppend.push_back(llvm::UncondBrInst::Create(BranchAfter));
916 }
else if (
Scope.getNumBranchAfters() ||
917 (HasFallthrough && !FallthroughIsBranchThrough) ||
918 (HasFixups && !HasEnclosingCleanups)) {
924 const unsigned SwitchCapacity = 10;
927 cleanupFlags.setHasExitSwitch();
930 "cleanup.dest", *
this);
931 llvm::SwitchInst *
Switch =
932 llvm::SwitchInst::Create(Load,
Default, SwitchCapacity);
934 InstsToAppend.push_back(Load);
935 InstsToAppend.push_back(
Switch);
938 if (FallthroughSource && !FallthroughIsBranchThrough) {
944 for (
unsigned I = 0, E =
Scope.getNumBranchAfters(); I != E; ++I) {
946 Scope.getBranchAfterBlock(I));
951 if (HasFixups && !HasEnclosingCleanups)
955 assert(BranchThroughDest);
956 InstsToAppend.push_back(llvm::UncondBrInst::Create(BranchThroughDest));
962 assert(
EHStack.hasNormalCleanups() == HasEnclosingCleanups);
964 EmitCleanup(*
this, Fn, cleanupFlags, NormalActiveFlag);
967 llvm::BasicBlock *NormalExit =
Builder.GetInsertBlock();
968 for (llvm::Instruction *Inst : InstsToAppend)
969 Inst->insertInto(NormalExit, NormalExit->end());
972 for (
unsigned I = FixupDepth, E =
EHStack.getNumBranchFixups();
990 if (!HasFallthrough && FallthroughSource) {
995 Builder.restoreIP(savedInactiveFallthroughIP);
1000 }
else if (HasFallthrough && FallthroughDest) {
1001 assert(!FallthroughIsBranchThrough);
1006 }
else if (HasFallthrough) {
1011 Builder.ClearInsertionPoint();
1018 llvm::BasicBlock *NewNormalEntry =
1023 if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)
1024 for (
unsigned I = FixupDepth, E =
EHStack.getNumBranchFixups();
1026 EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;
1030 if (NormalDeactivateOrigIP.isSet())
1031 Builder.restoreIP(NormalDeactivateOrigIP);
1032 assert(
EHStack.hasNormalCleanups() ||
EHStack.getNumBranchFixups() == 0);
1035 if (RequiresEHCleanup) {
1036 CGBuilderTy::InsertPoint SavedIP =
Builder.saveAndClearIP();
1045 bool PushedTerminate =
false;
1047 llvm::CleanupPadInst *CPI =
nullptr;
1053 ParentPad = llvm::ConstantTokenNone::get(
CGM.getLLVMContext());
1060 PushedTerminate =
true;
1062 if (!IsSEHFinallyCleanup)
1068 if (EHActiveFlag.
isValid() || IsActive) {
1069 cleanupFlags.setIsForEHCleanup();
1070 EmitCleanup(*
this, Fn, cleanupFlags, EHActiveFlag);
1074 Builder.CreateCleanupRet(CPI, NextAction);
1079 if (PushedTerminate)