cairo_lang_lowering/graph_algorithms/
feedback_set.rs

1use cairo_lang_diagnostics::Maybe;
2use cairo_lang_filesystem::flag::Flag;
3use cairo_lang_filesystem::ids::FlagId;
4use cairo_lang_utils::graph_algos::feedback_set::calc_feedback_set;
5use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
6
7use super::concrete_function_node::ConcreteFunctionWithBodyNode;
8use crate::db::{ConcreteSCCRepresentative, LoweringGroup};
9use crate::ids::ConcreteFunctionWithBodyId;
10use crate::{DependencyType, LoweringStage};
11
12/// Query implementation of [crate::db::LoweringGroup::function_with_body_feedback_set].
13pub fn function_with_body_feedback_set(
14    db: &dyn LoweringGroup,
15    function: ConcreteFunctionWithBodyId,
16    stage: LoweringStage,
17) -> Maybe<OrderedHashSet<ConcreteFunctionWithBodyId>> {
18    let r = db.lowered_scc_representative(function, DependencyType::Cost, stage);
19    db.priv_function_with_body_feedback_set_of_representative(r, stage)
20}
21
22/// Returns the value of the `add_withdraw_gas` flag, or `true` if the flag is not set.
23pub fn flag_add_withdraw_gas(db: &dyn LoweringGroup) -> bool {
24    db.get_flag(FlagId::new(db, "add_withdraw_gas"))
25        .map(|flag| *flag == Flag::AddWithdrawGas(true))
26        .unwrap_or(true)
27}
28
29/// Query implementation of [crate::db::LoweringGroup::needs_withdraw_gas].
30pub fn needs_withdraw_gas(
31    db: &dyn LoweringGroup,
32    function: ConcreteFunctionWithBodyId,
33) -> Maybe<bool> {
34    Ok(flag_add_withdraw_gas(db)
35        && db
36            .function_with_body_feedback_set(function, LoweringStage::Monomorphized)?
37            .contains(&function))
38}
39
40/// Query implementation of
41/// [crate::db::LoweringGroup::priv_function_with_body_feedback_set_of_representative].
42pub fn priv_function_with_body_feedback_set_of_representative(
43    db: &dyn LoweringGroup,
44    function: ConcreteSCCRepresentative,
45    stage: LoweringStage,
46) -> Maybe<OrderedHashSet<ConcreteFunctionWithBodyId>> {
47    Ok(calc_feedback_set(
48        ConcreteFunctionWithBodyNode {
49            function_id: function.0,
50            db,
51            dependency_type: DependencyType::Cost,
52            stage,
53        }
54        .into(),
55    ))
56}