From e6d8fbede2e492e55283072e426ba81ec90f54ae Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Mon, 9 Dec 2019 18:54:06 +0100 Subject: [PATCH 1/5] cleanup polonius liveness fact generation For the var_uses_region and var_drops_region relations: - check for all facts existence only once - remove function only used once - pull var_uses_region with the other access facts instead of on its own --- .../nll/type_check/liveness/polonius.rs | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index 810811f9f5cf3..deb49b61e8d5e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -5,7 +5,6 @@ use crate::util::liveness::{categorize, DefUse}; use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache}; use rustc::ty::subst::GenericArg; -use rustc::ty::Ty; use super::TypeChecker; @@ -84,17 +83,6 @@ impl Visitor<'tcx> for UseFactsExtractor<'_> { } } -fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty<'tcx>) { - debug!("add_regions(local={:?}, type={:?})", local, ty); - typeck.tcx().for_each_free_region(&ty, |region| { - let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(region); - debug!("add_regions for region {:?}", region_vid); - if let Some(facts) = typeck.borrowck_context.all_facts { - facts.var_uses_region.push((local, region_vid)); - } - }); -} - pub(super) fn populate_access_facts( typeck: &mut TypeChecker<'_, 'tcx>, body: ReadOnlyBodyAndCache<'_, 'tcx>, @@ -118,10 +106,15 @@ pub(super) fn populate_access_facts( facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| { (local, location_table.mid_index(location)) })); - } - for (local, local_decl) in body.local_decls.iter_enumerated() { - add_var_uses_regions(typeck, local, local_decl.ty); + for (local, local_decl) in body.local_decls.iter_enumerated() { + debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty); + let universal_regions = &typeck.borrowck_context.universal_regions; + typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| { + let region_vid = universal_regions.to_region_vid(region); + facts.var_uses_region.push((local, region_vid)); + }); + } } } @@ -133,12 +126,11 @@ pub(super) fn add_var_drops_regions( kind: &GenericArg<'tcx>, ) { debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind); - let tcx = typeck.tcx(); - - tcx.for_each_free_region(kind, |drop_live_region| { - let region_vid = typeck.borrowck_context.universal_regions.to_region_vid(drop_live_region); - if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { + if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { + let universal_regions = &typeck.borrowck_context.universal_regions; + typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| { + let region_vid = universal_regions.to_region_vid(drop_live_region); facts.var_drops_region.push((local, region_vid)); - }; - }); + }); + } } From cd9ec277c57016be63489c001f4c6898f11e5f8a Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Mon, 9 Dec 2019 18:57:12 +0100 Subject: [PATCH 2/5] cleanup polonius liveness fact generation: mir visitor have a variable instead of calling a method while constructing the extractor --- .../borrow_check/nll/type_check/liveness/polonius.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index deb49b61e8d5e..5a781d006f7ac 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -93,15 +93,15 @@ pub(super) fn populate_access_facts( debug!("populate_var_liveness_facts()"); if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { - UseFactsExtractor { + let mut extractor = UseFactsExtractor { var_defined: &mut facts.var_defined, var_used: &mut facts.var_used, var_drop_used: drop_used, path_accessed_at: &mut facts.path_accessed_at, location_table, move_data, - } - .visit_body(body); + }; + extractor.visit_body(body); facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| { (local, location_table.mid_index(location)) From d18bfd647e0e4c81f9e37c7e2f510e297cc85236 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Mon, 9 Dec 2019 18:58:42 +0100 Subject: [PATCH 3/5] cleanup polonius liveness fact generation: fix debug! logs --- .../borrow_check/nll/type_check/liveness/polonius.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index 5a781d006f7ac..af7a23629e6d9 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -27,22 +27,22 @@ impl UseFactsExtractor<'_> { } fn insert_def(&mut self, local: Local, location: Location) { - debug!("LivenessFactsExtractor::insert_def()"); + debug!("UseFactsExtractor::insert_def()"); self.var_defined.push((local, self.location_to_index(location))); } fn insert_use(&mut self, local: Local, location: Location) { - debug!("LivenessFactsExtractor::insert_use()"); + debug!("UseFactsExtractor::insert_use()"); self.var_used.push((local, self.location_to_index(location))); } fn insert_drop_use(&mut self, local: Local, location: Location) { - debug!("LivenessFactsExtractor::insert_drop_use()"); + debug!("UseFactsExtractor::insert_drop_use()"); self.var_drop_used.push((local, location)); } fn insert_path_access(&mut self, path: MovePathIndex, location: Location) { - debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location); + debug!("UseFactsExtractor::insert_path_access({:?}, {:?})", path, location); self.path_accessed_at.push((path, self.location_to_index(location))); } @@ -90,7 +90,7 @@ pub(super) fn populate_access_facts( move_data: &MoveData<'_>, drop_used: &mut Vec<(Local, Location)>, ) { - debug!("populate_var_liveness_facts()"); + debug!("populate_access_facts()"); if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { let mut extractor = UseFactsExtractor { From 72579c944446465f0f6042725f112485d04b9f6d Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Mon, 9 Dec 2019 18:59:49 +0100 Subject: [PATCH 4/5] cleanup polonius liveness fact generation: refactor some type names - singular instead of plurals for a relation - terminology: use "Path"s instead of "MovePath"s --- .../borrow_check/nll/type_check/liveness/polonius.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index af7a23629e6d9..49b39c01daa0b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -8,16 +8,16 @@ use rustc::ty::subst::GenericArg; use super::TypeChecker; -type VarPointRelations = Vec<(Local, LocationIndex)>; -type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>; +type VarPointRelation = Vec<(Local, LocationIndex)>; +type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>; struct UseFactsExtractor<'me> { - var_defined: &'me mut VarPointRelations, - var_used: &'me mut VarPointRelations, + var_defined: &'me mut VarPointRelation, + var_used: &'me mut VarPointRelation, location_table: &'me LocationTable, var_drop_used: &'me mut Vec<(Local, Location)>, move_data: &'me MoveData<'me>, - path_accessed_at: &'me mut MovePathPointRelations, + path_accessed_at: &'me mut PathPointRelation, } // A Visitor to walk through the MIR and extract point-wise facts From e0481d1d40913e0d074d6681d2354385055590c6 Mon Sep 17 00:00:00 2001 From: Remy Rakic Date: Mon, 9 Dec 2019 19:16:48 +0100 Subject: [PATCH 5/5] add polonius activities to -Z self-profile - "polonius_fact_generation" is dedicated to profiling the Polonius fact generation, from the MIR and NLL constraints - "polonius_analysis" is dedicated to profiling the duration of the Polonius computations themselves: move/init analysis, liveness, borrowck-ing --- src/librustc_mir/borrow_check/nll/constraint_generation.rs | 4 ++++ src/librustc_mir/borrow_check/nll/invalidation.rs | 1 + src/librustc_mir/borrow_check/nll/mod.rs | 2 ++ .../borrow_check/nll/type_check/liveness/polonius.rs | 2 ++ src/librustc_mir/borrow_check/nll/type_check/mod.rs | 7 +++++-- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index cae303039a194..dbeccab966bbb 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -97,6 +97,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { location: Location, ) { if let Some(all_facts) = self.all_facts { + let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); all_facts.cfg_edge.push(( self.location_table.start_index(location), self.location_table.mid_index(location), @@ -142,6 +143,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { location: Location, ) { if let Some(all_facts) = self.all_facts { + let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); all_facts.cfg_edge.push(( self.location_table.start_index(location), self.location_table.mid_index(location), @@ -205,6 +207,8 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { /// as `killed`. For example, when assigning to a local, or on a call's return destination. fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) { if let Some(all_facts) = self.all_facts { + let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); + // Depending on the `Place` we're killing: // - if it's a local, or a single deref of a local, // we kill all the borrows on the local. diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 2442bdf8a9b4e..e442f9c9e322f 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -31,6 +31,7 @@ pub(super) fn generate_invalidates<'tcx>( } if let Some(all_facts) = all_facts { + let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation"); let dominators = body.dominators(); let mut ig = InvalidationGenerator { all_facts, diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index bbcb823c8f91c..9ea3bd8899b9d 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -201,6 +201,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( ); if let Some(all_facts) = &mut all_facts { + let _prof_timer = infcx.tcx.prof.generic_activity("polonius_fact_generation"); all_facts .universal_region .extend(universal_regions.universal_regions()); @@ -302,6 +303,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( .unwrap_or_else(|_| String::from("Naive")); let algorithm = Algorithm::from_str(&algorithm).unwrap(); debug!("compute_regions: using polonius algorithm {:?}", algorithm); + let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis"); Some(Rc::new(Output::compute( &all_facts, algorithm, diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index 49b39c01daa0b..0354b0d6b92c5 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -109,6 +109,7 @@ pub(super) fn populate_access_facts( for (local, local_decl) in body.local_decls.iter_enumerated() { debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty); + let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation"); let universal_regions = &typeck.borrowck_context.universal_regions; typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| { let region_vid = universal_regions.to_region_vid(region); @@ -127,6 +128,7 @@ pub(super) fn add_var_drops_regions( ) { debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind); if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() { + let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation"); let universal_regions = &typeck.borrowck_context.universal_regions; typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| { let region_vid = universal_regions.to_region_vid(drop_live_region); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 8d4e76cadbfc2..cddc3b4a271d4 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -182,7 +182,7 @@ pub(crate) fn type_check<'tcx>( move_data, location_table); - translate_outlives_facts(cx.borrowck_context); + translate_outlives_facts(&mut cx); }, ); @@ -228,8 +228,10 @@ fn type_check_internal<'a, 'tcx, R>( extra(&mut checker) } -fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) { +fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { + let cx = &mut typeck.borrowck_context; if let Some(facts) = cx.all_facts { + let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation"); let location_table = cx.location_table; facts .outlives @@ -2489,6 +2491,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // that occurs when we are borrowing an unsafe place, for // example). if let Some(all_facts) = all_facts { + let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); if let Some(borrow_index) = borrow_set.location_map.get(&location) { let region_vid = borrow_region.to_region_vid(); all_facts.borrow_region.push((