Skip to content

Commit 5dadf39

Browse files
use ref count in the allocation pointer
1 parent aa46b9a commit 5dadf39

File tree

3 files changed

+108
-35
lines changed

3 files changed

+108
-35
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ repository.workspace = true
2020
resolver = "2"
2121

2222
[features]
23+
default = ["with-debug-utils"]
2324
with-cheatcode = []
2425
with-debug-utils = []
2526
with-mem-tracing = []

src/libfuncs/circuit.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ use crate::{
88
execution_result::{ADD_MOD_BUILTIN_SIZE, MUL_MOD_BUILTIN_SIZE, RANGE_CHECK96_BUILTIN_SIZE},
99
libfuncs::r#struct::build_struct_value,
1010
metadata::{
11-
drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta,
12-
runtime_bindings::RuntimeBindingsMeta, MetadataStorage,
11+
debug_utils::DebugUtils, drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, runtime_bindings::RuntimeBindingsMeta, MetadataStorage
1312
},
1413
native_panic,
15-
types::{circuit::build_u384_struct_type, TypeBuilder},
14+
types::{
15+
circuit::{build_u384_struct_type, calc_circuit_output_prefix_layout},
16+
TypeBuilder,
17+
},
1618
utils::{get_integer_layout, layout_repeat, ProgramRegistryExt},
1719
};
1820
use cairo_lang_sierra::{
@@ -363,13 +365,15 @@ fn build_eval<'ctx, 'this>(
363365
circuit_info.mul_offsets.len() * MUL_MOD_BUILTIN_SIZE,
364366
)?;
365367

366-
// Calculate capacity for array.
367368
let outputs_capacity = circuit_info.values.len();
368369
let u384_integer_layout = get_integer_layout(384);
369-
let outputs_layout = layout_repeat(&u384_integer_layout, outputs_capacity)?.0;
370-
let outputs_capacity_bytes = outputs_layout.pad_to_align().size();
370+
let outputs_prefix_layout = calc_circuit_output_prefix_layout();
371+
let outputs_layout = outputs_prefix_layout
372+
.extend(layout_repeat(&u384_integer_layout, outputs_capacity)?.0)?
373+
.0
374+
.pad_to_align();
371375
let outputs_capacity_bytes_value =
372-
ok_block.const_int(context, location, outputs_capacity_bytes, 64)?;
376+
ok_block.const_int(context, location, outputs_layout.size(), 64)?;
373377

374378
// Alloc memory for array.
375379
let ptr_ty = llvm::r#type::pointer(context, 0);
@@ -381,13 +385,19 @@ fn build_eval<'ctx, 'this>(
381385
location,
382386
)?)?;
383387

