rapx/check/opt/
mod.rs

1pub mod checking;
2pub mod data_collection;
3pub mod iterator;
4pub mod memory_cloning;
5
6use rustc_middle::ty::TyCtxt;
7
8use crate::analysis::dataflow::{Graph, default::DataflowAnalyzer};
9use checking::bounds_checking::BoundsCheck;
10use checking::encoding_checking::EncodingCheck;
11use data_collection::initialization::InitializationCheck;
12use data_collection::reallocation::ReservationCheck;
13use data_collection::suboptimal::SuboptimalCheck;
14use memory_cloning::used_as_immutable::UsedAsImmutableCheck;
15
16use lazy_static::lazy_static;
17use rustc_span::symbol::Symbol;
18use std::sync::Mutex;
19
20lazy_static! {
21    pub static ref NO_STD: Mutex<bool> = Mutex::new(false);
22    pub static ref LEVEL: Mutex<usize> = Mutex::new(0);
23}
24
25pub struct Opt<'tcx> {
26    pub tcx: TyCtxt<'tcx>,
27    pub level: usize,
28}
29
30pub trait OptCheck {
31    fn new() -> Self;
32    fn check(&mut self, graph: &Graph, tcx: &TyCtxt);
33    fn report(&self, graph: &Graph);
34    fn cnt(&self) -> usize;
35}
36
37impl<'tcx> Opt<'tcx> {
38    pub fn new(tcx: TyCtxt<'tcx>, level: usize) -> Self {
39        Self { tcx, level }
40    }
41
42    fn has_crate(&self, name: &str) -> bool {
43        for num in self.tcx.crates(()) {
44            if self.tcx.crate_name(*num) == Symbol::intern(name) {
45                return true;
46            }
47        }
48        false
49    }
50
51    pub fn start(&mut self) {
52        let mut dataflow = DataflowAnalyzer::new(self.tcx, false);
53        dataflow.build_graphs();
54        {
55            let mut no_std = NO_STD.lock().unwrap();
56            *no_std = !self.has_crate("std");
57            let mut level = LEVEL.lock().unwrap();
58            *level = self.level;
59        }
60        if !self.has_crate("core") {
61            //core it self
62            return;
63        }
64
65        let mut statistics = vec![0 as usize; 6];
66
67        dataflow.graphs.iter().for_each(|(_, graph)| {
68            let mut bounds_check = BoundsCheck::new();
69            bounds_check.check(graph, &self.tcx);
70            statistics[0] += bounds_check.cnt();
71
72            if self.level > 0 {
73                bounds_check.report(graph);
74            }
75
76            let no_std = NO_STD.lock().unwrap();
77            if !*no_std {
78                let mut encoding_check = EncodingCheck::new();
79                encoding_check.check(graph, &self.tcx);
80                statistics[1] += encoding_check.cnt();
81
82                let mut suboptimal_check = SuboptimalCheck::new();
83                suboptimal_check.check(graph, &self.tcx);
84                statistics[2] += suboptimal_check.cnt();
85
86                let mut initialization_check = InitializationCheck::new();
87                initialization_check.check(graph, &self.tcx);
88                statistics[3] += initialization_check.cnt();
89
90                let mut reservation_check = ReservationCheck::new();
91                reservation_check.check(graph, &self.tcx);
92                statistics[4] += reservation_check.cnt();
93
94                let mut used_as_immutable_check = UsedAsImmutableCheck::new();
95                used_as_immutable_check.check(graph, &self.tcx);
96                statistics[5] += used_as_immutable_check.cnt();
97
98                if self.level > 0 {
99                    encoding_check.report(graph);
100                    suboptimal_check.report(graph);
101                    initialization_check.report(graph);
102                    reservation_check.report(graph);
103                    used_as_immutable_check.report(graph);
104                }
105            }
106        });
107
108        let bug_cnt: usize = statistics.iter().sum();
109        if bug_cnt > 0 {
110            rap_warn!("Potential optimizations detected.");
111            rap_info!(
112                "  Bounds Checking: {}, Encoding Checking: {}, Suboptimal: {}, Initialization: {}, Reallocation: {}, Cloning: {}",
113                statistics[0],
114                statistics[1],
115                statistics[2],
116                statistics[3],
117                statistics[4],
118                statistics[5],
119            );
120        }
121    }
122}