@@ -149,6 +149,26 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
149
149
}
150
150
}
151
151
}
152
+
153
+ // Generate sideeffect intrinsic if jumping to any of the targets can form
154
+ // a loop.
155
+ fn maybe_sideeffect < ' b , ' tcx2 : ' b , Bx : BuilderMethods < ' b , ' tcx2 > > (
156
+ & self ,
157
+ mir : & ' b mir:: Body < ' tcx > ,
158
+ bx : & mut Bx ,
159
+ targets : & [ mir:: BasicBlock ] ,
160
+ ) {
161
+ if bx. tcx ( ) . sess . opts . debugging_opts . insert_sideeffect {
162
+ if targets. iter ( ) . any ( |target| {
163
+ * target <= * self . bb
164
+ && target
165
+ . start_location ( )
166
+ . is_predecessor_of ( self . bb . start_location ( ) , mir)
167
+ } ) {
168
+ bx. sideeffect ( ) ;
169
+ }
170
+ }
171
+ }
152
172
}
153
173
154
174
/// Codegen implementations for some terminator variants.
@@ -197,6 +217,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
197
217
let lltrue = helper. llblock ( self , targets[ 0 ] ) ;
198
218
let llfalse = helper. llblock ( self , targets[ 1 ] ) ;
199
219
if switch_ty == bx. tcx ( ) . types . bool {
220
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
200
221
// Don't generate trivial icmps when switching on bool
201
222
if let [ 0 ] = values[ ..] {
202
223
bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
@@ -210,9 +231,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
210
231
) ;
211
232
let llval = bx. const_uint_big ( switch_llty, values[ 0 ] ) ;
212
233
let cmp = bx. icmp ( IntPredicate :: IntEQ , discr. immediate ( ) , llval) ;
234
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
213
235
bx. cond_br ( cmp, lltrue, llfalse) ;
214
236
}
215
237
} else {
238
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
216
239
let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
217
240
bx. switch (
218
241
discr. immediate ( ) ,
@@ -308,6 +331,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
308
331
309
332
if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
310
333
// we don't actually need to drop anything.
334
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
311
335
helper. funclet_br ( self , & mut bx, target) ;
312
336
return
313
337
}
@@ -338,6 +362,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
338
362
FnType :: of_instance ( & bx, drop_fn) )
339
363
}
340
364
} ;
365
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
341
366
helper. do_call ( self , & mut bx, fn_ty, drop_fn, args,
342
367
Some ( ( ReturnDest :: Nothing , target) ) ,
343
368
unwind) ;
@@ -373,6 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
373
398
374
399
// Don't codegen the panic block if success if known.
375
400
if const_cond == Some ( expected) {
401
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
376
402
helper. funclet_br ( self , & mut bx, target) ;
377
403
return ;
378
404
}
@@ -383,6 +409,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
383
409
// Create the failure block and the conditional branch to it.
384
410
let lltarget = helper. llblock ( self , target) ;
385
411
let panic_block = self . new_block ( "panic" ) ;
412
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
386
413
if expected {
387
414
bx. cond_br ( cond, lltarget, panic_block. llbb ( ) ) ;
388
415
} else {
@@ -486,6 +513,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
486
513
if let Some ( destination_ref) = destination. as_ref ( ) {
487
514
let & ( ref dest, target) = destination_ref;
488
515
self . codegen_transmute ( & mut bx, & args[ 0 ] , dest) ;
516
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
489
517
helper. funclet_br ( self , & mut bx, target) ;
490
518
} else {
491
519
// If we are trying to transmute to an uninhabited type,
@@ -513,6 +541,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
513
541
Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) => {
514
542
// Empty drop glue; a no-op.
515
543
let & ( _, target) = destination. as_ref ( ) . unwrap ( ) ;
544
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
516
545
helper. funclet_br ( self , & mut bx, target) ;
517
546
return ;
518
547
}
@@ -549,6 +578,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
549
578
let fn_ty = FnType :: of_instance ( & bx, instance) ;
550
579
let llfn = bx. get_fn ( instance) ;
551
580
581
+ if let Some ( ( _, target) ) = destination. as_ref ( ) {
582
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ * target] ) ;
583
+ }
552
584
// Codegen the actual panic invoke/call.
553
585
helper. do_call (
554
586
self ,
@@ -561,7 +593,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
561
593
) ;
562
594
} else {
563
595
// a NOP
564
- helper. funclet_br ( self , & mut bx, destination. as_ref ( ) . unwrap ( ) . 1 )
596
+ let target = destination. as_ref ( ) . unwrap ( ) . 1 ;
597
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
598
+ helper. funclet_br ( self , & mut bx, target) ;
565
599
}
566
600
return ;
567
601
}
@@ -670,6 +704,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
670
704
}
671
705
672
706
if let Some ( ( _, target) ) = * destination {
707
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
673
708
helper. funclet_br ( self , & mut bx, target) ;
674
709
} else {
675
710
bx. unreachable ( ) ;
@@ -762,6 +797,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
762
797
_ => span_bug ! ( span, "no llfn for call" ) ,
763
798
} ;
764
799
800
+ if let Some ( ( _, target) ) = destination. as_ref ( ) {
801
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ * target] ) ;
802
+ }
765
803
helper. do_call ( self , & mut bx, fn_ty, fn_ptr, & llargs,
766
804
destination. as_ref ( ) . map ( |& ( _, target) | ( ret_dest, target) ) ,
767
805
cleanup) ;
@@ -811,6 +849,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
811
849
}
812
850
813
851
mir:: TerminatorKind :: Goto { target } => {
852
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
814
853
helper. funclet_br ( self , & mut bx, target) ;
815
854
}
816
855
0 commit comments