cubecl_opt/analyses/
base.rs

1use std::{any::Any, cell::RefCell, rc::Rc};
2
3use type_map::TypeMap;
4
5use crate::Optimizer;
6
7use super::{
8    dominance::{Dominators, PostDominators},
9    liveness::Liveness,
10    post_order::PostOrder,
11    uniformity::Uniformity,
12};
13
14/// An analysis used by optimization passes. Unlike optimization passes, analyses can have state
15/// and persist until they're invalidated.
16pub trait Analysis {
17    /// Perform the analysis for the current optimizer state and return the persistent analysis state
18    fn init(opt: &mut Optimizer) -> Self;
19}
20
21#[derive(Default, Clone, Debug)]
22pub struct AnalysisCache {
23    cache: Rc<RefCell<TypeMap>>,
24}
25
26impl AnalysisCache {
27    pub fn get<A: Analysis + Any>(&self, opt: &mut Optimizer) -> Rc<A> {
28        let analysis = self.cache.borrow().get::<Rc<A>>().cloned();
29        if let Some(analysis) = analysis {
30            analysis
31        } else {
32            let analysis = Rc::new(A::init(opt));
33            self.cache.borrow_mut().insert(analysis.clone());
34            analysis
35        }
36    }
37
38    pub fn try_get<A: Any>(&self) -> Option<Rc<A>> {
39        self.cache.borrow().get().cloned()
40    }
41
42    pub fn invalidate<A: Analysis + Any>(&self) {
43        self.cache.borrow_mut().remove::<Rc<A>>();
44    }
45}
46
47impl Optimizer {
48    /// Fetch an analysis if cached, or run it if not.
49    pub fn analysis<A: Analysis + Any>(&mut self) -> Rc<A> {
50        let analyses = self.analysis_cache.clone();
51        analyses.get(self)
52    }
53
54    /// Invalidate an analysis by removing it from the cache. The analysis is rerun when requested
55    /// again.
56    pub fn invalidate_analysis<A: Analysis + Any>(&self) {
57        self.analysis_cache.invalidate::<A>();
58    }
59
60    /// Invalidate all analyses that rely on the structure of the control flow graph.
61    pub fn invalidate_structure(&self) {
62        self.invalidate_analysis::<PostOrder>();
63        self.invalidate_analysis::<Dominators>();
64        self.invalidate_analysis::<PostDominators>();
65        self.invalidate_analysis::<Liveness>();
66        self.invalidate_analysis::<Uniformity>();
67    }
68}