cairo_lang_lowering/optimizations/
config.rs

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