Currently, there can be a lot of dead code generated for several reasons:
- The
Statement::Declaration for a var creates this nondet with the declared type and adds it to the var tracking data struct. Almost always, the actual init/assignment is separate from the declaration in the AST and is encountered later and gives an actual value to the var making this statement dead.
poly.expr body computes all var values up to a certain point but only values needed for the target expression of the poly.expr are live
- Subcomponent init within a loop ends up generating several lines of code that essentially do nothing:
%2 = cast.toindex %1 : !felt.type<"bn128">
%3 = pod.new { @N = %1 } : <[@N: !felt.type<"bn128">]>
%4 = pod.new : <[]>
%5 = pod.read %3[@N] : <[@N: !felt.type<"bn128">]>, !felt.type<"bn128">
%6 = cast.toindex %5 : !felt.type<"bn128">
We could add some default cleanup pass(es) at some point or give more documentation and examples regarding the llzk_passes option that users can specify to run a pass pipeline.
Currently, there can be a lot of dead code generated for several reasons:
Statement::Declarationfor avarcreates thisnondetwith the declared type and adds it to the var tracking data struct. Almost always, the actual init/assignment is separate from the declaration in the AST and is encountered later and gives an actual value to thevarmaking this statement dead.poly.exprbody computes allvarvalues up to a certain point but only values needed for the target expression of thepoly.exprare liveWe could add some default cleanup pass(es) at some point or give more documentation and examples regarding the
llzk_passesoption that users can specify to run a pass pipeline.