@@ -35,11 +35,13 @@ use std::ops::{ControlFlow, Index, IndexMut};
3535use std:: slice;
3636use std:: { iter, mem, option} ;
3737
38+ use self :: graph_cyclic_cache:: GraphIsCyclicCache ;
3839use self :: predecessors:: { PredecessorCache , Predecessors } ;
3940pub use self :: query:: * ;
4041
4142pub mod abstract_const;
4243pub mod coverage;
44+ mod graph_cyclic_cache;
4345pub mod interpret;
4446pub mod mono;
4547mod predecessors;
@@ -227,6 +229,7 @@ pub struct Body<'tcx> {
227229 pub is_polymorphic : bool ,
228230
229231 predecessor_cache : PredecessorCache ,
232+ is_cyclic : GraphIsCyclicCache ,
230233}
231234
232235impl < ' tcx > Body < ' tcx > {
@@ -267,6 +270,7 @@ impl<'tcx> Body<'tcx> {
267270 required_consts : Vec :: new ( ) ,
268271 is_polymorphic : false ,
269272 predecessor_cache : PredecessorCache :: new ( ) ,
273+ is_cyclic : GraphIsCyclicCache :: new ( ) ,
270274 } ;
271275 body. is_polymorphic = body. has_param_types_or_consts ( ) ;
272276 body
@@ -296,6 +300,7 @@ impl<'tcx> Body<'tcx> {
296300 var_debug_info : Vec :: new ( ) ,
297301 is_polymorphic : false ,
298302 predecessor_cache : PredecessorCache :: new ( ) ,
303+ is_cyclic : GraphIsCyclicCache :: new ( ) ,
299304 } ;
300305 body. is_polymorphic = body. has_param_types_or_consts ( ) ;
301306 body
@@ -309,11 +314,12 @@ impl<'tcx> Body<'tcx> {
309314 #[ inline]
310315 pub fn basic_blocks_mut ( & mut self ) -> & mut IndexVec < BasicBlock , BasicBlockData < ' tcx > > {
311316 // Because the user could mutate basic block terminators via this reference, we need to
312- // invalidate the predecessor cache .
317+ // invalidate the caches .
313318 //
314319 // FIXME: Use a finer-grained API for this, so only transformations that alter terminators
315- // invalidate the predecessor cache .
320+ // invalidate the caches .
316321 self . predecessor_cache . invalidate ( ) ;
322+ self . is_cyclic . invalidate ( ) ;
317323 & mut self . basic_blocks
318324 }
319325
@@ -322,6 +328,7 @@ impl<'tcx> Body<'tcx> {
322328 & mut self ,
323329 ) -> ( & mut IndexVec < BasicBlock , BasicBlockData < ' tcx > > , & mut LocalDecls < ' tcx > ) {
324330 self . predecessor_cache . invalidate ( ) ;
331+ self . is_cyclic . invalidate ( ) ;
325332 ( & mut self . basic_blocks , & mut self . local_decls )
326333 }
327334
@@ -334,13 +341,14 @@ impl<'tcx> Body<'tcx> {
334341 & mut Vec < VarDebugInfo < ' tcx > > ,
335342 ) {
336343 self . predecessor_cache . invalidate ( ) ;
344+ self . is_cyclic . invalidate ( ) ;
337345 ( & mut self . basic_blocks , & mut self . local_decls , & mut self . var_debug_info )
338346 }
339347
340348 /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
341349 /// `START_BLOCK`.
342350 pub fn is_cfg_cyclic ( & self ) -> bool {
343- graph :: is_cyclic ( self )
351+ self . is_cyclic . is_cyclic ( self )
344352 }
345353
346354 #[ inline]
0 commit comments