cairo_lang_lowering/optimizations/
strategy.rs1use cairo_lang_diagnostics::Maybe;
2use cairo_lang_utils::{Intern, LookupIntern, define_short_id};
3
4use super::dedup_blocks::dedup_blocks;
5use super::early_unsafe_panic::early_unsafe_panic;
6use super::gas_redeposit::gas_redeposit;
7use super::trim_unreachable::trim_unreachable;
8use super::validate::validate;
9use crate::Lowered;
10use crate::db::LoweringGroup;
11use crate::ids::ConcreteFunctionWithBodyId;
12use crate::implicits::lower_implicits;
13use crate::inline::apply_inlining;
14use crate::optimizations::branch_inversion::branch_inversion;
15use crate::optimizations::cancel_ops::cancel_ops;
16use crate::optimizations::const_folding::const_folding;
17use crate::optimizations::match_optimizer::optimize_matches;
18use crate::optimizations::remappings::optimize_remappings;
19use crate::optimizations::reorder_statements::reorder_statements;
20use crate::optimizations::return_optimization::return_optimization;
21use crate::optimizations::split_structs::split_structs;
22use crate::reorganize_blocks::reorganize_blocks;
23
24#[derive(Clone, Debug, Eq, Hash, PartialEq)]
26pub enum OptimizationPhase {
27 ApplyInlining {
28 enable_const_folding: bool,
29 },
30 BranchInversion,
31 CancelOps,
32 ConstFolding,
33 DedupBlocks,
34 EarlyUnsafePanic,
35 OptimizeMatches,
36 OptimizeRemappings,
37 ReorderStatements,
38 ReorganizeBlocks,
39 ReturnOptimization,
40 SplitStructs,
41 TrimUnreachable,
42 GasRedeposit,
43 LowerImplicits,
46 Validate,
48 SubStrategy {
51 strategy: OptimizationStrategyId,
53 iterations: usize,
55 },
56}
57
58impl OptimizationPhase {
59 pub fn apply(
63 self,
64 db: &dyn LoweringGroup,
65 function: ConcreteFunctionWithBodyId,
66 lowered: &mut Lowered,
67 ) -> Maybe<()> {
68 match self {
69 OptimizationPhase::ApplyInlining { enable_const_folding } => {
70 apply_inlining(db, function, lowered, enable_const_folding)?
71 }
72 OptimizationPhase::BranchInversion => branch_inversion(db, lowered),
73 OptimizationPhase::CancelOps => cancel_ops(lowered),
74 OptimizationPhase::ConstFolding => const_folding(db, function, lowered),
75 OptimizationPhase::EarlyUnsafePanic => early_unsafe_panic(db, lowered),
76 OptimizationPhase::DedupBlocks => dedup_blocks(lowered),
77 OptimizationPhase::OptimizeMatches => optimize_matches(lowered),
78 OptimizationPhase::OptimizeRemappings => optimize_remappings(lowered),
79 OptimizationPhase::ReorderStatements => reorder_statements(db, lowered),
80 OptimizationPhase::ReorganizeBlocks => reorganize_blocks(lowered),
81 OptimizationPhase::ReturnOptimization => return_optimization(db, lowered),
82 OptimizationPhase::SplitStructs => split_structs(lowered),
83 OptimizationPhase::TrimUnreachable => trim_unreachable(db, lowered),
84 OptimizationPhase::LowerImplicits => lower_implicits(db, function, lowered),
85 OptimizationPhase::GasRedeposit => gas_redeposit(db, function, lowered),
86 OptimizationPhase::Validate => validate(lowered)
87 .unwrap_or_else(|err| panic!("Failed validation: {:?}", err.to_message())),
88 OptimizationPhase::SubStrategy { strategy, iterations } => {
89 for _ in 1..iterations {
90 let before = lowered.clone();
91 strategy.apply_strategy(db, function, lowered)?;
92 if *lowered == before {
93 return Ok(());
94 }
95 }
96 strategy.apply_strategy(db, function, lowered)?
97 }
98 }
99 Ok(())
100 }
101}
102
103define_short_id!(
104 OptimizationStrategyId,
105 OptimizationStrategy,
106 LoweringGroup,
107 lookup_intern_strategy,
108 intern_strategy
109);
110
111#[derive(Clone, Debug, Eq, Hash, PartialEq)]
113pub struct OptimizationStrategy(pub Vec<OptimizationPhase>);
114
115impl OptimizationStrategyId {
116 pub fn apply_strategy(
120 self,
121 db: &dyn LoweringGroup,
122 function: ConcreteFunctionWithBodyId,
123 lowered: &mut Lowered,
124 ) -> Maybe<()> {
125 for phase in self.lookup_intern(db).0 {
126 phase.apply(db, function, lowered)?;
127 }
128
129 Ok(())
130 }
131}
132
133pub fn baseline_optimization_strategy(db: &dyn LoweringGroup) -> OptimizationStrategyId {
135 OptimizationStrategy(vec![
136 OptimizationPhase::ReorganizeBlocks,
138 OptimizationPhase::ApplyInlining { enable_const_folding: true },
139 OptimizationPhase::ReturnOptimization,
140 OptimizationPhase::ReorganizeBlocks,
141 OptimizationPhase::ReorderStatements,
142 OptimizationPhase::BranchInversion,
143 OptimizationPhase::CancelOps,
144 OptimizationPhase::ReorganizeBlocks,
146 OptimizationPhase::ConstFolding,
147 OptimizationPhase::OptimizeMatches,
148 OptimizationPhase::SplitStructs,
149 OptimizationPhase::ReorganizeBlocks,
150 OptimizationPhase::ReorderStatements,
151 OptimizationPhase::OptimizeMatches,
152 OptimizationPhase::ReorganizeBlocks,
153 OptimizationPhase::CancelOps,
154 OptimizationPhase::ReorganizeBlocks,
155 OptimizationPhase::DedupBlocks,
156 OptimizationPhase::ReturnOptimization,
158 OptimizationPhase::ReorderStatements,
159 OptimizationPhase::ReorganizeBlocks,
160 ])
161 .intern(db)
162}
163
164pub fn final_optimization_strategy(db: &dyn LoweringGroup) -> OptimizationStrategyId {
166 OptimizationStrategy(vec![
167 OptimizationPhase::GasRedeposit,
168 OptimizationPhase::EarlyUnsafePanic,
169 OptimizationPhase::TrimUnreachable,
172 OptimizationPhase::LowerImplicits,
173 OptimizationPhase::ReorganizeBlocks,
174 ])
175 .intern(db)
176}