diff --git a/src/libfuncs/array.rs b/src/libfuncs/array.rs index 5d8e38edd..47d3e53f7 100644 --- a/src/libfuncs/array.rs +++ b/src/libfuncs/array.rs @@ -10,7 +10,7 @@ use crate::{ drop_overrides::DropOverridesMeta, realloc_bindings::ReallocBindingsMeta, MetadataStorage, }, types::TypeBuilder, - utils::{BlockExt, ProgramRegistryExt}, + utils::{BlockExt, GepIndex, ProgramRegistryExt}, }; use cairo_lang_sierra::{ extensions::{ @@ -479,14 +479,13 @@ pub fn build_get<'ctx, 'this>( let elem_offset = valid_block.append_op_result(arith::muli(elem_stride, index, location))?; - let elem_ptr = valid_block.append_op_result(llvm::get_element_ptr_dynamic( + let elem_ptr = valid_block.gep( context, + location, ptr, - &[elem_offset], + &[GepIndex::Value(elem_offset)], IntegerType::new(context, 8).into(), - llvm::r#type::pointer(context, 0), - location, - ))?; + )?; let elem_size = valid_block.const_int(context, location, elem_layout.size(), 64)?; diff --git a/src/libfuncs/starknet.rs b/src/libfuncs/starknet.rs index c4ca0552d..590014113 100644 --- a/src/libfuncs/starknet.rs +++ b/src/libfuncs/starknet.rs @@ -6,7 +6,7 @@ use crate::{ ffi::get_struct_field_type_at, metadata::{drop_overrides::DropOverridesMeta, MetadataStorage}, starknet::handler::StarknetSyscallHandlerCallbacks, - utils::{get_integer_layout, BlockExt, ProgramRegistryExt, PRIME}, + utils::{get_integer_layout, BlockExt, GepIndex, ProgramRegistryExt, PRIME}, }; use cairo_lang_sierra::{ extensions::{ @@ -21,13 +21,11 @@ use cairo_lang_sierra::{ use melior::{ dialect::{ arith::{self, CmpiPredicate}, - llvm::{self, LoadStoreOptions}, + llvm::{self, r#type::pointer, LoadStoreOptions}, }, ir::{ - attribute::{DenseI32ArrayAttribute, DenseI64ArrayAttribute, TypeAttribute}, - operation::OperationBuilder, - r#type::IntegerType, - Attribute, Block, Identifier, Location, Type, ValueLike, + attribute::DenseI64ArrayAttribute, operation::OperationBuilder, r#type::IntegerType, + Attribute, Block, Location, Type, ValueLike, }, Context, }; @@ -266,17 +264,15 @@ pub fn build_call_contract<'ctx, 'this>( )?; // Extract function pointer. - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::CALL_CONTRACT.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::CALL_CONTRACT.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -318,48 +314,26 @@ pub fn build_call_contract<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -609,17 +583,15 @@ pub fn build_storage_read<'ctx, 'this>( )?; // Extract function pointer. - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::STORAGE_READ.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::STORAGE_READ.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -660,48 +632,26 @@ pub fn build_storage_read<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -804,17 +754,15 @@ pub fn build_storage_write<'ctx, 'this>( let value_arg_ptr = helper.init_block().alloca_int(context, location, 252)?; entry.store(context, location, value_arg_ptr, entry.argument(4)?.into())?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::STORAGE_WRITE.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::STORAGE_WRITE.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -856,48 +804,26 @@ pub fn build_storage_write<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -1185,17 +1111,15 @@ pub fn build_emit_event<'ctx, 'this>( )?; entry.store(context, location, data_arg_ptr, entry.argument(3)?.into())?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::EMIT_EVENT.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::EMIT_EVENT.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -1236,48 +1160,26 @@ pub fn build_emit_event<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -1365,17 +1267,15 @@ pub fn build_get_block_hash<'ctx, 'this>( )); // Extract function pointer. - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::GET_BLOCK_HASH.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::GET_BLOCK_HASH.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -1415,48 +1315,26 @@ pub fn build_get_block_hash<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -1543,17 +1421,15 @@ pub fn build_get_execution_info<'ctx, 'this>( )?; // Extract function pointer. - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::GET_EXECUTION_INFO.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::GET_EXECUTION_INFO.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -1587,48 +1463,26 @@ pub fn build_get_execution_info<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -1715,17 +1569,15 @@ pub fn build_get_execution_info_v2<'ctx, 'this>( )?; // Extract function pointer. - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::GET_EXECUTION_INFOV2.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::GET_EXECUTION_INFOV2.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -1759,48 +1611,26 @@ pub fn build_get_execution_info_v2<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -1974,17 +1804,15 @@ pub fn build_deploy<'ctx, 'this>( entry.argument(4)?.into(), )?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::DEPLOY.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::DEPLOY.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -2036,48 +1864,26 @@ pub fn build_deploy<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -2198,17 +2004,15 @@ pub fn build_keccak<'ctx, 'this>( )?; entry.store(context, location, input_arg_ptr, entry.argument(2)?.into())?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::KECCAK.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::KECCAK.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -2242,52 +2046,29 @@ pub fn build_keccak<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; - let remaining_gas = entry.load( context, location, @@ -2414,17 +2195,15 @@ pub fn build_library_call<'ctx, 'this>( entry.argument(4)?.into(), )?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::LIBRARY_CALL.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::LIBRARY_CALL.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -2466,48 +2245,26 @@ pub fn build_library_call<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -2606,17 +2363,15 @@ pub fn build_replace_class<'ctx, 'this>( entry.argument(2)?.into(), )?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::REPLACE_CLASS.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::REPLACE_CLASS.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -2650,48 +2405,26 @@ pub fn build_replace_class<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -2813,17 +2546,15 @@ pub fn build_send_message_to_l1<'ctx, 'this>( entry.argument(3)?.into(), )?; - let fn_ptr = entry.append_op_result(llvm::get_element_ptr( + let fn_ptr = entry.gep( context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::SEND_MESSAGE_TO_L1.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), location, - ))?; + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::SEND_MESSAGE_TO_L1.try_into()?, + )], + pointer(context, 0), + )?; let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( @@ -2864,48 +2595,26 @@ pub fn build_send_message_to_l1<'ctx, 'this>( )?; let payload_ok = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry.append_op_result( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), )?; entry.load(context, location, ptr, variant_tys[1].0)? }; @@ -3039,30 +2748,16 @@ pub fn build_sha256_process_block_syscall<'ctx, 'this>( let sha256_prev_state_ptr = entry.argument(2)?.into(); let sha256_current_block_ptr = entry.argument(3)?.into(); - let fn_ptr = entry - .append_operation(llvm::get_element_ptr( - context, - entry.argument(1)?.into(), - DenseI32ArrayAttribute::new( - context, - &[StarknetSyscallHandlerCallbacks::<()>::SHA256_PROCESS_BLOCK.try_into()?], - ), - llvm::r#type::pointer(context, 0), - llvm::r#type::pointer(context, 0), - location, - )) - .result(0)? - .into(); - let fn_ptr = entry - .append_operation(llvm::load( - context, - fn_ptr, - llvm::r#type::pointer(context, 0), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + let fn_ptr = entry.gep( + context, + location, + entry.argument(1)?.into(), + &[GepIndex::Const( + StarknetSyscallHandlerCallbacks::<()>::SHA256_PROCESS_BLOCK.try_into()?, + )], + pointer(context, 0), + )?; + let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?; entry.append_operation( OperationBuilder::new("llvm.call", location) diff --git a/src/libfuncs/starknet/secp256.rs b/src/libfuncs/starknet/secp256.rs index d06c35094..d13560523 100644 --- a/src/libfuncs/starknet/secp256.rs +++ b/src/libfuncs/starknet/secp256.rs @@ -3,7 +3,7 @@ use crate::{ libfuncs::LibfuncHelper, metadata::MetadataStorage, starknet::handler::StarknetSyscallHandlerCallbacks, - utils::{get_integer_layout, BlockExt, ProgramRegistryExt}, + utils::{get_integer_layout, BlockExt, GepIndex, ProgramRegistryExt}, }; use cairo_lang_sierra::{ extensions::{ @@ -15,17 +15,10 @@ use cairo_lang_sierra::{ program_registry::ProgramRegistry, }; use melior::{ - dialect::{ - arith, - llvm::{self, LoadStoreOptions}, - }, + dialect::llvm::{self, LoadStoreOptions}, ir::{ - attribute::{ - DenseI32ArrayAttribute, DenseI64ArrayAttribute, IntegerAttribute, TypeAttribute, - }, - operation::OperationBuilder, - r#type::IntegerType, - Block, Identifier, Location, + attribute::DenseI32ArrayAttribute, operation::OperationBuilder, r#type::IntegerType, Block, + Location, }, Context, }; @@ -113,50 +106,22 @@ pub fn build_k1_new<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -250,109 +215,61 @@ pub fn build_k1_new<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -401,50 +318,22 @@ pub fn build_k1_add<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -539,118 +428,61 @@ pub fn build_k1_add<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -699,50 +531,22 @@ pub fn build_k1_mul<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -837,118 +641,61 @@ pub fn build_k1_mul<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -997,50 +744,22 @@ pub fn build_k1_get_point_from_x<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -1126,110 +845,62 @@ pub fn build_k1_get_point_from_x<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; + + // Load the two variants of the result returned by the syscall handler. + let payload_ok = { + let ptr = entry.gep( + context, + location, result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( - context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); - - // Load the two variants of the result returned by the syscall handler. - let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -1307,50 +978,22 @@ pub fn build_k1_get_xy<'ctx, 'this>( ) }; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -1418,155 +1061,93 @@ pub fn build_k1_get_xy<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; + + let payload_ok = { + let ptr = entry.gep( + context, + location, result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + + let value = entry.load(context, location, ptr, variant_tys[0].0)?; + + let x_value = entry.extract_value( + context, + location, + value, llvm::r#type::r#struct( context, &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), + IntegerType::new(context, 128).into(), + IntegerType::new(context, 128).into(), ], false, ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + 0, + )?; + let y_value = entry.extract_value( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), location, - )) - .result(0)? - .into(); - - let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - let value = entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - - let x_value = entry - .append_operation(llvm::extract_value( - context, - value, - DenseI64ArrayAttribute::new(context, &[0]), - llvm::r#type::r#struct( - context, - &[ - IntegerType::new(context, 128).into(), - IntegerType::new(context, 128).into(), - ], - false, - ), - location, - )) - .result(0)? - .into(); - let y_value = entry - .append_operation(llvm::extract_value( + value, + llvm::r#type::r#struct( context, - value, - DenseI64ArrayAttribute::new(context, &[1]), - llvm::r#type::r#struct( - context, - &[ - IntegerType::new(context, 128).into(), - IntegerType::new(context, 128).into(), - ], - false, - ), - location, - )) - .result(0)? - .into(); + &[ + IntegerType::new(context, 128).into(), + IntegerType::new(context, 128).into(), + ], + false, + ), + 1, + )?; (x_value, y_value) }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -1620,50 +1201,22 @@ pub fn build_r1_new<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -1757,110 +1310,62 @@ pub fn build_r1_new<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; // Load the two variants of the result returned by the syscall handler. let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -1909,50 +1414,22 @@ pub fn build_r1_add<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -2047,118 +1524,61 @@ pub fn build_r1_add<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -2207,50 +1627,22 @@ pub fn build_r1_mul<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -2348,118 +1740,61 @@ pub fn build_r1_mul<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -2508,50 +1843,22 @@ pub fn build_r1_get_point_from_x<'ctx, 'this>( ], )?; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -2639,109 +1946,61 @@ pub fn build_r1_get_point_from_x<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( - context, - result_ptr, - llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), - location, - )) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + let ptr = entry.gep( + context, + location, + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; entry.load(context, location, ptr, variant_tys[0].0)? }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, @@ -2819,50 +2078,22 @@ pub fn build_r1_get_xy<'ctx, 'this>( ) }; - let k1 = helper - .init_block() - .append_operation(arith::constant( + let result_ptr = helper.init_block().alloca1( + context, + location, + llvm::r#type::r#struct( context, - IntegerAttribute::new(IntegerType::new(context, 64).into(), 1).into(), - location, - )) - .result(0)? - .into(); - let result_ptr = helper - .init_block() - .append_operation( - OperationBuilder::new("llvm.alloca", location) - .add_attributes(&[ - ( - Identifier::new(context, "alignment"), - IntegerAttribute::new( - IntegerType::new(context, 64).into(), - result_layout.align().try_into()?, - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(llvm::r#type::r#struct( - context, - &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), - ], - false, - )) - .into(), - ), - ]) - .add_operands(&[k1]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + result_layout.align(), + )?; // Allocate space and write the current gas. let gas_builtin_ptr = helper.init_block().alloca1( @@ -2932,155 +2163,93 @@ pub fn build_r1_get_xy<'ctx, 'this>( .build()?, ); - let result = entry - .append_operation(llvm::load( + let result = entry.load( + context, + location, + result_ptr, + llvm::r#type::r#struct( context, + &[ + result_tag_ty, + llvm::r#type::array( + IntegerType::new(context, 8).into(), + (result_layout.size() - 1).try_into()?, + ), + ], + false, + ), + )?; + let result_tag = entry.extract_value( + context, + location, + result, + IntegerType::new(context, 1).into(), + 0, + )?; + + let payload_ok = { + let ptr = entry.gep( + context, + location, result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + + let value = entry.load(context, location, ptr, variant_tys[0].0)?; + + let x_value = entry.extract_value( + context, + location, + value, llvm::r#type::r#struct( context, &[ - result_tag_ty, - llvm::r#type::array( - IntegerType::new(context, 8).into(), - (result_layout.size() - 1).try_into()?, - ), + IntegerType::new(context, 128).into(), + IntegerType::new(context, 128).into(), ], false, ), - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - let result_tag = entry - .append_operation(llvm::extract_value( + 0, + )?; + let y_value = entry.extract_value( context, - result, - DenseI64ArrayAttribute::new(context, &[0]), - IntegerType::new(context, 1).into(), location, - )) - .result(0)? - .into(); - - let payload_ok = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - let value = entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[0].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); - - let x_value = entry - .append_operation(llvm::extract_value( - context, - value, - DenseI64ArrayAttribute::new(context, &[0]), - llvm::r#type::r#struct( - context, - &[ - IntegerType::new(context, 128).into(), - IntegerType::new(context, 128).into(), - ], - false, - ), - location, - )) - .result(0)? - .into(); - let y_value = entry - .append_operation(llvm::extract_value( + value, + llvm::r#type::r#struct( context, - value, - DenseI64ArrayAttribute::new(context, &[1]), - llvm::r#type::r#struct( - context, - &[ - IntegerType::new(context, 128).into(), - IntegerType::new(context, 128).into(), - ], - false, - ), - location, - )) - .result(0)? - .into(); + &[ + IntegerType::new(context, 128).into(), + IntegerType::new(context, 128).into(), + ], + false, + ), + 1, + )?; (x_value, y_value) }; let payload_err = { - let ptr = entry - .append_operation( - OperationBuilder::new("llvm.getelementptr", location) - .add_attributes(&[ - ( - Identifier::new(context, "rawConstantIndices"), - DenseI32ArrayAttribute::new( - context, - &[result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?], - ) - .into(), - ), - ( - Identifier::new(context, "elem_type"), - TypeAttribute::new(IntegerType::new(context, 8).into()).into(), - ), - ]) - .add_operands(&[result_ptr]) - .add_results(&[llvm::r#type::pointer(context, 0)]) - .build()?, - ) - .result(0)? - .into(); - entry - .append_operation(llvm::load( - context, - ptr, - variant_tys[1].0, - location, - LoadStoreOptions::default(), - )) - .result(0)? - .into() - }; - - let remaining_gas = entry - .append_operation(llvm::load( + let ptr = entry.gep( context, - gas_builtin_ptr, - IntegerType::new(context, 128).into(), location, - LoadStoreOptions::default(), - )) - .result(0)? - .into(); + result_ptr, + &[GepIndex::Const( + result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?, + )], + IntegerType::new(context, 8).into(), + )?; + entry.load(context, location, ptr, variant_tys[1].0)? + }; + + let remaining_gas = entry.load( + context, + location, + gas_builtin_ptr, + IntegerType::new(context, 128).into(), + )?; entry.append_operation(helper.cond_br( context, diff --git a/src/types/array.rs b/src/types/array.rs index a187fef11..f43129389 100644 --- a/src/types/array.rs +++ b/src/types/array.rs @@ -24,7 +24,7 @@ use crate::{ drop_overrides::DropOverridesMeta, dup_overrides::DupOverridesMeta, realloc_bindings::ReallocBindingsMeta, MetadataStorage, }, - utils::{BlockExt, ProgramRegistryExt}, + utils::{BlockExt, GepIndex, ProgramRegistryExt}, }; use cairo_lang_sierra::{ extensions::{ @@ -190,14 +190,13 @@ fn build_dup<'ctx>( let src_value_offset = block_realloc.append_op_result(arith::muli(value_offset, elem_stride, location))?; - block_realloc.append_op_result(llvm::get_element_ptr_dynamic( + block_realloc.gep( context, + location, value_ptr, - &[src_value_offset], + &[GepIndex::Value(src_value_offset)], IntegerType::new(context, 8).into(), - llvm::r#type::pointer(context, 0), - location, - ))? + )? }; match metadata.get::() { @@ -216,24 +215,20 @@ fn build_dup<'ctx>( let idx = block.argument(0)?.into(); - let src_value_ptr = - block.append_op_result(llvm::get_element_ptr_dynamic( - context, - src_value_ptr, - &[idx], - IntegerType::new(context, 8).into(), - llvm::r#type::pointer(context, 0), - location, - ))?; - let dst_value_ptr = - block.append_op_result(llvm::get_element_ptr_dynamic( - context, - dst_value_ptr, - &[idx], - IntegerType::new(context, 8).into(), - llvm::r#type::pointer(context, 0), - location, - ))?; + let src_value_ptr = block.gep( + context, + location, + src_value_ptr, + &[GepIndex::Value(idx)], + IntegerType::new(context, 8).into(), + )?; + let dst_value_ptr = block.gep( + context, + location, + dst_value_ptr, + &[GepIndex::Value(idx)], + IntegerType::new(context, 8).into(), + )?; let value = block.load(context, location, src_value_ptr, elem_ty)?; let values = dup_override_meta diff --git a/src/utils.rs b/src/utils.rs index 2c5fc73d9..110ff2c93 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,9 @@ //! # Various utilities pub(crate) use self::{ - block_ext::BlockExt, program_registry_ext::ProgramRegistryExt, range_ext::RangeExt, + block_ext::{BlockExt, GepIndex}, + program_registry_ext::ProgramRegistryExt, + range_ext::RangeExt, }; use crate::{metadata::MetadataStorage, OptLevel}; use cairo_lang_compiler::CompilerConfig; diff --git a/src/utils/block_ext.rs b/src/utils/block_ext.rs index fb43755cf..66935e4a7 100644 --- a/src/utils/block_ext.rs +++ b/src/utils/block_ext.rs @@ -4,7 +4,9 @@ use crate::{error::Error, utils::get_integer_layout}; use melior::{ dialect::{llvm::r#type::pointer, ods}, ir::{ - attribute::{DenseI64ArrayAttribute, IntegerAttribute, TypeAttribute}, + attribute::{ + DenseI32ArrayAttribute, DenseI64ArrayAttribute, IntegerAttribute, TypeAttribute, + }, r#type::IntegerType, Attribute, Block, Location, Operation, Type, Value, ValueLike, }, @@ -12,6 +14,15 @@ use melior::{ }; use num_bigint::BigInt; +/// Index types for LLVM GEP. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum GepIndex<'c, 'a> { + /// A compile time known index. + Const(i32), + /// A runtime value index. + Value(Value<'c, 'a>), +} + pub trait BlockExt<'ctx> { /// Appends the operation and returns the first result. fn append_op_result(&self, operation: Operation<'ctx>) -> Result, Error>; @@ -123,9 +134,38 @@ pub trait BlockExt<'ctx> { dst: Value<'ctx, '_>, len_bytes: Value<'ctx, '_>, ); + + /// Creates a getelementptr operation. Returns a pointer to the indexed element. + /// This method allows combining both compile time indexes and runtime value indexes. + /// + /// See: + /// - https://llvm.org/docs/LangRef.html#getelementptr-instruction + /// - https://llvm.org/docs/GetElementPtr.html + /// + /// Get Element Pointer is used to index into pointers, it uses the given + /// element type to compute the offsets, it allows indexing deep into a structure (field of field of a ptr for example), + /// this is why it accepts a array of indexes, it indexes through the list, offsetting depending on the element type, + /// for example it knows when you index into a struct field, the following index will use the struct field type for offsets, etc. + /// + /// Address computation is done at compile time. + /// + /// Note: This GEP sets the inbounds attribute, all GEPs we do in native should be inbounds, llvm inbounds requires the following: + /// + /// The base pointer has an in bounds address of the allocated object that it is based on. This means that it points into that allocated object, or to its end. Note that the object does not have to be live anymore; being in-bounds of a deallocated object is sufficient. + /// + /// During the successive addition of offsets to the address, the resulting pointer must remain in bounds of the allocated object at each step. + fn gep( + &self, + context: &'ctx Context, + location: Location<'ctx>, + ptr: Value<'ctx, '_>, + indexes: &[GepIndex<'ctx, '_>], + elem_type: Type<'ctx>, + ) -> Result, Error>; } impl<'ctx> BlockExt<'ctx> for Block<'ctx> { + #[inline] fn const_int( &self, context: &'ctx Context, @@ -149,6 +189,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { ) } + #[inline] fn const_int_from_type( &self, context: &'ctx Context, @@ -171,6 +212,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { ) } + #[inline] fn extract_value( &self, context: &'ctx Context, @@ -195,6 +237,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { ) } + #[inline] fn insert_value( &self, context: &'ctx Context, @@ -220,6 +263,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { ) } + #[inline] fn insert_values<'block>( &'block self, context: &'ctx Context, @@ -233,6 +277,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { Ok(container) } + #[inline] fn store( &self, context: &'ctx Context, @@ -250,6 +295,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { Ok(self.append_operation(operation).result(0)?.into()) } + #[inline] fn load( &self, context: &'ctx Context, @@ -260,6 +306,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { self.append_op_result(ods::llvm::load(context, value_type, addr, location).into()) } + #[inline] fn memcpy( &self, context: &'ctx Context, @@ -281,6 +328,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { ); } + #[inline] fn alloca( &self, context: &'ctx Context, @@ -306,6 +354,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { self.append_op_result(op.into()) } + #[inline] fn alloca1( &self, context: &'ctx Context, @@ -317,6 +366,7 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { self.alloca(context, location, elem_type, num_elems, align) } + #[inline] fn alloca_int( &self, context: &'ctx Context, @@ -332,4 +382,40 @@ impl<'ctx> BlockExt<'ctx> for Block<'ctx> { get_integer_layout(bits).align(), ) } + + #[inline] + fn gep( + &self, + context: &'ctx Context, + location: Location<'ctx>, + ptr: Value<'ctx, '_>, + indexes: &[GepIndex<'ctx, '_>], + elem_type: Type<'ctx>, + ) -> Result, Error> { + let mut dynamic_indices = Vec::with_capacity(indexes.len()); + let mut raw_constant_indices = Vec::with_capacity(indexes.len()); + + for index in indexes { + match index { + GepIndex::Const(idx) => raw_constant_indices.push(*idx), + GepIndex::Value(value) => { + dynamic_indices.push(*value); + raw_constant_indices.push(i32::MIN); // marker for dynamic index + } + } + } + + let mut op = ods::llvm::getelementptr( + context, + pointer(context, 0), + ptr, + &dynamic_indices, + DenseI32ArrayAttribute::new(context, &raw_constant_indices), + TypeAttribute::new(elem_type), + location, + ); + op.set_inbounds(Attribute::unit(context)); + + self.append_op_result(op.into()) + } } diff --git a/tests/alexandria/Scarb.lock b/tests/alexandria/Scarb.lock index 5802fb43c..94ac822ea 100644 --- a/tests/alexandria/Scarb.lock +++ b/tests/alexandria/Scarb.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "alexandria_bytes" version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" dependencies = [ "alexandria_data_structures", "alexandria_math", @@ -22,7 +22,7 @@ dependencies = [ [[package]] name = "alexandria_data_structures" version = "0.2.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" dependencies = [ "alexandria_encoding", ] @@ -30,7 +30,7 @@ dependencies = [ [[package]] name = "alexandria_encoding" version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" dependencies = [ "alexandria_bytes", "alexandria_math", @@ -40,12 +40,12 @@ dependencies = [ [[package]] name = "alexandria_math" version = "0.2.1" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" [[package]] name = "alexandria_numeric" version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" dependencies = [ "alexandria_math", "alexandria_searching", @@ -54,7 +54,7 @@ dependencies = [ [[package]] name = "alexandria_searching" version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2#7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2" +source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=95d98a5182001d07673b856a356eff0e6bd05354#95d98a5182001d07673b856a356eff0e6bd05354" dependencies = [ "alexandria_data_structures", ] diff --git a/tests/alexandria/Scarb.toml b/tests/alexandria/Scarb.toml index bd7283a2d..5ef146bd0 100644 --- a/tests/alexandria/Scarb.toml +++ b/tests/alexandria/Scarb.toml @@ -1,11 +1,11 @@ [package] name = "alexandria" version = "0.1.0" -cairo-version = "2.7.1" +cairo-version = "2.8.4" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -alexandria_math = { rev = "7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2", git = "https://github.com/keep-starknet-strange/alexandria.git" } -alexandria_data_structures = { rev = "7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2", git = "https://github.com/keep-starknet-strange/alexandria.git" } -alexandria_encoding = { rev = "7c19379ab6cf0f8b48be3c5b118ffddd7e26a4d2", git = "https://github.com/keep-starknet-strange/alexandria.git" } +alexandria_math = { rev = "95d98a5182001d07673b856a356eff0e6bd05354", git = "https://github.com/keep-starknet-strange/alexandria.git" } +alexandria_data_structures = { rev = "95d98a5182001d07673b856a356eff0e6bd05354", git = "https://github.com/keep-starknet-strange/alexandria.git" } +alexandria_encoding = { rev = "95d98a5182001d07673b856a356eff0e6bd05354", git = "https://github.com/keep-starknet-strange/alexandria.git" }