Skip to content

Commit

Permalink
Merge pull request #82 from Unparalleled-Calvin/main
Browse files Browse the repository at this point in the history
Change API definition in dataflow graph
  • Loading branch information
hxuhack authored Dec 16, 2024
2 parents 965fa94 + 1bd0582 commit b98fef6
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 135 deletions.
56 changes: 15 additions & 41 deletions rap/src/analysis/core/dataflow/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,13 @@ impl GraphEdge {
pub fn to_dot_graph<'tcx>(&self) -> String {
let mut attr = String::new();
let mut dot = String::new();
match self {
//label=xxx
GraphEdge::NodeEdge {
src: _,
dst: _,
op,
seq,
} => {
write!(
attr,
"label=\"{}\" ",
escaped_string(format!("{}_{:?}", seq, op))
)
.unwrap();
}
GraphEdge::ConstEdge {
src: _,
dst: _,
op,
seq,
} => {
write!(
attr,
"label=\"{}\" ",
escaped_string(format!("{}_{:?}", seq, op))
)
.unwrap();
}
}
match self {
GraphEdge::NodeEdge {
src, dst, op: _, ..
} => {
write!(dot, "{:?} -> {:?} [{}]", src, dst, attr).unwrap();
}
GraphEdge::ConstEdge {
src, dst, op: _, ..
} => {
write!(dot, "{:?} -> {:?} [{}]", src, dst, attr).unwrap();
}
}
write!(
attr,
"label=\"{}\" ",
escaped_string(format!("{}_{:?}", self.seq, self.op))
)
.unwrap();
write!(dot, "{:?} -> {:?} [{}]", self.src, self.dst, attr).unwrap();
dot
}
}
Expand All @@ -81,6 +47,14 @@ impl GraphNode {
write!(attr, "label=\"<f0> {:?}\" ", local).unwrap();
}
}
NodeOp::Const(ref name) => {
write!(
attr,
"label=\"<f0> {}\" style=dashed ",
escaped_string(name.clone())
)
.unwrap();
}
NodeOp::Call(def_id) => {
let func_name = tcx.def_path_str(def_id);
if is_marker {
Expand Down
80 changes: 34 additions & 46 deletions rap/src/analysis/core/dataflow/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub enum NodeOp {
//warning: the fields are related to the version of the backend rustc version
Nop,
Err,
Const(String),
//Rvalue
Use,
Repeat,
Expand Down Expand Up @@ -55,19 +56,11 @@ pub enum EdgeOp {
}

#[derive(Clone)]
pub enum GraphEdge {
NodeEdge {
src: Local,
dst: Local,
op: EdgeOp,
seq: u32,
},
ConstEdge {
src: String,
dst: Local,
op: EdgeOp,
seq: u32,
},
pub struct GraphEdge {
pub src: Local,
pub dst: Local,
pub op: EdgeOp,
pub seq: u32,
}

#[derive(Clone)]
Expand Down Expand Up @@ -117,15 +110,18 @@ impl Graph {

pub fn add_node_edge(&mut self, src: Local, dst: Local, op: EdgeOp) -> EdgeIdx {
let seq = self.nodes[dst].seq;
let edge_idx = self.edges.push(GraphEdge::NodeEdge { src, dst, op, seq });
let edge_idx = self.edges.push(GraphEdge { src, dst, op, seq });
self.nodes[dst].in_edges.push(edge_idx);
self.nodes[src].out_edges.push(edge_idx);
edge_idx
}

pub fn add_const_edge(&mut self, src: String, dst: Local, op: EdgeOp) -> EdgeIdx {
let seq = self.nodes[dst].seq;
let edge_idx = self.edges.push(GraphEdge::ConstEdge { src, dst, op, seq });
let mut const_node = GraphNode::new();
const_node.op = NodeOp::Const(src);
let src = self.nodes.push(const_node);
let edge_idx = self.edges.push(GraphEdge { src, dst, op, seq });
self.nodes[dst].in_edges.push(edge_idx);
edge_idx
}
Expand Down Expand Up @@ -307,8 +303,8 @@ impl Graph {
pub fn collect_equivalent_locals(&self, local: Local) -> HashSet<Local> {
let mut set = HashSet::new();
let mut root = local;
let mut find_root_operator = |idx: Local| -> DFSStatus {
let node = &self.nodes[idx];
let mut find_root_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
match node.op {
NodeOp::Nop | NodeOp::Use | NodeOp::Ref => {
//Nop means an orphan node or a parameter
Expand All @@ -318,8 +314,8 @@ impl Graph {
_ => DFSStatus::Stop,
}
};
let mut find_equivalent_operator = |idx: Local| -> DFSStatus {
let node = &self.nodes[idx];
let mut find_equivalent_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if set.contains(&idx) {
return DFSStatus::Stop;
}
Expand Down Expand Up @@ -352,7 +348,7 @@ impl Graph {
pub fn is_connected(&self, idx_1: Local, idx_2: Local) -> bool {
let target = idx_2;
let find = Cell::new(false);
let mut node_operator = |idx: Local| -> DFSStatus {
let mut node_operator = |_: &Graph, idx: Local| -> DFSStatus {
find.set(idx == target);
if find.get() {
DFSStatus::Stop
Expand Down Expand Up @@ -406,32 +402,30 @@ impl Graph {
traverse_all: bool,
) -> DFSStatus
where
F: FnMut(Local) -> DFSStatus,
G: FnMut(&EdgeOp) -> DFSStatus,
F: FnMut(&Graph, Local) -> DFSStatus,
G: FnMut(&Graph, EdgeIdx) -> DFSStatus,
{
macro_rules! traverse {
($edges: ident, $field: ident) => {
for edge_idx in self.nodes[now].$edges.iter() {
let edge = &self.edges[*edge_idx];
if let GraphEdge::NodeEdge { $field, op, .. } = edge {
if matches!(edge_validator(op), DFSStatus::Continue) {
let result = self.dfs(
*$field,
direction,
node_operator,
edge_validator,
traverse_all,
);
if matches!(result, DFSStatus::Stop) && !traverse_all {
return DFSStatus::Stop;
}
if matches!(edge_validator(self, *edge_idx), DFSStatus::Continue) {
let result = self.dfs(
edge.$field,
direction,
node_operator,
edge_validator,
traverse_all,
);
if matches!(result, DFSStatus::Stop) && !traverse_all {
return DFSStatus::Stop;
}
}
}
};
}

if matches!(node_operator(now), DFSStatus::Continue) {
if matches!(node_operator(self, now), DFSStatus::Continue) {
match direction {
Direction::Upside => {
traverse!(in_edges, src);
Expand All @@ -452,30 +446,24 @@ impl Graph {

pub fn get_upside_idx(&self, node_idx: Local, order: usize) -> Option<Local> {
if let Some(edge_idx) = self.nodes[node_idx].in_edges.get(order) {
match self.edges[*edge_idx] {
GraphEdge::NodeEdge { src, .. } => Some(src),
GraphEdge::ConstEdge { .. } => None,
}
Some(self.edges[*edge_idx].src)
} else {
None
}
}

pub fn get_downside_idx(&self, node_idx: Local, order: usize) -> Option<Local> {
if let Some(edge_idx) = self.nodes[node_idx].out_edges.get(order) {
match self.edges[*edge_idx] {
GraphEdge::NodeEdge { dst, .. } => Some(dst),
GraphEdge::ConstEdge { .. } => None,
}
Some(self.edges[*edge_idx].dst)
} else {
None
}
}
}

impl Graph {
pub fn equivalent_edge_validator(op: &EdgeOp) -> DFSStatus {
match op {
pub fn equivalent_edge_validator(graph: &Graph, idx: EdgeIdx) -> DFSStatus {
match graph.edges[idx].op {
EdgeOp::Copy | EdgeOp::Move | EdgeOp::Mut | EdgeOp::Immut => DFSStatus::Continue,
EdgeOp::Nop
| EdgeOp::Const
Expand All @@ -488,7 +476,7 @@ impl Graph {
}
}

pub fn always_true_edge_validator(_: &EdgeOp) -> DFSStatus {
pub fn always_true_edge_validator(_: &Graph, _: EdgeIdx) -> DFSStatus {
DFSStatus::Continue
}
}
Expand Down
13 changes: 4 additions & 9 deletions rap/src/analysis/opt/checking/bounds_checking/bounds_len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ use rustc_middle::mir::Local;
use rustc_middle::ty::TyCtxt;

use crate::analysis::core::dataflow::graph::{
AggKind, DFSStatus, Direction, Graph, GraphEdge, GraphNode, NodeOp,
AggKind, DFSStatus, Direction, Graph, GraphNode, NodeOp,
};
use crate::analysis::utils::def_path::DefPath;
use crate::rap_debug;
use crate::utils::log::{
relative_pos_range, span_to_filename, span_to_line_number, span_to_source_code,
};
Expand Down Expand Up @@ -61,11 +60,7 @@ fn extract_upperbound_node_if_ops_range(graph: &Graph, node: &GraphNode) -> Opti
if let NodeOp::Aggregate(AggKind::Adt(def_id)) = node.op {
if def_id == target_def_id {
let upperbound_edge = &graph.edges[node.in_edges[1]]; // the second field
if let GraphEdge::NodeEdge { src, .. } = upperbound_edge {
return Some(*src);
} else {
rap_debug!("The upperbound edge of Agg node is not a NodeEdge");
}
return Some(upperbound_edge.src);
}
}
None
Expand All @@ -76,7 +71,7 @@ fn find_upside_vec_len_node(graph: &Graph, node_idx: Local) -> Option<Local> {
let def_paths = &DEFPATHS.get().unwrap();
let target_def_id = def_paths.vec_len.last_def_id();
// Warning: may traverse all upside nodes and the new result will overwrite on the previous result
let mut node_operator = |idx: Local| -> DFSStatus {
let mut node_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == target_def_id {
Expand All @@ -100,7 +95,7 @@ fn find_downside_index_node(graph: &Graph, node_idx: Local) -> Vec<Local> {
let mut index_node_idxs: Vec<Local> = Vec::new();
let def_paths = &DEFPATHS.get().unwrap();
// Warning: traverse all downside nodes
let mut node_operator = |idx: Local| -> DFSStatus {
let mut node_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == def_paths.ops_index.last_def_id()
Expand Down
71 changes: 32 additions & 39 deletions rap/src/analysis/opt/memory_cloning/hash_key_cloning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use once_cell::sync::OnceCell;

use crate::analysis::core::dataflow::graph::DFSStatus;
use crate::analysis::core::dataflow::graph::Direction;
use crate::analysis::core::dataflow::graph::GraphEdge::NodeEdge;
use rustc_hir::{intravisit, Expr, ExprKind};
use rustc_middle::mir::Local;
use rustc_middle::ty::{TyCtxt, TyKind, TypeckResults};
Expand Down Expand Up @@ -72,26 +71,23 @@ fn find_first_param_upside_clone(graph: &Graph, node: &GraphNode) -> Option<Loca
let mut clone_node_idx = None;
let def_paths = &DEFPATHS.get().unwrap();
let target_def_id = def_paths.clone.last_def_id();
if let NodeEdge { src, .. } = &graph.edges[node.in_edges[1]] {
// the first param is self, so we use 1
let mut node_operator = |idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == target_def_id {
clone_node_idx = Some(idx);
return DFSStatus::Stop;
}
let mut node_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == target_def_id {
clone_node_idx = Some(idx);
return DFSStatus::Stop;
}
DFSStatus::Continue
};
graph.dfs(
*src,
Direction::Upside,
&mut node_operator,
&mut Graph::equivalent_edge_validator,
false,
);
}
}
DFSStatus::Continue
};
graph.dfs(
graph.edges[node.in_edges[1]].src, // the first param is self, so we use 1
Direction::Upside,
&mut node_operator,
&mut Graph::equivalent_edge_validator,
false,
);
clone_node_idx
}

Expand All @@ -100,26 +96,23 @@ fn find_hashset_new_node(graph: &Graph, node: &GraphNode) -> Option<Local> {
let mut new_node_idx = None;
let def_paths = &DEFPATHS.get().unwrap();
let target_def_id = def_paths.hashset_new.last_def_id();
if let NodeEdge { src, .. } = &graph.edges[node.in_edges[0]] {
// the first param is self
let mut node_operator = |idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == target_def_id {
new_node_idx = Some(idx);
return DFSStatus::Stop;
}
let mut node_operator = |graph: &Graph, idx: Local| -> DFSStatus {
let node = &graph.nodes[idx];
if let NodeOp::Call(def_id) = node.op {
if def_id == target_def_id {
new_node_idx = Some(idx);
return DFSStatus::Stop;
}
DFSStatus::Continue
};
graph.dfs(
*src,
Direction::Upside,
&mut node_operator,
&mut Graph::equivalent_edge_validator,
false,
);
}
}
DFSStatus::Continue
};
graph.dfs(
graph.edges[node.in_edges[0]].src, // the first param is self
Direction::Upside,
&mut node_operator,
&mut Graph::equivalent_edge_validator,
false,
);
new_node_idx
}

Expand Down

0 comments on commit b98fef6

Please sign in to comment.