Skip to content

Commit

Permalink
Added caching for basic corelib defs in the same structure.
Browse files Browse the repository at this point in the history
commit-id:341919b2
  • Loading branch information
orizi committed Jan 19, 2025
1 parent 9351827 commit 4e2ac87
Show file tree
Hide file tree
Showing 25 changed files with 468 additions and 416 deletions.
7 changes: 4 additions & 3 deletions crates/cairo-lang-executable/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,15 @@ impl AnalyzerPlugin for RawExecutableAnalyzer {
let Ok(free_functions) = db.module_free_functions(module_id) else {
return diagnostics;
};
let info = db.defs_info();
for (id, item) in free_functions.iter() {
if !item.has_attr(syntax_db, EXECUTABLE_RAW_ATTR) {
continue;
}
let Ok(signature) = db.free_function_signature(*id) else {
continue;
};
if signature.return_type != corelib::unit_ty(db) {
if signature.return_type != info.unit_ty {
diagnostics.push(PluginDiagnostic::error(
&signature.stable_ptr.lookup(syntax_db).ret_ty(syntax_db),
"Invalid return type for `#[executable_raw]` function, expected `()`."
Expand All @@ -171,7 +172,7 @@ impl AnalyzerPlugin for RawExecutableAnalyzer {
};
if input.ty
!= corelib::get_core_ty_by_name(db, "Span".into(), vec![GenericArgumentId::Type(
db.core_felt252_ty(),
info.felt252_ty,
)])
{
diagnostics.push(PluginDiagnostic::error(
Expand All @@ -189,7 +190,7 @@ impl AnalyzerPlugin for RawExecutableAnalyzer {
.to_string(),
));
}
if output.ty != corelib::core_array_felt252_ty(db) {
if output.ty != info.array_felt252_ty {
diagnostics.push(PluginDiagnostic::error(
output.stable_ptr.untyped(),
"Invalid second param type for `#[executable_raw]` function, expected \
Expand Down
42 changes: 18 additions & 24 deletions crates/cairo-lang-lowering/src/add_withdraw_gas/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use cairo_lang_diagnostics::Maybe;
use cairo_lang_semantic::corelib::{
core_array_felt252_ty, core_module, core_submodule, get_function_id, get_ty_by_name,
option_none_variant, option_some_variant, unit_ty,
core_module, get_function_id, get_ty_by_name, option_none_variant, option_some_variant,
};
use cairo_lang_semantic::items::constant::ConstValue;
use cairo_lang_semantic::{GenericArgumentId, MatchArmSelector, TypeLongId};
Expand Down Expand Up @@ -41,6 +40,7 @@ fn add_withdraw_gas_to_function(
let location = LocationId::from_stable_location(db, function.stable_location(db)?)
.with_auto_generation_note(db, "withdraw_gas");
let panic_block = create_panic_block(db, function, lowered, location)?;
let info = db.defs_info();

let old_root_block = lowered.blocks.root_block()?.clone();
let old_root_new_id = lowered.blocks.push(old_root_block);
Expand All @@ -49,27 +49,21 @@ fn add_withdraw_gas_to_function(
statements: vec![],
end: FlatBlockEnd::Match {
info: MatchInfo::Extern(MatchExternInfo {
function: get_function_id(
db.upcast(),
core_submodule(db.upcast(), "gas"),
"withdraw_gas".into(),
vec![],
)
.lowered(db),
function: info.withdraw_gas_fn.lowered(db),
inputs: vec![],
arms: vec![
MatchArm {
arm_selector: MatchArmSelector::VariantId(option_some_variant(
db.upcast(),
unit_ty(db.upcast()),
info.unit_ty,
)),
block_id: old_root_new_id,
var_ids: vec![],
},
MatchArm {
arm_selector: MatchArmSelector::VariantId(option_none_variant(
db.upcast(),
unit_ty(db.upcast()),
info.unit_ty,
)),
block_id: panic_block_id,
var_ids: vec![],
Expand Down Expand Up @@ -97,33 +91,30 @@ fn create_panic_block(
function.function_with_body_id(db).base_semantic_function(db),
lowered.variables.clone(),
)?;
let new_array_var =
variables.new_var(VarRequest { ty: core_array_felt252_ty(db.upcast()), location });
let out_of_gas_err_var = variables.new_var(VarRequest { ty: db.core_felt252_ty(), location });
let info = db.defs_info();
let new_array_var = variables.new_var(VarRequest { ty: info.array_felt252_ty, location });
let out_of_gas_err_var = variables.new_var(VarRequest { ty: info.felt252_ty, location });
let panic_instance_var = variables.new_var(VarRequest {
ty: get_ty_by_name(db.upcast(), core_module(db.upcast()), "Panic".into(), vec![]),
location,
});
let panic_data_var =
variables.new_var(VarRequest { ty: core_array_felt252_ty(db.upcast()), location });
let panic_data_var = variables.new_var(VarRequest { ty: info.array_felt252_ty, location });
let err_data_var = variables.new_var(VarRequest {
ty: TypeLongId::Tuple(vec![variables[panic_instance_var].ty, variables[panic_data_var].ty])
.intern(db),
location,
});
lowered.variables = variables.variables;

let array_module = core_submodule(db.upcast(), "array");

let add_location = |var_id| VarUsage { var_id, location };

// The block consists of creating a new array, appending 'Out of gas' to it and panic with this
// array as panic data.
Ok(FlatBlock {
statements: vec![
Statement::Call(StatementCall {
function: get_function_id(db.upcast(), array_module, "array_new".into(), vec![
GenericArgumentId::Type(db.core_felt252_ty()),
function: get_function_id(db.upcast(), info.array_mod, "array_new".into(), vec![
GenericArgumentId::Type(info.felt252_ty),
])
.lowered(db),
inputs: vec![],
Expand All @@ -134,14 +125,17 @@ fn create_panic_block(
Statement::Const(StatementConst {
value: ConstValue::Int(
BigInt::from_bytes_be(Sign::Plus, "Out of gas".as_bytes()),
db.core_felt252_ty(),
info.felt252_ty,
),
output: out_of_gas_err_var,
}),
Statement::Call(StatementCall {
function: get_function_id(db.upcast(), array_module, "array_append".into(), vec![
GenericArgumentId::Type(db.core_felt252_ty()),
])
function: get_function_id(
db.upcast(),
info.array_mod,
"array_append".into(),
vec![GenericArgumentId::Type(info.felt252_ty)],
)
.lowered(db),
inputs: vec![new_array_var, out_of_gas_err_var]
.into_iter()
Expand Down
5 changes: 3 additions & 2 deletions crates/cairo-lang-lowering/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe};
use cairo_lang_filesystem::ids::FileId;
use cairo_lang_semantic::db::SemanticGroup;
use cairo_lang_semantic::items::enm::SemanticEnumEx;
use cairo_lang_semantic::{self as semantic, ConcreteTypeId, TypeId, TypeLongId, corelib};
use cairo_lang_semantic::{self as semantic, ConcreteTypeId, TypeId, TypeLongId};
use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
use cairo_lang_utils::unordered_hash_set::UnorderedHashSet;
Expand Down Expand Up @@ -492,7 +492,8 @@ pub(crate) fn get_direct_callees(
if lowered_function.blocks.is_empty() {
return direct_callees;
}
let withdraw_gas_fns = corelib::core_withdraw_gas_fns(db.upcast())
let info = db.defs_info();
let withdraw_gas_fns = [info.withdraw_gas_fn, info.withdraw_gas_all_fn]
.map(|id| FunctionLongId::Semantic(id).intern(db));
let mut visited = vec![false; lowered_function.blocks.len()];
let mut stack = vec![BlockId(0)];
Expand Down
5 changes: 3 additions & 2 deletions crates/cairo-lang-lowering/src/destructs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use cairo_lang_defs::ids::LanguageElementId;
use cairo_lang_semantic as semantic;
use cairo_lang_semantic::ConcreteFunction;
use cairo_lang_semantic::corelib::{core_module, get_ty_by_name, unit_ty};
use cairo_lang_semantic::corelib::{core_module, get_ty_by_name};
use cairo_lang_semantic::items::functions::{GenericFunctionId, ImplGenericFunctionId};
use cairo_lang_semantic::items::imp::ImplId;
use cairo_lang_utils::{Intern, LookupIntern, extract_matches};
Expand Down Expand Up @@ -311,6 +311,7 @@ pub fn add_destructs(
lowered.variables.clone(),
)
.unwrap();
let unit_ty = db.defs_info_ex().unit_ty;

let plain_trait_function = destruct_trait_fn(db.upcast());
let panic_trait_function = panic_destruct_trait_fn(db.upcast());
Expand Down Expand Up @@ -355,7 +356,7 @@ pub fn add_destructs(
let mut last_panic_var = first_panic_var;

for destruction in destructions {
let output_var = variables.new_var(VarRequest { ty: unit_ty(db.upcast()), location });
let output_var = variables.new_var(VarRequest { ty: unit_ty, location });

match destruction {
DestructionEntry::Plain(plain_destruct) => {
Expand Down
5 changes: 2 additions & 3 deletions crates/cairo-lang-lowering/src/implicits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,14 @@ fn block_body_implicits(
)
})
.clone();
let require_implicits_libfunc_id =
semantic::corelib::internal_require_implicit(ctx.db.upcast());
let require_implicits_id = ctx.db.defs_info().require_implicit_fn;
let mut remove = vec![];
for (i, statement) in ctx.lowered.blocks[block_id].statements.iter_mut().enumerate() {
if let Statement::Call(stmt) = statement {
if matches!(
stmt.function.lookup_intern(ctx.db),
FunctionLongId::Semantic(func_id)
if func_id.get_concrete(ctx.db.upcast()).generic_function == require_implicits_libfunc_id
if func_id.get_concrete(ctx.db.upcast()).generic_function == require_implicits_id
) {
remove.push(i);
continue;
Expand Down
10 changes: 10 additions & 0 deletions crates/cairo-lang-lowering/src/lower/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::Arc;

use cairo_lang_defs::ids::{LanguageElementId, ModuleFileId};
use cairo_lang_diagnostics::{DiagnosticAdded, Maybe};
use cairo_lang_semantic::corelib::DefsInfoEx;
use cairo_lang_semantic::expr::fmt::ExprFormatter;
use cairo_lang_semantic::items::enm::SemanticEnumEx;
use cairo_lang_semantic::items::imp::ImplLookupContext;
Expand Down Expand Up @@ -103,6 +104,7 @@ pub struct EncapsulatingLoweringContext<'db> {
pub usages: Usages,
/// Lowerings of generated functions.
pub lowerings: OrderedHashMap<GeneratedFunctionKey, FlatLowered>,
pub base_info: Arc<DefsInfoEx>,
}
impl<'db> EncapsulatingLoweringContext<'db> {
pub fn new(
Expand All @@ -119,9 +121,17 @@ impl<'db> EncapsulatingLoweringContext<'db> {
expr_formatter: ExprFormatter { db: db.upcast(), function_id: semantic_function_id },
usages,
lowerings: Default::default(),
base_info: db.defs_info_ex(),
})
}
}
impl Deref for EncapsulatingLoweringContext<'_> {
type Target = DefsInfoEx;

fn deref(&self) -> &Self::Target {
&self.base_info
}
}

pub struct LoweringContext<'a, 'db> {
pub encapsulating_ctx: Option<&'a mut EncapsulatingLoweringContext<'db>>,
Expand Down
31 changes: 9 additions & 22 deletions crates/cairo-lang-lowering/src/lower/logical_op.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use cairo_lang_semantic as semantic;
use cairo_lang_semantic::corelib;
use cairo_lang_syntax::node::TypedStablePtr;
use semantic::MatchArmSelector;

Expand All @@ -17,9 +16,7 @@ pub fn create_bool(
variant: semantic::ConcreteVariant,
location: LocationId,
) -> VarUsage {
let semantic_db = ctx.db.upcast();

let unit = StructConstruct { inputs: vec![], ty: corelib::unit_ty(semantic_db), location }
let unit = StructConstruct { inputs: vec![], ty: ctx.unit_ty, location }
.add(ctx, &mut builder.statements);

generators::EnumConstruct { input: unit, variant, location }.add(ctx, &mut builder.statements)
Expand All @@ -33,9 +30,7 @@ pub fn lower_logical_op(
) -> LoweringResult<LoweredExpr> {
let location = ctx.get_location(expr.stable_ptr.untyped());

let semantic_db = ctx.db.upcast();

let unit_ty = corelib::unit_ty(semantic_db);
let unit_ty = ctx.unit_ty;
let lhs = lower_expr_to_var_usage(ctx, builder, expr.lhs)?;

let mut subscope_lhs_true = create_subscope_with_bound_refs(ctx, builder);
Expand All @@ -49,24 +44,16 @@ pub fn lower_logical_op(
let sealed_block_lhs_true = subscope_lhs_true.goto_callsite(Some(rhs_var));
let mut subscope_lhs_false = create_subscope_with_bound_refs(ctx, builder);
let lhs_false_block_id = subscope_lhs_false.block_id;
let false_var = create_bool(
ctx,
&mut subscope_lhs_false,
corelib::false_variant(semantic_db),
location,
);
let false_var =
create_bool(ctx, &mut subscope_lhs_false, ctx.false_variant.clone(), location);
let sealed_block_lhs_false = subscope_lhs_false.goto_callsite(Some(false_var));
(sealed_block_lhs_true, lhs_false_block_id, sealed_block_lhs_false)
}

// Lowers `lhs || rhs` to `if lhs { true } else { rhs }`.
semantic::LogicalOperator::OrOr => {
let true_var = create_bool(
ctx,
&mut subscope_lhs_true,
corelib::true_variant(semantic_db),
location,
);
let true_var =
create_bool(ctx, &mut subscope_lhs_true, ctx.true_variant.clone(), location);
let sealed_block_lhs_true = subscope_lhs_true.goto_callsite(Some(true_var));
let mut subscope_lhs_false = create_subscope_with_bound_refs(ctx, builder);
let lhs_false_block_id = subscope_lhs_false.block_id;
Expand All @@ -78,16 +65,16 @@ pub fn lower_logical_op(
};

let match_info = MatchInfo::Enum(MatchEnumInfo {
concrete_enum_id: corelib::core_bool_enum(semantic_db),
concrete_enum_id: ctx.bool_enum,
input: lhs,
arms: vec![
MatchArm {
arm_selector: MatchArmSelector::VariantId(corelib::false_variant(semantic_db)),
arm_selector: MatchArmSelector::VariantId(ctx.false_variant.clone()),
block_id: lhs_false_block_id,
var_ids: vec![ctx.new_var(VarRequest { ty: unit_ty, location })],
},
MatchArm {
arm_selector: MatchArmSelector::VariantId(corelib::true_variant(semantic_db)),
arm_selector: MatchArmSelector::VariantId(ctx.true_variant.clone()),
block_id: lhs_true_block_id,
var_ids: vec![ctx.new_var(VarRequest { ty: unit_ty, location })],
},
Expand Down
11 changes: 5 additions & 6 deletions crates/cairo-lang-lowering/src/lower/lower_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ pub fn lower_expr_if_bool(

// The condition cannot be unit.
let condition = lower_expr_to_var_usage(ctx, builder, condition)?;
let semantic_db = ctx.db.upcast();
let unit_ty = corelib::unit_ty(semantic_db);
let unit_ty = ctx.unit_ty;
let if_location = ctx.get_location(expr.stable_ptr.untyped());

// Main block.
Expand All @@ -74,16 +73,16 @@ pub fn lower_expr_if_bool(
.map_err(LoweringFlowError::Failed)?;

let match_info = MatchInfo::Enum(MatchEnumInfo {
concrete_enum_id: corelib::core_bool_enum(semantic_db),
concrete_enum_id: ctx.bool_enum,
input: condition,
arms: vec![
MatchArm {
arm_selector: MatchArmSelector::VariantId(corelib::false_variant(semantic_db)),
arm_selector: MatchArmSelector::VariantId(ctx.false_variant.clone()),
block_id: block_else_id,
var_ids: vec![else_block_input_var_id],
},
MatchArm {
arm_selector: MatchArmSelector::VariantId(corelib::true_variant(semantic_db)),
arm_selector: MatchArmSelector::VariantId(ctx.true_variant.clone()),
block_id: block_main_id,
var_ids: vec![main_block_var_id],
},
Expand All @@ -108,7 +107,7 @@ pub fn lower_expr_if_let(
let matched_expr = ctx.function_body.arenas.exprs[matched_expr].clone();
let ty = matched_expr.ty();

if ty == ctx.db.core_felt252_ty()
if ty == ctx.felt252_ty
|| corelib::get_convert_to_felt252_libfunc_name_by_type(ctx.db.upcast(), ty).is_some()
{
return Err(LoweringFlowError::Failed(ctx.diagnostics.report(
Expand Down
Loading

0 comments on commit 4e2ac87

Please sign in to comment.