rapx/analysis/core/alias_analysis/
default.rs1pub mod alias;
2pub mod graph;
3pub mod mop;
4
5use super::{AAFact, AAResult, AliasAnalysis};
6use crate::{
7 analysis::{
8 utils::intrinsic_id::{
9 COPY_FROM, COPY_FROM_NONOVERLAPPING, COPY_TO, COPY_TO_NONOVERLAPPING,
10 },
11 Analysis,
12 },
13 rap_debug, rap_info, rap_trace,
14 utils::source::*,
15};
16use graph::MopGraph;
17use rustc_data_structures::fx::FxHashMap;
18use rustc_hir::def_id::DefId;
19use rustc_middle::ty::TyCtxt;
20use std::{collections::HashSet, convert::From};
21
22pub const VISIT_LIMIT: usize = 1000;
23
24pub struct DefaultAlias<'tcx> {
25 pub tcx: TyCtxt<'tcx>,
26 pub fn_map: FxHashMap<DefId, AAResult>,
27}
28
29impl<'tcx> Analysis for DefaultAlias<'tcx> {
30 fn name(&self) -> &'static str {
31 "Default alias analysis algorithm."
32 }
33
34 fn run(&mut self) {
35 rap_debug!("Start alias analysis.");
36 let mir_keys = self.tcx.mir_keys(());
37 for local_def_id in mir_keys {
38 self.query_mop(local_def_id.to_def_id());
39 }
40 for (fn_id, fn_alias) in &mut self.fn_map {
42 let fn_name = get_fn_name(self.tcx, *fn_id);
43 fn_alias.sort_alias_index();
44 if fn_alias.len() > 0 {
45 rap_info!("Alias found in {:?}: {}", fn_name, fn_alias);
46 }
47 }
48 self.handle_conor_cases();
49 }
50
51 fn reset(&mut self) {
52 todo!();
53 }
54}
55
56impl<'tcx, T> AliasAnalysis<T> for DefaultAlias<'tcx>
57where
58 T: From<AAResult> + Clone,
59{
60 fn get_fn_alias(&mut self, def_id: DefId) -> T {
61 self.fn_map
62 .get(&def_id)
63 .expect(&format!("Cannot find alias analysis result for {def_id:?}"))
64 .clone()
65 .into()
66 }
67
68 fn get_all_fn_alias(&mut self) -> FxHashMap<DefId, T> {
69 self.fn_map
70 .iter()
71 .map(|(k, v)| (*k, T::from(v.clone())))
72 .collect::<FxHashMap<DefId, T>>()
73 }
74}
75
76impl<'tcx> DefaultAlias<'tcx> {
77 pub fn new(tcx: TyCtxt<'tcx>) -> Self {
78 Self {
79 tcx,
80 fn_map: FxHashMap::default(),
81 }
82 }
83
84 fn handle_conor_cases(&mut self) {
85 let cases = [
86 COPY_FROM_NONOVERLAPPING,
87 COPY_TO_NONOVERLAPPING,
88 COPY_TO,
89 COPY_FROM,
90 ];
91 let alias = AAFact::new(1, 2);
92 for (key, value) in self.fn_map.iter_mut() {
93 if cases.contains(&key.index.as_usize()) {
94 value.alias_set.clear();
95 value.alias_set.insert(alias.clone());
96 }
97 }
98 }
99
100 fn query_mop(&mut self, def_id: DefId) {
101 let fn_name = get_fn_name(self.tcx, def_id);
102 rap_trace!("query_mop: {:?}", fn_name);
103 if let Some(_other) = self.tcx.hir_body_const_context(def_id.expect_local()) {
105 return;
106 }
107
108 if self.tcx.is_mir_available(def_id) {
109 let mut mop_graph = MopGraph::new(self.tcx, def_id);
110 mop_graph.solve_scc();
111 let mut recursion_set = HashSet::default();
112 mop_graph.check(0, &mut self.fn_map, &mut recursion_set);
113 if mop_graph.visit_times > VISIT_LIMIT {
114 rap_trace!("Over visited: {:?}", def_id);
115 }
116 self.fn_map.insert(def_id, mop_graph.ret_alias);
117 } else {
118 rap_trace!("mir is not available at {}", self.tcx.def_path_str(def_id));
119 }
120 }
121}