@@ -39,7 +39,6 @@ enum MergingSucc {
39
39
struct TerminatorCodegenHelper < ' tcx > {
40
40
bb : mir:: BasicBlock ,
41
41
terminator : & ' tcx mir:: Terminator < ' tcx > ,
42
- funclet_bb : Option < mir:: BasicBlock > ,
43
42
}
44
43
45
44
impl < ' a , ' tcx > TerminatorCodegenHelper < ' tcx > {
@@ -49,28 +48,24 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
49
48
& self ,
50
49
fx : & ' b mut FunctionCx < ' a , ' tcx , Bx > ,
51
50
) -> Option < & ' b Bx :: Funclet > {
52
- let funclet_bb = self . funclet_bb ?;
53
- if base:: wants_msvc_seh ( fx. cx . tcx ( ) . sess ) {
54
- // If `landing_pad_for` hasn't been called yet to create the `Funclet`,
55
- // it has to be now. This may not seem necessary, as RPO should lead
56
- // to all the unwind edges being visited (and so to `landing_pad_for`
57
- // getting called for them), before building any of the blocks inside
58
- // the funclet itself - however, if MIR contains edges that end up not
59
- // being needed in the LLVM IR after monomorphization, the funclet may
60
- // be unreachable, and we don't have yet a way to skip building it in
61
- // such an eventuality (which may be a better solution than this).
62
- if fx. funclets [ funclet_bb] . is_none ( ) {
63
- fx. landing_pad_for ( funclet_bb) ;
64
- }
65
-
66
- Some (
67
- fx. funclets [ funclet_bb]
68
- . as_ref ( )
69
- . expect ( "landing_pad_for didn't also create funclets entry" ) ,
70
- )
71
- } else {
72
- None
51
+ let cleanup_kinds = ( & fx. cleanup_kinds ) . as_ref ( ) ?;
52
+ let funclet_bb = cleanup_kinds[ self . bb ] . funclet_bb ( self . bb ) ?;
53
+ // If `landing_pad_for` hasn't been called yet to create the `Funclet`,
54
+ // it has to be now. This may not seem necessary, as RPO should lead
55
+ // to all the unwind edges being visited (and so to `landing_pad_for`
56
+ // getting called for them), before building any of the blocks inside
57
+ // the funclet itself - however, if MIR contains edges that end up not
58
+ // being needed in the LLVM IR after monomorphization, the funclet may
59
+ // be unreachable, and we don't have yet a way to skip building it in
60
+ // such an eventuality (which may be a better solution than this).
61
+ if fx. funclets [ funclet_bb] . is_none ( ) {
62
+ fx. landing_pad_for ( funclet_bb) ;
73
63
}
64
+ Some (
65
+ fx. funclets [ funclet_bb]
66
+ . as_ref ( )
67
+ . expect ( "landing_pad_for didn't also create funclets entry" ) ,
68
+ )
74
69
}
75
70
76
71
/// Get a basic block (creating it if necessary), possibly with cleanup
@@ -104,23 +99,24 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
104
99
fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
105
100
target : mir:: BasicBlock ,
106
101
) -> ( bool , bool ) {
107
- let target_funclet = fx. cleanup_kinds [ target] . funclet_bb ( target) ;
108
- let ( needs_landing_pad, is_cleanupret) = match ( self . funclet_bb , target_funclet) {
109
- ( None , None ) => ( false , false ) ,
110
- ( None , Some ( _) ) => ( true , false ) ,
111
- ( Some ( _) , None ) => {
112
- let span = self . terminator . source_info . span ;
113
- span_bug ! ( span, "{:?} - jump out of cleanup?" , self . terminator) ;
114
- }
115
- ( Some ( f) , Some ( t_f) ) => {
116
- if f == t_f || !base:: wants_msvc_seh ( fx. cx . tcx ( ) . sess ) {
117
- ( false , false )
118
- } else {
119
- ( true , true )
102
+ if let Some ( ref cleanup_kinds) = fx. cleanup_kinds {
103
+ let funclet_bb = cleanup_kinds[ self . bb ] . funclet_bb ( self . bb ) ;
104
+ let target_funclet = cleanup_kinds[ target] . funclet_bb ( target) ;
105
+ let ( needs_landing_pad, is_cleanupret) = match ( funclet_bb, target_funclet) {
106
+ ( None , None ) => ( false , false ) ,
107
+ ( None , Some ( _) ) => ( true , false ) ,
108
+ ( Some ( f) , Some ( t_f) ) => ( f != t_f, f != t_f) ,
109
+ ( Some ( _) , None ) => {
110
+ let span = self . terminator . source_info . span ;
111
+ span_bug ! ( span, "{:?} - jump out of cleanup?" , self . terminator) ;
120
112
}
121
- }
122
- } ;
123
- ( needs_landing_pad, is_cleanupret)
113
+ } ;
114
+ ( needs_landing_pad, is_cleanupret)
115
+ } else {
116
+ let needs_landing_pad = !fx. mir [ self . bb ] . is_cleanup && fx. mir [ target] . is_cleanup ;
117
+ let is_cleanupret = false ;
118
+ ( needs_landing_pad, is_cleanupret)
119
+ }
124
120
}
125
121
126
122
fn funclet_br < Bx : BuilderMethods < ' a , ' tcx > > (
@@ -1253,9 +1249,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1253
1249
) -> MergingSucc {
1254
1250
debug ! ( "codegen_terminator: {:?}" , terminator) ;
1255
1251
1256
- // Create the cleanup bundle, if needed.
1257
- let funclet_bb = self . cleanup_kinds [ bb] . funclet_bb ( bb) ;
1258
- let helper = TerminatorCodegenHelper { bb, terminator, funclet_bb } ;
1252
+ let helper = TerminatorCodegenHelper { bb, terminator } ;
1259
1253
1260
1254
let mergeable_succ = || {
1261
1255
// Note: any call to `switch_to_block` will invalidate a `true` value
0 commit comments