@@ -119,16 +119,30 @@ char *EHScopeStack::allocate(size_t Size) {
119
119
}
120
120
121
121
EHScopeStack::stable_iterator
122
- EHScopeStack::getEnclosingEHCleanup (iterator it) const {
123
- assert (it != end ());
124
- do {
125
- if (isa<EHCleanupScope>(*it)) {
126
- if (cast<EHCleanupScope>(*it).isEHCleanup ())
127
- return stabilize (it);
128
- return cast<EHCleanupScope>(*it).getEnclosingEHCleanup ();
122
+ EHScopeStack::getInnermostActiveNormalCleanup () const {
123
+ for (stable_iterator si = getInnermostNormalCleanup (), se = stable_end ();
124
+ si != se; ) {
125
+ EHCleanupScope &cleanup = cast<EHCleanupScope>(*find (si));
126
+ if (cleanup.isActive ()) return si;
127
+ si = cleanup.getEnclosingNormalCleanup ();
128
+ }
129
+ return stable_end ();
130
+ }
131
+
132
+ EHScopeStack::stable_iterator EHScopeStack::getInnermostActiveEHScope () const {
133
+ for (stable_iterator si = getInnermostEHScope (), se = stable_end ();
134
+ si != se; ) {
135
+ // Skip over inactive cleanups.
136
+ EHCleanupScope *cleanup = dyn_cast<EHCleanupScope>(&*find (si));
137
+ if (cleanup && !cleanup->isActive ()) {
138
+ si = cleanup->getEnclosingEHScope ();
139
+ continue ;
129
140
}
130
- ++it;
131
- } while (it != end ());
141
+
142
+ // All other scopes are always active.
143
+ return si;
144
+ }
145
+
132
146
return stable_end ();
133
147
}
134
148
@@ -146,11 +160,11 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
146
160
Size ,
147
161
BranchFixups.size (),
148
162
InnermostNormalCleanup,
149
- InnermostEHCleanup );
163
+ InnermostEHScope );
150
164
if (IsNormalCleanup)
151
165
InnermostNormalCleanup = stable_begin ();
152
166
if (IsEHCleanup)
153
- InnermostEHCleanup = stable_begin ();
167
+ InnermostEHScope = stable_begin ();
154
168
155
169
return Scope->getCleanupBuffer ();
156
170
}
@@ -161,11 +175,9 @@ void EHScopeStack::popCleanup() {
161
175
assert (isa<EHCleanupScope>(*begin ()));
162
176
EHCleanupScope &Cleanup = cast<EHCleanupScope>(*begin ());
163
177
InnermostNormalCleanup = Cleanup.getEnclosingNormalCleanup ();
164
- InnermostEHCleanup = Cleanup.getEnclosingEHCleanup ();
178
+ InnermostEHScope = Cleanup.getEnclosingEHScope ();
165
179
StartOfData += Cleanup.getAllocatedSize ();
166
180
167
- if (empty ()) NextEHDestIndex = FirstEHDestIndex;
168
-
169
181
// Destroy the cleanup.
170
182
Cleanup.~EHCleanupScope ();
171
183
@@ -182,37 +194,35 @@ void EHScopeStack::popCleanup() {
182
194
}
183
195
}
184
196
185
- EHFilterScope *EHScopeStack::pushFilter (unsigned NumFilters) {
186
- char *Buffer = allocate (EHFilterScope::getSizeForNumFilters (NumFilters));
187
- CatchDepth++;
188
- return new (Buffer) EHFilterScope (NumFilters);
197
+ EHFilterScope *EHScopeStack::pushFilter (unsigned numFilters) {
198
+ assert (getInnermostEHScope () == stable_end ());
199
+ char *buffer = allocate (EHFilterScope::getSizeForNumFilters (numFilters));
200
+ EHFilterScope *filter = new (buffer) EHFilterScope (numFilters);
201
+ InnermostEHScope = stable_begin ();
202
+ return filter;
189
203
}
190
204
191
205
void EHScopeStack::popFilter () {
192
206
assert (!empty () && " popping exception stack when not empty" );
193
207
194
- EHFilterScope &Filter = cast<EHFilterScope>(*begin ());
195
- StartOfData += EHFilterScope::getSizeForNumFilters (Filter.getNumFilters ());
196
-
197
- if (empty ()) NextEHDestIndex = FirstEHDestIndex;
208
+ EHFilterScope &filter = cast<EHFilterScope>(*begin ());
209
+ StartOfData += EHFilterScope::getSizeForNumFilters (filter.getNumFilters ());
198
210
199
- assert (CatchDepth > 0 && " mismatched filter push/pop" );
200
- CatchDepth--;
211
+ InnermostEHScope = filter.getEnclosingEHScope ();
201
212
}
202
213
203
- EHCatchScope *EHScopeStack::pushCatch (unsigned NumHandlers) {
204
- char *Buffer = allocate (EHCatchScope::getSizeForNumHandlers (NumHandlers));
205
- CatchDepth++;
206
- EHCatchScope *Scope = new (Buffer) EHCatchScope (NumHandlers);
207
- for (unsigned I = 0 ; I != NumHandlers; ++I)
208
- Scope->getHandlers ()[I].Index = getNextEHDestIndex ();
209
- return Scope;
214
+ EHCatchScope *EHScopeStack::pushCatch (unsigned numHandlers) {
215
+ char *buffer = allocate (EHCatchScope::getSizeForNumHandlers (numHandlers));
216
+ EHCatchScope *scope =
217
+ new (buffer) EHCatchScope (numHandlers, InnermostEHScope);
218
+ InnermostEHScope = stable_begin ();
219
+ return scope;
210
220
}
211
221
212
222
void EHScopeStack::pushTerminate () {
213
223
char *Buffer = allocate (EHTerminateScope::getSize ());
214
- CatchDepth++ ;
215
- new (Buffer) EHTerminateScope ( getNextEHDestIndex () );
224
+ new (Buffer) EHTerminateScope (InnermostEHScope) ;
225
+ InnermostEHScope = stable_begin ( );
216
226
}
217
227
218
228
// / Remove any 'null' fixups on the stack. However, we can't pop more
@@ -384,17 +394,6 @@ static llvm::BasicBlock *CreateNormalEntry(CodeGenFunction &CGF,
384
394
return Entry;
385
395
}
386
396
387
- static llvm::BasicBlock *CreateEHEntry (CodeGenFunction &CGF,
388
- EHCleanupScope &Scope) {
389
- assert (Scope.isEHCleanup ());
390
- llvm::BasicBlock *Entry = Scope.getEHBlock ();
391
- if (!Entry) {
392
- Entry = CGF.createBasicBlock (" eh.cleanup" );
393
- Scope.setEHBlock (Entry);
394
- }
395
- return Entry;
396
- }
397
-
398
397
// / Attempts to reduce a cleanup's entry block to a fallthrough. This
399
398
// / is basically llvm::MergeBlockIntoPredecessor, except
400
399
// / simplified/optimized for the tighter constraints on cleanup blocks.
@@ -544,7 +543,10 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
544
543
545
544
// Check whether we need an EH cleanup. This is only true if we've
546
545
// generated a lazy EH cleanup block.
547
- bool RequiresEHCleanup = Scope.hasEHBranches ();
546
+ llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock ();
547
+ assert (Scope.hasEHBranches () == (EHEntry != 0 ));
548
+ bool RequiresEHCleanup = (EHEntry != 0 );
549
+ EHScopeStack::stable_iterator EHParent = Scope.getEnclosingEHScope ();
548
550
549
551
// Check the three conditions which might require a normal cleanup:
550
552
@@ -580,12 +582,6 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
580
582
RequiresNormalCleanup = true ;
581
583
}
582
584
583
- EHScopeStack::Cleanup::Flags cleanupFlags;
584
- if (Scope.isNormalCleanup ())
585
- cleanupFlags.setIsNormalCleanupKind ();
586
- if (Scope.isEHCleanup ())
587
- cleanupFlags.setIsEHCleanupKind ();
588
-
589
585
// If we have a prebranched fallthrough into an inactive normal
590
586
// cleanup, rewrite it so that it leads to the appropriate place.
591
587
if (Scope.isNormalCleanup () && HasPrebranchedFallthrough && !IsActive) {
@@ -634,61 +630,11 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
634
630
EHScopeStack::Cleanup *Fn =
635
631
reinterpret_cast <EHScopeStack::Cleanup*>(CleanupBuffer.data ());
636
632
637
- // We want to emit the EH cleanup after the normal cleanup, but go
638
- // ahead and do the setup for the EH cleanup while the scope is still
639
- // alive.
640
- llvm::BasicBlock *EHEntry = 0 ;
641
- SmallVector<llvm::Instruction*, 2 > EHInstsToAppend;
642
- if (RequiresEHCleanup) {
643
- EHEntry = CreateEHEntry (*this , Scope);
644
-
645
- // Figure out the branch-through dest if necessary.
646
- llvm::BasicBlock *EHBranchThroughDest = 0 ;
647
- if (Scope.hasEHBranchThroughs ()) {
648
- assert (Scope.getEnclosingEHCleanup () != EHStack.stable_end ());
649
- EHScope &S = *EHStack.find (Scope.getEnclosingEHCleanup ());
650
- EHBranchThroughDest = CreateEHEntry (*this , cast<EHCleanupScope>(S));
651
- }
652
-
653
- // If we have exactly one branch-after and no branch-throughs, we
654
- // can dispatch it without a switch.
655
- if (!Scope.hasEHBranchThroughs () &&
656
- Scope.getNumEHBranchAfters () == 1 ) {
657
- assert (!EHBranchThroughDest);
658
-
659
- // TODO: remove the spurious eh.cleanup.dest stores if this edge
660
- // never went through any switches.
661
- llvm::BasicBlock *BranchAfterDest = Scope.getEHBranchAfterBlock (0 );
662
- EHInstsToAppend.push_back (llvm::BranchInst::Create (BranchAfterDest));
663
-
664
- // Otherwise, if we have any branch-afters, we need a switch.
665
- } else if (Scope.getNumEHBranchAfters ()) {
666
- // The default of the switch belongs to the branch-throughs if
667
- // they exist.
668
- llvm::BasicBlock *Default =
669
- (EHBranchThroughDest ? EHBranchThroughDest : getUnreachableBlock ());
670
-
671
- const unsigned SwitchCapacity = Scope.getNumEHBranchAfters ();
672
-
673
- llvm::LoadInst *Load =
674
- new llvm::LoadInst (getEHCleanupDestSlot (), " cleanup.dest" );
675
- llvm::SwitchInst *Switch =
676
- llvm::SwitchInst::Create (Load, Default, SwitchCapacity);
677
-
678
- EHInstsToAppend.push_back (Load);
679
- EHInstsToAppend.push_back (Switch);
680
-
681
- for (unsigned I = 0 , E = Scope.getNumEHBranchAfters (); I != E; ++I)
682
- Switch->addCase (Scope.getEHBranchAfterIndex (I),
683
- Scope.getEHBranchAfterBlock (I));
684
-
685
- // Otherwise, we have only branch-throughs; jump to the next EH
686
- // cleanup.
687
- } else {
688
- assert (EHBranchThroughDest);
689
- EHInstsToAppend.push_back (llvm::BranchInst::Create (EHBranchThroughDest));
690
- }
691
- }
633
+ EHScopeStack::Cleanup::Flags cleanupFlags;
634
+ if (Scope.isNormalCleanup ())
635
+ cleanupFlags.setIsNormalCleanupKind ();
636
+ if (Scope.isEHCleanup ())
637
+ cleanupFlags.setIsEHCleanupKind ();
692
638
693
639
if (!RequiresNormalCleanup) {
694
640
destroyOptimisticNormalEntry (*this , Scope);
@@ -890,10 +836,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
890
836
cleanupFlags.setIsForEHCleanup ();
891
837
EmitCleanup (*this , Fn, cleanupFlags, EHActiveFlag);
892
838
893
- // Append the prepared cleanup prologue from above.
894
- llvm::BasicBlock *EHExit = Builder.GetInsertBlock ();
895
- for (unsigned I = 0 , E = EHInstsToAppend.size (); I != E; ++I)
896
- EHExit->getInstList ().push_back (EHInstsToAppend[I]);
839
+ Builder.CreateBr (getEHDispatchBlock (EHParent));
897
840
898
841
Builder.restoreIP (SavedIP);
899
842
@@ -1005,64 +948,6 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
1005
948
Builder.ClearInsertionPoint ();
1006
949
}
1007
950
1008
- void CodeGenFunction::EmitBranchThroughEHCleanup (UnwindDest Dest) {
1009
- // We should never get invalid scope depths for an UnwindDest; that
1010
- // implies that the destination wasn't set up correctly.
1011
- assert (Dest.getScopeDepth ().isValid () && " invalid scope depth on EH dest?" );
1012
-
1013
- if (!HaveInsertPoint ())
1014
- return ;
1015
-
1016
- // Create the branch.
1017
- llvm::BranchInst *BI = Builder.CreateBr (Dest.getBlock ());
1018
-
1019
- // Calculate the innermost active cleanup.
1020
- EHScopeStack::stable_iterator
1021
- InnermostCleanup = EHStack.getInnermostActiveEHCleanup ();
1022
-
1023
- // If the destination is in the same EH cleanup scope as us, we
1024
- // don't need to thread through anything.
1025
- if (InnermostCleanup.encloses (Dest.getScopeDepth ())) {
1026
- Builder.ClearInsertionPoint ();
1027
- return ;
1028
- }
1029
- assert (InnermostCleanup != EHStack.stable_end ());
1030
-
1031
- // Store the index at the start.
1032
- llvm::ConstantInt *Index = Builder.getInt32 (Dest.getDestIndex ());
1033
- new llvm::StoreInst (Index, getEHCleanupDestSlot (), BI);
1034
-
1035
- // Adjust BI to point to the first cleanup block.
1036
- {
1037
- EHCleanupScope &Scope =
1038
- cast<EHCleanupScope>(*EHStack.find (InnermostCleanup));
1039
- BI->setSuccessor (0 , CreateEHEntry (*this , Scope));
1040
- }
1041
-
1042
- // Add this destination to all the scopes involved.
1043
- for (EHScopeStack::stable_iterator
1044
- I = InnermostCleanup, E = Dest.getScopeDepth (); ; ) {
1045
- assert (E.strictlyEncloses (I));
1046
- EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find (I));
1047
- assert (Scope.isEHCleanup ());
1048
- I = Scope.getEnclosingEHCleanup ();
1049
-
1050
- // If this is the last cleanup we're propagating through, add this
1051
- // as a branch-after.
1052
- if (I == E) {
1053
- Scope.addEHBranchAfter (Index, Dest.getBlock ());
1054
- break ;
1055
- }
1056
-
1057
- // Otherwise, add it as a branch-through. If this isn't new
1058
- // information, all the rest of the work has been done before.
1059
- if (!Scope.addEHBranchThrough (Dest.getBlock ()))
1060
- break ;
1061
- }
1062
-
1063
- Builder.ClearInsertionPoint ();
1064
- }
1065
-
1066
951
static bool IsUsedAsNormalCleanup (EHScopeStack &EHStack,
1067
952
EHScopeStack::stable_iterator C) {
1068
953
// If we needed a normal block for any reason, that counts.
@@ -1083,18 +968,21 @@ static bool IsUsedAsNormalCleanup(EHScopeStack &EHStack,
1083
968
}
1084
969
1085
970
static bool IsUsedAsEHCleanup (EHScopeStack &EHStack,
1086
- EHScopeStack::stable_iterator C ) {
971
+ EHScopeStack::stable_iterator cleanup ) {
1087
972
// If we needed an EH block for any reason, that counts.
1088
- if (cast<EHCleanupScope>(* EHStack.find (C)). getEHBlock ())
973
+ if (EHStack.find (cleanup)-> hasEHBranches ())
1089
974
return true ;
1090
975
1091
976
// Check whether any enclosed cleanups were needed.
1092
977
for (EHScopeStack::stable_iterator
1093
- I = EHStack.getInnermostEHCleanup (); I != C; ) {
1094
- assert (C.strictlyEncloses (I));
1095
- EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find (I));
1096
- if (S.getEHBlock ()) return true ;
1097
- I = S.getEnclosingEHCleanup ();
978
+ i = EHStack.getInnermostEHScope (); i != cleanup; ) {
979
+ assert (cleanup.strictlyEncloses (i));
980
+
981
+ EHScope &scope = *EHStack.find (i);
982
+ if (scope.hasEHBranches ())
983
+ return true ;
984
+
985
+ i = scope.getEnclosingEHScope ();
1098
986
}
1099
987
1100
988
return false ;
@@ -1189,10 +1077,3 @@ llvm::Value *CodeGenFunction::getNormalCleanupDestSlot() {
1189
1077
CreateTempAlloca (Builder.getInt32Ty (), " cleanup.dest.slot" );
1190
1078
return NormalCleanupDest;
1191
1079
}
1192
-
1193
- llvm::Value *CodeGenFunction::getEHCleanupDestSlot () {
1194
- if (!EHCleanupDest)
1195
- EHCleanupDest =
1196
- CreateTempAlloca (Builder.getInt32Ty (), " eh.cleanup.dest.slot" );
1197
- return EHCleanupDest;
1198
- }
0 commit comments