Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements and Bug Fixes #21

Open
wants to merge 44 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d1d5a06
Lock crates used for testing
zgrannan Mar 13, 2025
6ea610a
remove build.rs
zgrannan Mar 13, 2025
6287c21
WIP
zgrannan Mar 14, 2025
ca685aa
Two-phase borrows
zgrannan Mar 14, 2025
0f878d3
Appease clippy
zgrannan Mar 14, 2025
4c0b1d5
Polonius fixes
zgrannan Mar 14, 2025
1a841ce
No capabilities on region projections
zgrannan Mar 14, 2025
208f559
Use dyn
zgrannan Mar 15, 2025
8ce9e46
Fix liveness computation for RP graph
zgrannan Mar 15, 2025
35adcbf
Support for havocing of nested references in fn calls
zgrannan Mar 16, 2025
21741af
Render alias edges
zgrannan Mar 16, 2025
8fc8ceb
Graph rendering improvements
zgrannan Mar 16, 2025
5893e62
Support an additional case
zgrannan Mar 17, 2025
22f37ae
another case
zgrannan Mar 17, 2025
efc4768
Fix dotgraph tooltip
zgrannan Mar 17, 2025
acd5185
Small stuff
zgrannan Mar 17, 2025
9546516
Fix visualization
zgrannan Mar 17, 2025
7d5cf5d
add additional test
zgrannan Mar 19, 2025
34e5e5a
cleanup
zgrannan Mar 20, 2025
54fd516
Add a fix for loops
zgrannan Mar 21, 2025
b6769d8
Fix for polonius
zgrannan Mar 21, 2025
8b93951
loop fixes
zgrannan Mar 22, 2025
8775218
update benchmarks
zgrannan Mar 22, 2025
0024efa
typecheck only version for comparison
zgrannan Mar 23, 2025
4f0873b
Save cached lockfiles
zgrannan Mar 23, 2025
c933b13
Add all the lockfiles
zgrannan Mar 23, 2025
80f53cf
WIP
zgrannan Mar 24, 2025
e874765
Try not merging sccs
zgrannan Mar 24, 2025
3bb36f9
Try not merging sccs
zgrannan Mar 24, 2025
34b0f16
ignore crate
zgrannan Mar 24, 2025
ee65309
loop fix
zgrannan Mar 24, 2025
f5cc50a
WIP
zgrannan Mar 24, 2025
f2ebbfa
CI fixes
zgrannan Mar 24, 2025
301920e
CI fixes
zgrannan Mar 24, 2025
bb043aa
Disable validity checks on this crate for now
zgrannan Mar 24, 2025
429cc28
WIP
zgrannan Mar 24, 2025
749e576
Fix Jonas's example
zgrannan Mar 24, 2025
372c278
Mostly fix visualization
zgrannan Mar 24, 2025
e5d2063
Maybe improvements for rpa construction
zgrannan Mar 25, 2025
1c3d5d7
Fix issues Jasper identified
zgrannan Mar 25, 2025
80989cd
Performance improvements for serde_derive
zgrannan Mar 25, 2025
f869106
Fix stupid weaken issue
zgrannan Mar 25, 2025
2f0a3e4
Fix itertools and regex-syntax
zgrannan Mar 25, 2025
ce37652
update benchmark results
zgrannan Mar 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix liveness computation for RP graph
  • Loading branch information
zgrannan committed Mar 21, 2025
commit 8ce9e462426d96e5772b30518d5ebf913185d3a6
5 changes: 2 additions & 3 deletions src/borrow_pcg/borrow_checker/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use crate::borrow_pcg::coupling_graph_constructor::BorrowCheckerInterface;
use crate::borrow_pcg::region_projection::PCGRegion;
use crate::combined_pcs::PCGNode;
use crate::rustc_interface::borrowck::{
BorrowData, BorrowIndex, BorrowSet, LocationTable, RegionInferenceContext,
PoloniusOutput,
BorrowData, BorrowIndex, BorrowSet, LocationTable, PoloniusOutput, RegionInferenceContext,
};
use crate::rustc_interface::data_structures::fx::FxIndexMap;
use crate::rustc_interface::dataflow::compute_fixpoint;
Expand Down Expand Up @@ -136,7 +135,7 @@ impl<'mir, 'tcx> BorrowCheckerInterface<'mir, 'tcx> for BorrowCheckerImpl<'mir,
if let Some(local) = rp.local() {
local
} else {
todo!()
return true; // e.g. from a constant or a remote place
}
}
PCGNode::Place(MaybeRemotePlace::Local(p)) => p.local(),
Expand Down
75 changes: 45 additions & 30 deletions src/borrow_pcg/coupling_graph_constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,17 @@ impl<T> DebugRecursiveCallHistory<T> {
fn add(&mut self, _action: T) {}
}

