cairo_lang_lowering/inline/
statements_weights.rs1use cairo_lang_semantic::TypeId;
2use cairo_lang_utils::casts::IntoOrPanic;
3use salsa::Database;
4
5use crate::db::LoweringGroup;
6use crate::{BlockEnd, Lowered, Statement, VarUsage, VariableId};
7
8pub trait InlineWeight<'db> {
10 fn calling_weight(&self, lowered: &Lowered<'db>) -> isize;
12 fn statement_weight(&self, statement: &Statement<'db>) -> isize;
14 fn block_end_weight(&self, block_end: &BlockEnd<'db>) -> isize;
16 fn lowered_weight(&self, lowered: &Lowered<'db>) -> isize {
18 self.calling_weight(lowered)
19 + lowered
20 .blocks
21 .iter()
22 .map(|(_, block)| {
23 block
24 .statements
25 .iter()
26 .map(|statement| self.statement_weight(statement))
27 .sum::<isize>()
28 + self.block_end_weight(&block.end)
29 })
30 .sum::<isize>()
31 }
32}
33
34pub struct SimpleInlineWeight;
36impl<'db> InlineWeight<'db> for SimpleInlineWeight {
37 fn calling_weight(&self, _lowered: &Lowered<'db>) -> isize {
38 0
39 }
40
41 fn statement_weight(&self, _statement: &Statement<'db>) -> isize {
42 1
43 }
44
45 fn block_end_weight(&self, _block_end: &BlockEnd<'db>) -> isize {
46 1
47 }
48}
49
50pub struct ApproxCasmInlineWeight<'db> {
53 db: &'db dyn Database,
54 lowered: &'db Lowered<'db>,
55}
56impl<'db> ApproxCasmInlineWeight<'db> {
57 pub fn new(db: &'db dyn Database, lowered: &'db Lowered<'db>) -> Self {
59 Self { db, lowered }
60 }
61 fn tys_total_size(&self, tys: impl IntoIterator<Item = TypeId<'db>>) -> usize {
63 tys.into_iter().map(|ty| self.db.type_size(ty)).sum()
64 }
65 fn vars_size<'b, I: IntoIterator<Item = &'db VariableId>>(&self, vars: I) -> usize {
67 self.tys_total_size(vars.into_iter().map(|v| self.lowered.variables[*v].ty))
68 }
69 fn inputs_size<'b, I: IntoIterator<Item = &'db VarUsage<'db>>>(&self, vars: I) -> usize {
71 self.vars_size(vars.into_iter().map(|v| &v.var_id))
72 }
73}
74
75impl<'db> InlineWeight<'db> for ApproxCasmInlineWeight<'db> {
76 fn calling_weight(&self, _lowered: &Lowered<'db>) -> isize {
77 0
78 }
79 fn statement_weight(&self, statement: &Statement<'db>) -> isize {
80 match statement {
81 Statement::Call(statement_call) => self.inputs_size(&statement_call.inputs),
87 _ => 0,
88 }
89 .into_or_panic()
90 }
91
92 fn block_end_weight(&self, block_end: &BlockEnd<'db>) -> isize {
93 match block_end {
94 BlockEnd::Return(..) => 0,
96 BlockEnd::Goto(_, r) => self.vars_size(r.keys()),
99 BlockEnd::Match { info } => info.arms().len() + self.inputs_size(info.inputs()),
101 BlockEnd::Panic(_) | BlockEnd::NotSet => unreachable!(),
102 }
103 .into_or_panic()
104 }
105}