lambdaclass / cairo_native

A compiler to convert Cairo's intermediate representation "Sierra" code to MLIR.

Home Page:https://lambdaclass.github.io/cairo_native/cairo_native

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ensure that all `llvm.alloca`s are on the helper's init block.

azteca1998 opened this issue · comments

All llvm.alloca (and their dependencies, which should be constants only) should be appended to the init block, otherwise the tail recursion mechanism will keep allocating more and more stack space every iteration, which is precisely what we want to avoid by using that mechanism.

Let me know if i can work in this one.

Hey, whats up! I'm a first time contributor and would love to introduce myself in the codebase. Let me know if I can grab this or any other issue :)

@azteca1998 Hello mate. When you say llvm.alloca you mean llvm::alloca? Do i have to check in libfuncs for those things?

All llvm::alloca should be like this right?:

let stack_ptr = helper
                .init_block()
                .append_operation(llvm::alloca(
                    context,
                    value_len,
                    llvm::r#type::opaque_pointer(context),
                    location,
                    AllocaOptions::new()
                        .align(Some(IntegerAttribute::new(
                            IntegerType::new(context, 64).into(),
                            inner_layout.align() as i64,
                        )))
                        .elem_type(Some(TypeAttribute::new(inner_ty))),
                ))
                .result(0)?
                .into();

And i dont get the part that you say "and their dependencies".

Hello,

With llvm.alloca I'm referring to the alloca instructions in the llvm dialect. In MLIR they're written as llvm.alloca, but we have them available as llvm::alloca in Rust.

The llvm.alloca instruction accepts other values as arguments (which are dependencies). In your example, the argument would be value_len. They also need to be on the init block, otherwise the generated MLIR would be invalid.

All llvm.alloca operations must be in the init block instead of entry or whatever other local block every libfunc has. I know there's at least one place where it's not in the init block.

Hello,

With llvm.alloca I'm referring to the alloca instructions in the llvm dialect. In MLIR they're written as llvm.alloca, but we have them available as llvm::alloca in Rust.

The llvm.alloca instruction accepts other values as arguments (which are dependencies). In your example, the argument would be value_len. They also need to be on the init block, otherwise the generated MLIR would be invalid.

All llvm.alloca operations must be in the init block instead of entry or whatever other local block every libfunc has. I know there's at least one place where it's not in the init block.

In the previous example, llvm::alloca and the dependencie, are in the init block right? Because I'm using the helper where is located the init function.

When you say entry, is the variable we use to call init_block() right? And we dont want that, we want the LibFuncHelper, am I right?

helper.init_block() is the block at which the operation is appended. We want to append the init block (helper.init_block()) instead of entry (the default block for each libfunc), or any other block internally created within the libfunc (only present in complex libfuncs).

Basically, every .append_operation(llvm::alloca(...)) and its dependencies (the constant) should append to helper.init_block().

Ok. And i have to look through all the code of the project, not just the libfuncs directory?

Ideally yes, but outside the libfuncs (and a few helper functions I think) you won't have the helper. If you find something outside libfuncs' implementations just letting us know is fine, we'll fix it later.

This is already done

This is already done

In my PR or someone else did this? @edg-l