pub(crate) struct CouplingGraphConstructor<'mir, 'tcx> {
pub(crate) struct RegionProjectionAbstractionConstructor<'mir, 'tcx> {
repacker: PlaceRepacker<'mir, 'tcx>,
#[allow(unused)]
block: BasicBlock,
coupling_graph: coupling::DisjointSetGraph<CGNode<'tcx>>,
graph: coupling::DisjointSetGraph<CGNode<'tcx>>,
}

#[derive(Clone, Eq, PartialEq)]
struct AddEdgeHistory<'a, 'tcx> {
bottom_connect: &'a BTreeSet<CGNode<'tcx>>,
upper_candidate: &'a BTreeSet<CGNode<'tcx>>,
bottom_connect: &'a Coupled<CGNode<'tcx>>,
upper_candidate: &'a Coupled<CGNode<'tcx>>,
}

impl std::fmt::Display for AddEdgeHistory<'_, '_> {
Expand All @@ -239,77 +239,92 @@ impl std::fmt::Display for AddEdgeHistory<'_, '_> {
}
}

impl<'mir, 'tcx> CouplingGraphConstructor<'mir, 'tcx> {
pub(crate) fn new(
repacker: PlaceRepacker<'mir, 'tcx>,
block: BasicBlock,
) -> Self {
impl<'mir, 'tcx> RegionProjectionAbstractionConstructor<'mir, 'tcx> {
pub(crate) fn new(repacker: PlaceRepacker<'mir, 'tcx>, block: BasicBlock) -> Self {
Self {
repacker,
block,
coupling_graph: coupling::DisjointSetGraph::new(),
graph: coupling::DisjointSetGraph::new(),
}
}

fn add_edges_from<'a>(
&mut self,
bg: &coupling::DisjointSetGraph<CGNode<'tcx>>,
bottom_connect: &'a BTreeSet<CGNode<'tcx>>,
upper_candidate: &'a BTreeSet<CGNode<'tcx>>,
bottom_connect: &'a Coupled<CGNode<'tcx>>,
upper_candidate: &'a Coupled<CGNode<'tcx>>,
borrow_checker: &dyn BorrowCheckerInterface<'mir, 'tcx>,
mut history: DebugRecursiveCallHistory<AddEdgeHistory<'a, 'tcx>>,
) {
history.add(AddEdgeHistory {
bottom_connect,
upper_candidate,
});
let upper_candidate = upper_candidate.clone().into();
let upper_candidate = upper_candidate.clone();
let endpoints = bg.endpoints_pointing_to(&upper_candidate);
for coupled in endpoints {
pcg_validity_assert!(
coupled != upper_candidate,
"Coupling graph should be acyclic"
);
let should_include = coupled
.iter()
.any(|n| /* self.liveness.is_live(*n, self.block) && */ !n.is_old());
let coupled_set: BTreeSet<_> = coupled.clone().into_iter().collect();
let is_root = bg.is_root(&coupled) && !coupled.iter().any(|n| n.is_old());
let should_include = is_root
|| coupled.iter().any(|n| {
borrow_checker.is_live(
(*n).into(),
Location {
block: self.block,
statement_index: 0,
},
) && !n.is_old()
});
tracing::info!(
"connect {} to {} ? (is_root: {:?}): {}",
bottom_connect.to_short_string(self.repacker),
coupled.to_short_string(self.repacker),
is_root,
should_include
);
if !should_include {
self.add_edges_from(bg, bottom_connect, &coupled_set, history.clone());
} else {
self.coupling_graph.add_edge(
self.add_edges_from(
bg,
bottom_connect,
&coupled,
&bottom_connect.clone().into(),
self.repacker,
borrow_checker,
history.clone(),
);
self.add_edges_from(bg, &coupled_set, &coupled_set, history.clone());
} else {
self.graph
.add_edge(&coupled, &bottom_connect.clone(), self.repacker);
self.add_edges_from(bg, &coupled, &coupled, borrow_checker, history.clone());
}
}
}

pub(crate) fn construct_region_projection_abstraction(
mut self,
bg: &BorrowsGraph<'tcx>,
borrow_checker: &dyn BorrowCheckerInterface<'mir, 'tcx>,
) -> coupling::DisjointSetGraph<CGNode<'tcx>> {
tracing::debug!("Construct coupling graph start");
let full_graph = bg.base_coupling_graph(self.repacker);
let full_graph = bg.base_rp_graph(self.repacker);
if coupling_imgcat_debug() {
full_graph.render_with_imgcat(self.repacker, "Base coupling graph");
}
let leaf_nodes = full_graph.leaf_nodes();
let num_leaf_nodes = leaf_nodes.len();
for (i, node) in leaf_nodes.into_iter().enumerate() {
tracing::debug!("Inserting leaf node {} / {}", i, num_leaf_nodes);
self.coupling_graph
.insert_endpoint(node.clone(), self.repacker);
let node_set: BTreeSet<_> = node.into_iter().collect();
self.graph.insert_endpoint(node.clone(), self.repacker);
self.add_edges_from(
&full_graph,
&node_set,
&node_set,
&node,
&node,
borrow_checker,
DebugRecursiveCallHistory::new(),
);
}
tracing::debug!("Construct coupling graph end");
self.coupling_graph
self.graph
}
}
16 changes: 6 additions & 10 deletions src/borrow_pcg/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ use super::{
borrow_pcg_edge::{
BlockedNode, BorrowPCGEdge, BorrowPCGEdgeLike, BorrowPCGEdgeRef, LocalNode, ToBorrowsEdge,
},
coupling_graph_constructor::{BorrowCheckerInterface, CGNode, CouplingGraphConstructor},
coupling_graph_constructor::{
BorrowCheckerInterface, CGNode, RegionProjectionAbstractionConstructor,
},
edge::borrow::LocalBorrow,
edge_data::EdgeData,
has_pcs_elem::{HasPcgElems, MakePlaceOld},
Expand Down Expand Up @@ -150,7 +152,7 @@ impl<'tcx> BorrowsGraph<'tcx> {
.map(|(kind, conditions)| BorrowPCGEdgeRef { kind, conditions })
}

pub(crate) fn base_coupling_graph(
pub(crate) fn base_rp_graph(
&self,
repacker: PlaceRepacker<'_, 'tcx>,
) -> coupling::DisjointSetGraph<CGNode<'tcx>> {
Expand Down Expand Up @@ -213,7 +215,6 @@ impl<'tcx> BorrowsGraph<'tcx> {
continue;
}
seen.insert(ef);
tracing::debug!("Exploring from {}", ef.current());
let edges_blocking = blocking_map.get_edges_blocking(ef.current(), repacker);
for edge in edges_blocking.iter() {
match edge.kind() {
Expand All @@ -232,10 +233,6 @@ impl<'tcx> BorrowsGraph<'tcx> {
graph.add_edge(&inputs, &outputs, repacker);
}
_ => {
// if let BorrowPCGEdgeKind::Outlives(outlives) = edge.kind() {
// graph.insert_endpoint(Coupled::singleton(outlives.long().into()));
// graph.insert_endpoint(Coupled::singleton(outlives.short().into()));
// }
for node in edge.blocked_by_nodes(repacker) {
if let LocalNode::RegionProjection(rp) = node {
if let Some(source) = ef.connect()
Expand Down Expand Up @@ -421,13 +418,12 @@ impl<'tcx> BorrowsGraph<'tcx> {

fn construct_region_projection_abstraction<'mir>(
&self,
#[allow(unused)]
borrow_checker: &dyn BorrowCheckerInterface<'mir, 'tcx>,
repacker: PlaceRepacker<'mir, 'tcx>,
block: BasicBlock,
) -> coupling::DisjointSetGraph<CGNode<'tcx>> {
let constructor = CouplingGraphConstructor::new(repacker, block);
constructor.construct_region_projection_abstraction(self)
let constructor = RegionProjectionAbstractionConstructor::new(repacker, block);
constructor.construct_region_projection_abstraction(self, borrow_checker)
}

fn join_loop<'mir>(
Expand Down
9 changes: 9 additions & 0 deletions src/coupling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ impl<'tcx, N: Copy + Ord + Clone + DisplayWithRepacker<'tcx> + Hash> DisjointSet
.collect()
}

pub(crate) fn is_root(&self, node: &Coupled<N>) -> bool {
self.lookup(*node.iter().next().unwrap()).is_some_and(|idx| {
self.inner
.neighbors_directed(idx, Direction::Incoming)
.count()
== 0
})
}

pub(crate) fn edges(&self) -> impl Iterator<Item = (Coupled<N>, Coupled<N>)> + '_ {
self.inner.edge_references().map(|e| {
let source = self.inner.node_weight(e.source()).unwrap();
Expand Down
1 change: 1 addition & 0 deletions src/utils/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub(crate) trait FallableVisitor<'tcx> {
Ok(())
}

#[allow(unreachable_patterns)]
fn super_statement_fallable(
&mut self,
statement: &mir::Statement<'tcx>,
Expand Down