388+
// Insert initial reference count, equal to 1.
389+
let k1 = ok_block.const_int(context, location, 1, 32)?;
390+
ok_block.store(context, location, outputs_ptr, k1)?;
391+
384392
// Insert evaluated gates into the array.
385393
for (i, gate) in gates.into_iter().enumerate() {
386394
let value_ptr = ok_block.gep(
387395
context,
388396
location,
389397
outputs_ptr,
390-
&[GepIndex::Const(i as i32)],
398+
&[GepIndex::Const(
399+
outputs_prefix_layout.size() as i32 + i as i32,
400+
)],
391401
IntegerType::new(context, 384).into(),
392402
)?;
393403
ok_block.store(context, location, value_ptr, gate)?;
@@ -397,7 +407,6 @@ fn build_eval<'ctx, 'this>(
397407

398408
// Build output struct
399409
let outputs_type_id = &info.branch_signatures()[0].vars[2].ty;
400-
let ref_count = ok_block.const_int(context, location, 1, 8)?;
401410
let outputs = build_struct_value(
402411
context,
403412
registry,
@@ -406,7 +415,7 @@ fn build_eval<'ctx, 'this>(
406415
helper,
407416
metadata,
408417
outputs_type_id,
409-
&[ref_count, outputs_ptr, modulus_struct],
418+
&[outputs_ptr, modulus_struct],
410419
)?;
411420

412421
helper.br(ok_block, 0, &[add_mod, mul_mod, outputs], location)?;
@@ -920,23 +929,34 @@ fn build_get_output<'ctx, 'this>(
920929
location,
921930
outputs,
922931
llvm::r#type::pointer(context, 0),
923-
1,
932+
0,
924933
)?;
925934
let modulus_struct = entry.extract_value(
926935
context,
927936
location,
928937
outputs,
929938
build_u384_struct_type(context),
930-
2,
939+
1,
931940
)?;
932941

942+
let circuit_output_prefix_offset = calc_circuit_output_prefix_layout().size();
943+
metadata
944+
.get_mut::<DebugUtils>()
945+
.unwrap()
946+
.debug_print(context, helper.module, &entry, "AFTER OUTPUT", location)?;
933947
let output_integer_ptr = entry.gep(
934948
context,
935949
location,
936950
circuit_ptr,
937-
&[GepIndex::Const(output_idx as i32)],
951+
&[GepIndex::Const(
952+
circuit_output_prefix_offset as i32 + output_idx as i32,
953+
)],
938954
u384_type,
939955
)?;
956+
metadata
957+
.get_mut::<DebugUtils>()
958+
.unwrap()
959+
.debug_print(context, helper.module, &entry, "BEFORE OUTPUT", location)?;
940960
let output_integer = entry.load(context, location, output_integer_ptr, u384_type)?;
941961
let output_struct = u384_integer_to_struct(context, entry, location, output_integer)?;
942962

src/types/circuit.rs

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use super::WithSelf;
66
use crate::{
77
error::{Result, SierraAssertError},
88
metadata::{
9-
drop_overrides::DropOverridesMeta, dup_overrides::DupOverridesMeta,
10-
realloc_bindings::ReallocBindingsMeta, MetadataStorage,
9+
debug_utils::DebugUtils, drop_overrides::DropOverridesMeta,
10+
dup_overrides::DupOverridesMeta, realloc_bindings::ReallocBindingsMeta, MetadataStorage,
1111
},
1212
utils::{get_integer_layout, layout_repeat, ProgramRegistryExt},
1313
};
@@ -22,7 +22,7 @@ use cairo_lang_sierra::{
2222
};
2323
use melior::{
2424
dialect::{arith::CmpiPredicate, func, llvm, scf},
25-
helpers::{ArithBlockExt, BuiltinBlockExt, LlvmBlockExt},
25+
helpers::{ArithBlockExt, BuiltinBlockExt, GepIndex, LlvmBlockExt},
2626
ir::{r#type::IntegerType, Block, BlockLike, Location, Module, Region, Type, Value},
2727
Context,
2828
};
@@ -305,8 +305,6 @@ pub fn build_circuit_outputs<'ctx>(
305305
metadata: &mut MetadataStorage,
306306
info: WithSelf<InfoOnlyConcreteType>,
307307
) -> Result<Type<'ctx>> {
308-
let u8_ty = IntegerType::new(context, 8).into();
309-
310308
DupOverridesMeta::register_with(
311309
context,
312310
module,
@@ -318,15 +316,42 @@ pub fn build_circuit_outputs<'ctx>(
318316
let region = Region::new();
319317
let value_ty = registry.build_type(context, module, metadata, info.self_ty())?;
320318
let entry = region.append_block(Block::new(&[(value_ty, location)]));
321-
let k1 = entry.const_int(context, location, 1, 8)?;
319+
let k1 = entry.const_int(context, location, 1, 32)?;
322320

323321
let outputs = entry.arg(0)?;
324-
let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?;
322+
let gates_ptr = entry.extract_value(
323+
context,
324+
location,
325+
outputs,
326+
llvm::r#type::pointer(context, 0),
327+
0,
328+
)?;
329+
let ref_count_ptr = entry.gep(
330+
context,
331+
location,
332+
gates_ptr,
333+
&[GepIndex::Const(0)],
334+
IntegerType::new(context, 8).into(),
335+
)?;
336+
let ref_count = entry.load(
337+
context,
338+
location,
339+
ref_count_ptr,
340+
IntegerType::new(context, 32).into(),
341+
)?;
325342
let ref_count_inc = entry.addi(ref_count, k1, location)?;
326343

327-
let output_new = entry.insert_value(context, location, outputs, ref_count_inc, 0)?;
344+
metadata
345+
.get_mut::<DebugUtils>()
346+
.unwrap()
347+
.debug_print(context, module, &entry, "DUP", location)?;
348+
metadata
349+
.get_mut::<DebugUtils>()
350+
.unwrap()
351+
.print_i32(context, module, &entry, ref_count, location)?;
328352

329-
entry.append_operation(func::r#return(&[output_new, output_new], location));
353+
entry.store(context, location, ref_count_ptr, ref_count_inc)?;
354+
entry.append_operation(func::r#return(&[outputs, outputs], location));
330355

331356
Ok(Some(region))
332357
},
@@ -342,14 +367,43 @@ pub fn build_circuit_outputs<'ctx>(
342367
let region = Region::new();
343368
let value_ty = registry.build_type(context, module, metadata, info.self_ty())?;
344369
let entry = region.append_block(Block::new(&[(value_ty, location)]));
345-
let k1 = entry.const_int(context, location, 1, 8)?;
370+
let k1 = entry.const_int(context, location, 1, 32)?;
346371

347372
let outputs = entry.arg(0)?;
348-
let ref_count = entry.extract_value(context, location, outputs, u8_ty, 0)?;
373+
let gates_ptr = entry.extract_value(
374+
context,
375+
location,
376+
outputs,
377+
llvm::r#type::pointer(context, 0),
378+
0,
379+
)?;
380+
381+
let ref_count_ptr = entry.gep(
382+
context,
383+
location,
384+
gates_ptr,
385+
&[GepIndex::Const(0)],
386+
IntegerType::new(context, 8).into(),
387+
)?;
388+
let ref_count = entry.load(
389+
context,
390+
location,
391+
ref_count_ptr,
392+
IntegerType::new(context, 32).into(),
393+
)?;
349394

350395
// Check that the reference counting is different from 1. If it is equeal to 1, then it is shared.
351396
let is_shared = entry.cmpi(context, CmpiPredicate::Ne, ref_count, k1, location)?;
352397

398+
metadata
399+
.get_mut::<DebugUtils>()
400+
.unwrap()
401+
.debug_print(context, module, &entry, "DROP", location)?;
402+
metadata
403+
.get_mut::<DebugUtils>()
404+
.unwrap()
405+
.print_i32(context, module, &entry, ref_count, location)?;
406+
353407
entry.append_operation(scf::r#if(
354408
is_shared,
355409
&[],
@@ -359,8 +413,7 @@ pub fn build_circuit_outputs<'ctx>(
359413
let entry = region.append_block(Block::new(&[]));
360414
let ref_count_dec = entry.subi(ref_count, k1, location)?;
361415

362-
entry.insert_value(context, location, ref_count_dec, outputs, 0)?;
363-
416+
entry.store(context, location, ref_count_ptr, ref_count_dec)?;
364417
entry.append_operation(scf::r#yield(&[], location));
365418

366419
region
@@ -370,14 +423,6 @@ pub fn build_circuit_outputs<'ctx>(
370423
let region = Region::new();
371424
let entry = region.append_block(Block::new(&[]));
372425

373-
let gates_ptr = entry.extract_value(
374-
context,
375-
location,
376-
outputs,
377-
llvm::r#type::pointer(context, 0),
378-
1,
379-
)?;
380-
381426
entry
382427
.append_operation(ReallocBindingsMeta::free(context, gates_ptr, location)?);
383428
entry.append_operation(scf::r#yield(&[], location));
@@ -396,7 +441,6 @@ pub fn build_circuit_outputs<'ctx>(
396441
Ok(llvm::r#type::r#struct(
397442
context,
398443
&[
399-
u8_ty,
400444
llvm::r#type::pointer(context, 0),
401445
build_u384_struct_type(context),
402446
],
@@ -546,3 +590,11 @@ pub fn build_u384_struct_type(context: &Context) -> Type<'_> {
546590
false,
547591
)
548592
}
593+
594+
pub fn calc_circuit_output_prefix_layout() -> Layout {
595+
let u384_layout = get_integer_layout(384);
596+
get_integer_layout(32)
597+
.align_to(u384_layout.align())
598+
.expect("layout size rounded up to the next multiple of layout alignment should never be greater than ISIZE::MAX")
599+
.pad_to_align()
600+
}

0 commit comments

Comments
 (0)