rapx/analysis/dataflow/
mod.rs1pub mod debug;
2pub mod default;
3pub mod graph;
4
5use std::{
6 collections::{HashMap, HashSet},
7 fmt::{self, Debug, Display},
8};
9
10pub mod types;
11use crate::{analysis::Analysis, utils::source::get_fn_name_byid};
12pub use types::*;
13
14impl From<DataflowGraph> for DataFlowGraph {
15 fn from(graph: DataflowGraph) -> Self {
16 let param_ret_deps = graph.param_return_deps();
17 DataFlowGraph {
18 nodes: graph.nodes,
19 edges: graph.edges,
20 param_ret_deps,
21 }
22 }
23}
24
25pub type Graph = DataflowGraph;
27pub type GraphNode = DataflowNode;
28pub type GraphEdge = DataflowEdge;
29
30use rustc_hir::def_id::DefId;
31use rustc_index::IndexVec;
32use rustc_middle::mir::Local;
33
34pub type Arg2Ret = IndexVec<Local, bool>;
35pub type Arg2RetMap = HashMap<DefId, IndexVec<Local, bool>>;
36#[derive(Clone)]
37pub struct DataFlowGraph {
38 pub nodes: GraphNodes,
39 pub edges: GraphEdges,
40 pub param_ret_deps: Arg2Ret,
41}
42pub type DataFlowGraphMap = HashMap<DefId, DataFlowGraph>;
43
44pub struct Arg2RetWrapper(pub Arg2Ret);
45pub struct Arg2RetMapWrapper(pub Arg2RetMap);
46pub struct DataFlowGraphWrapper(pub DataFlowGraph);
47pub struct DataFlowGraphMapWrapper(pub HashMap<DefId, DataFlowGraph>);
48
49pub trait DataflowAnalysis: Analysis {
51 fn get_fn_dataflow(&self, def_id: DefId) -> Option<DataFlowGraph>;
52 fn get_all_dataflow(&self) -> DataFlowGraphMap;
53 fn has_flow_between(&self, def_id: DefId, local1: Local, local2: Local) -> bool;
54 fn collect_equivalent_locals(&self, def_id: DefId, local: Local) -> HashSet<Local>;
55 fn get_fn_arg2ret(&self, def_id: DefId) -> Arg2Ret;
56 fn get_all_arg2ret(&self) -> Arg2RetMap;
57}
58
59impl fmt::Display for Arg2RetWrapper {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 let arg2ret: &Arg2Ret = &self.0;
62 for (local, depends) in arg2ret.iter_enumerated() {
63 if local.as_u32() > 0 {
64 if *depends {
65 writeln!(f, "Argument {:?} ---> Return value _0", local)?;
66 }
67 }
68 }
69 Ok(())
70 }
71}
72
73impl fmt::Display for Arg2RetMapWrapper {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 writeln!(f, "=== Print dataflow analysis results ===")?;
76 for (def_id, arg2ret) in &self.0 {
77 let fn_name = get_fn_name_byid(def_id);
78 writeln!(
79 f,
80 "Function: {:?}\n{}",
81 fn_name,
82 Arg2RetWrapper(arg2ret.clone())
83 )?;
84 }
85 Ok(())
86 }
87}
88
89impl Display for DataFlowGraphWrapper {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 let graph = &self.0;
92 write!(
93 f,
94 "Graph statistics: {} nodes, {} edges.\n",
95 graph.nodes.len(),
96 graph.edges.len()
97 )?;
98 if graph.param_ret_deps.len() > 1 {
99 write!(f, "Return value dependencies: \n")?;
100 }
101 for (node_idx, deps) in graph.param_ret_deps.iter_enumerated() {
102 if node_idx.as_u32() > 0 {
103 if *deps {
104 write!(f, "Argument {:?} ---> Return value _0.\n", node_idx)?;
105 }
106 }
107 }
108
109 for (node_idx, node) in graph.nodes.iter_enumerated() {
110 let node_adj: Vec<Local> = node
111 .out_edges
112 .iter()
113 .map(|edge_idx| graph.edges[*edge_idx].dst)
114 .collect();
115 if !node_adj.is_empty() {
116 write!(f, "Node {:?} -> Node {:?}\n", node_idx, node_adj)?;
117 }
118 }
119 Ok(())
120 }
121}
122
123impl Debug for DataFlowGraphWrapper {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 writeln!(f, "Nodes:")?;
126 for node in &self.0.nodes {
127 writeln!(f, " {:?}", node)?;
128 }
129 writeln!(f, "Edges:")?;
130 for edge in &self.0.edges {
131 writeln!(f, " {:?}", edge)?;
132 }
133 Ok(())
134 }
135}
136
137impl Display for DataFlowGraphMapWrapper {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 writeln!(f, "===Print dataflow analysis resuts===")?;
140 for (def_id, dfg) in &self.0 {
141 let fn_name = get_fn_name_byid(def_id);
142 writeln!(
143 f,
144 "Function: {:?}\n{}",
145 fn_name,
146 DataFlowGraphWrapper(dfg.clone())
147 )?;
148 }
149 Ok(())
150 }
151}
152
153impl Debug for DataFlowGraphMapWrapper {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 for (def_id, dfg) in &self.0 {
156 writeln!(
157 f,
158 "DefId: {:?}\n{:?}",
159 def_id,
160 DataFlowGraphWrapper(dfg.clone())
161 )?;
162 }
163 Ok(())
164 }
165}