cairo_lang_lowering/optimizations/
config.rs1use 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
12const DEFAULT_INLINE_SMALL_FUNCTIONS_THRESHOLD: usize = 24;
16
17#[derive(Debug, Eq, PartialEq, Clone)]
19pub struct OptimizationConfig {
20 pub moveable_functions: Vec<String>,
22 pub inline_small_functions_threshold: usize,
25 pub inlining_strategy: InliningStrategy,
27 pub skip_const_folding: bool,
29}
30
31impl OptimizationConfig {
32 pub fn with_moveable_functions(mut self, moveable_functions: Vec<String>) -> Self {
34 self.moveable_functions = moveable_functions;
35 self
36 }
37 pub fn with_minimal_movable_functions(self) -> Self {
39 self.with_moveable_functions(vec!["felt252_sub".into()])
40 }
41 pub fn with_inline_small_functions_threshold(
43 mut self,
44 inline_small_functions_threshold: usize,
45 ) -> Self {
46 self.inline_small_functions_threshold = inline_small_functions_threshold;
47 self
48 }
49 pub fn with_inlining_strategy(mut self, inlining_strategy: InliningStrategy) -> Self {
51 self.inlining_strategy = inlining_strategy;
52 self
53 }
54 pub fn with_skip_const_folding(mut self, skip_const_folding: bool) -> Self {
56 self.skip_const_folding = skip_const_folding;
57 self
58 }
59}
60
61impl Default for OptimizationConfig {
62 fn default() -> Self {
63 Self {
64 moveable_functions: vec![],
65 inline_small_functions_threshold: DEFAULT_INLINE_SMALL_FUNCTIONS_THRESHOLD,
66 inlining_strategy: InliningStrategy::Default,
67 skip_const_folding: false,
68 }
69 }
70}
71
72pub fn priv_movable_function_ids(db: &dyn LoweringGroup) -> Arc<UnorderedHashSet<FunctionId>> {
73 let semantic_db: &dyn SemanticGroup = db.elongate();
74 let libfunc_by_name = |name: &String| {
75 let mut path_iter = name.split("::");
76
77 let mut module = db.core_module();
78
79 let mut next = path_iter.next();
80 while let Some(path_item) = next {
81 next = path_iter.next();
82 if next.is_some() {
83 module = corelib::get_submodule(semantic_db, module, path_item)
84 .unwrap_or_else(|| panic!("module not found: {}", path_item));
85 continue;
86 }
87
88 return FunctionLongId::Semantic(corelib::get_function_id(
89 semantic_db,
90 module,
91 path_item.into(),
92 vec![],
93 ))
94 .intern(db);
95 }
96
97 panic!("Got empty string as movable_function");
98 };
99
100 Arc::new(db.optimization_config().moveable_functions.iter().map(libfunc_by_name).collect())
101}