Skip to main content

cairo_lang_lowering/optimizations/
config.rs

1use std::sync::Arc;
2
3use cairo_lang_defs::ids::ExternFunctionId;
4use cairo_lang_semantic::helper::ModuleHelper;
5use cairo_lang_utils::unordered_hash_set::UnorderedHashSet;
6
7use crate::db::LoweringGroup;
8use crate::utils::InliningStrategy;
9
10/// A configuration struct that controls the behavior of the optimization passes.
11#[derive(Debug, Eq, PartialEq, Clone)]
12pub struct OptimizationConfig {
13    /// A list of functions that can be moved during the reorder_statements optimization.
14    pub moveable_functions: Vec<String>,
15    /// Determines whether inlining is disabled.
16    pub inlining_strategy: InliningStrategy,
17    /// Should const folding be skipped.
18    pub skip_const_folding: bool,
19}
20
21impl OptimizationConfig {
22    /// Sets the list of moveable functions.
23    pub fn with_moveable_functions(mut self, moveable_functions: Vec<String>) -> Self {
24        self.moveable_functions = moveable_functions;
25        self
26    }
27    /// Sets the list of moveable functions to a minimal set, useful for testing.
28    pub fn with_minimal_movable_functions(self) -> Self {
29        self.with_moveable_functions(vec!["felt252_sub".into()])
30    }
31    /// Sets the `inlining_strategy` flag.
32    pub fn with_inlining_strategy(mut self, inlining_strategy: InliningStrategy) -> Self {
33        self.inlining_strategy = inlining_strategy;
34        self
35    }
36    /// Sets the `skip_const_folding` flag.
37    pub fn with_skip_const_folding(mut self, skip_const_folding: bool) -> Self {
38        self.skip_const_folding = skip_const_folding;
39        self
40    }
41}
42
43impl Default for OptimizationConfig {
44    fn default() -> Self {
45        Self {
46            moveable_functions: vec![],
47            inlining_strategy: InliningStrategy::Default,
48            skip_const_folding: false,
49        }
50    }
51}
52
53pub fn priv_movable_function_ids(
54    db: &dyn LoweringGroup,
55) -> Arc<UnorderedHashSet<ExternFunctionId>> {
56    let libfunc_by_name = |name: &String| {
57        let mut path_iter = name.split("::");
58
59        let mut module = ModuleHelper::core(db);
60
61        let mut next = path_iter.next();
62        while let Some(path_item) = next {
63            next = path_iter.next();
64            if next.is_some() {
65                module = module.submodule(path_item);
66                continue;
67            }
68
69            return module.extern_function_id(path_item);
70        }
71
72        panic!("Got empty string as movable_function");
73    };
74
75    Arc::new(db.optimization_config().moveable_functions.iter().map(libfunc_by_name).collect())
76}