From a67406e2fb058d2ebf66f73c27815adf8fd0aa06 Mon Sep 17 00:00:00 2001 From: Justus Adam Date: Fri, 26 Jul 2024 14:07:05 -0400 Subject: [PATCH] Add mechanism to include crates --- .../src/body_cache.rs | 4 ++++ .../src/construct.rs | 4 ++-- .../src/local_analysis.rs | 4 ++-- crates/paralegal-flow/src/ana/mod.rs | 22 +++++++++++++++++-- crates/paralegal-flow/src/args.rs | 11 ++++++++++ crates/paralegal-flow/tests/cross-crate.rs | 1 + 6 files changed, 40 insertions(+), 6 deletions(-) diff --git a/crates/flowistry_pdg_construction/src/body_cache.rs b/crates/flowistry_pdg_construction/src/body_cache.rs index 979c3e23c3..5883a1ca6e 100644 --- a/crates/flowistry_pdg_construction/src/body_cache.rs +++ b/crates/flowistry_pdg_construction/src/body_cache.rs @@ -67,6 +67,10 @@ impl<'tcx> BodyCache<'tcx> { unsafe { std::mem::transmute(cbody) } }) } + + pub fn is_loadable(&self, key: DefId) -> bool { + (self.load_policy)(key.krate) + } } fn compute_body_with_borrowck_facts(tcx: TyCtxt<'_>, def_id: DefId) -> CachedBody<'_> { diff --git a/crates/flowistry_pdg_construction/src/construct.rs b/crates/flowistry_pdg_construction/src/construct.rs index 8464dc3aa9..3730e2e204 100644 --- a/crates/flowistry_pdg_construction/src/construct.rs +++ b/crates/flowistry_pdg_construction/src/construct.rs @@ -9,7 +9,7 @@ use flowistry_pdg::{CallString, GlobalLocation}; use df::{AnalysisDomain, Results, ResultsVisitor}; use rustc_hash::FxHashMap; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_index::IndexVec; use rustc_middle::{ mir::{visit::Visitor, AggregateKind, Location, Place, Rvalue, Terminator, TerminatorKind}, @@ -53,7 +53,7 @@ impl<'tcx> MemoPdgConstructor<'tcx> { dump_mir: false, async_info: AsyncInfo::make(tcx).expect("Async functions are not defined"), pdg_cache: Default::default(), - body_cache: BodyCache::new(tcx, |_| true), + body_cache: BodyCache::new(tcx, |krate| krate == LOCAL_CRATE), } } diff --git a/crates/flowistry_pdg_construction/src/local_analysis.rs b/crates/flowistry_pdg_construction/src/local_analysis.rs index 82bdba09fa..ffade83a02 100644 --- a/crates/flowistry_pdg_construction/src/local_analysis.rs +++ b/crates/flowistry_pdg_construction/src/local_analysis.rs @@ -443,8 +443,8 @@ impl<'tcx, 'a> LocalAnalysis<'tcx, 'a> { // Recursively generate the PDG for the child function. - if !resolved_fn.def_id().is_local() { - trace!(" bailing because function is not local"); + if self.memo.body_cache.is_loadable(resolved_fn.def_id()) { + trace!(" bailing because function is not loadable"); return None; } let cache_key = resolved_fn; diff --git a/crates/paralegal-flow/src/ana/mod.rs b/crates/paralegal-flow/src/ana/mod.rs index 86c36a5175..ad30c0a470 100644 --- a/crates/paralegal-flow/src/ana/mod.rs +++ b/crates/paralegal-flow/src/ana/mod.rs @@ -24,7 +24,11 @@ use flowistry_pdg_construction::{ use itertools::Itertools; use petgraph::visit::GraphBase; -use rustc_hir::{self as hir, def, def_id::DefId}; +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::{ + self as hir, def, + def_id::{DefId, LOCAL_CRATE}, +}; use rustc_middle::ty::TyCtxt; use rustc_span::{FileNameDisplayPreference, Span as RustSpan, Symbol}; @@ -55,12 +59,26 @@ impl<'tcx> SPDGGenerator<'tcx> { ) -> Self { let inline_judge = InlineJudge::new(marker_ctx, tcx, opts.anactrl()); let mut pdg_constructor = MemoPdgConstructor::new(tcx); + let included_crate_names = opts + .anactrl() + .included() + .iter() + .map(|s| Symbol::intern(s)) + .collect::>(); + let included_crates = tcx + .crates(()) + .iter() + .copied() + .filter(|cnum| included_crate_names.contains(&tcx.crate_name(*cnum))) + .chain(Some(LOCAL_CRATE)) + .collect::>(); pdg_constructor .with_call_change_callback(MyCallback { judge: inline_judge.clone(), tcx, }) - .with_dump_mir(opts.dbg().dump_mir()); + .with_dump_mir(opts.dbg().dump_mir()) + .with_body_loading_policy(move |krate| included_crates.contains(&krate)); Self { inline_judge, pdg_constructor, diff --git a/crates/paralegal-flow/src/args.rs b/crates/paralegal-flow/src/args.rs index bbe3a9b2b4..b24fca1af3 100644 --- a/crates/paralegal-flow/src/args.rs +++ b/crates/paralegal-flow/src/args.rs @@ -436,6 +436,9 @@ struct ClapAnalysisCtrl { /// this is used explicitly supply the argument. #[clap(long, conflicts_with_all = ["adaptive_depth", "no_cross_function_analysis"])] unconstrained_depth: bool, + /// Crates that should be recursed into. + #[clap(long)] + include: Vec, } #[derive(serde::Serialize, serde::Deserialize)] @@ -448,6 +451,7 @@ pub struct AnalysisCtrl { /// Disables all recursive analysis (both paralegal_flow's inlining as well as /// Flowistry's recursive analysis). inlining_depth: InliningDepth, + include: Vec, } impl Default for AnalysisCtrl { @@ -455,6 +459,7 @@ impl Default for AnalysisCtrl { Self { analyze: Vec::new(), inlining_depth: InliningDepth::Adaptive, + include: Default::default(), } } } @@ -467,6 +472,7 @@ impl TryFrom for AnalysisCtrl { no_cross_function_analysis, adaptive_depth, unconstrained_depth: _, + include, } = value; let inlining_depth = if adaptive_depth { @@ -480,6 +486,7 @@ impl TryFrom for AnalysisCtrl { Ok(Self { analyze, inlining_depth, + include, }) } } @@ -508,6 +515,10 @@ impl AnalysisCtrl { pub fn inlining_depth(&self) -> &InliningDepth { &self.inlining_depth } + + pub fn included(&self) -> &[String] { + &self.include + } } impl DumpArgs { diff --git a/crates/paralegal-flow/tests/cross-crate.rs b/crates/paralegal-flow/tests/cross-crate.rs index bea931513f..47999040e4 100644 --- a/crates/paralegal-flow/tests/cross-crate.rs +++ b/crates/paralegal-flow/tests/cross-crate.rs @@ -10,6 +10,7 @@ const CRATE_DIR: &str = "tests/cross-crate"; lazy_static! { static ref TEST_CRATE_ANALYZED: bool = { paralegal_flow_command(CRATE_DIR) + .args(["--include", "dependency"]) .status() .unwrap() .success()