cairo_lang_lowering/graph_algorithms/
feedback_set.rs1use cairo_lang_diagnostics::Maybe;
2use cairo_lang_filesystem::db::FilesGroup;
3use cairo_lang_filesystem::flag::Flag;
4use cairo_lang_filesystem::ids::{FlagId, FlagLongId};
5use cairo_lang_utils::graph_algos::feedback_set::calc_feedback_set;
6use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
7use salsa::Database;
8
9use super::concrete_function_node::ConcreteFunctionWithBodyNode;
10use crate::db::LoweringGroup;
11use crate::ids::ConcreteFunctionWithBodyId;
12use crate::{DependencyType, LoweringStage};
13
14#[salsa::tracked(returns(ref))]
16pub fn function_with_body_feedback_set<'db>(
17 db: &'db dyn Database,
18 function: ConcreteFunctionWithBodyId<'db>,
19 stage: LoweringStage,
20) -> Maybe<OrderedHashSet<ConcreteFunctionWithBodyId<'db>>> {
21 let r = db.lowered_scc_representative(function, DependencyType::Cost, stage);
22 function_with_body_feedback_set_of_representative(db, r.0, stage)
23}
24
25pub fn flag_add_withdraw_gas(db: &dyn Database) -> bool {
27 db.get_flag(FlagId::new(db, FlagLongId("add_withdraw_gas".into())))
28 .map(|flag| *flag == Flag::AddWithdrawGas(true))
29 .unwrap_or(true)
30}
31
32#[salsa::tracked]
34pub fn needs_withdraw_gas<'db>(
35 db: &'db dyn Database,
36 function: ConcreteFunctionWithBodyId<'db>,
37) -> Maybe<bool> {
38 Ok(flag_add_withdraw_gas(db)
39 && db
40 .function_with_body_feedback_set(function, LoweringStage::Monomorphized)?
41 .contains(&function))
42}
43
44#[salsa::tracked]
47fn function_with_body_feedback_set_of_representative<'db>(
48 db: &'db dyn Database,
49 function_id: ConcreteFunctionWithBodyId<'db>,
50 stage: LoweringStage,
51) -> Maybe<OrderedHashSet<ConcreteFunctionWithBodyId<'db>>> {
52 Ok(calc_feedback_set(
53 ConcreteFunctionWithBodyNode {
54 function_id,
55 db,
56 dependency_type: DependencyType::Cost,
57 stage,
58 }
59 .into(),
60 ))
61}