Currently builder.eval
always creates a new variable. When the expression is a constant or a single variable, using
builder.eval
to evaluate an expression causes an unnecessary variable assignment, which impacts performance
significantly.
The naming of builder.eval
is semantically incorrect because creating a new variable is out of scope of "eval".
However, the assumption is taken too widely to fix. So we introduce a new method builder.eval_expr
for the real
"evaluation".
builder.eval_expr
returns a right value,
which is either a constant or a variable. An instruction can use a right value for reading a value directly.
Currently builder.eval_expr
only supports SymbolicVar
.
RVar
represents the right value of SymbolicVar
.
To unify static/dynamic programs in eDSL, we introduce a new concept, CR variable("C" for compile time and "R" for runtime). A CR variable behaves like a normal variable in eDSL(e.g. it supports assignment), but it could be either a constant or a variable in runtime.
Currently, there are 2 types of CR variables:
Usize
could be a constant native field or a Var
at right time.
Array
has 2 variants: Fixed
and Dyn
.
Fixed
is a logical array only exists in compile time.
- A static program can only use
Fixed
to represent an array. Fixed
only supports constant index access.- Try to use
Fixed
if possible because most of its operations don't cost instructions.
Dyn
is an array on heap.
- A static program cannot use
Dyn
. - When initializing a
Dyn
, the length could be either a constant or a variable. - The length of
Dyn
is fixed after initialization. Dyn
supports dynamic index access.
In static programs, only constant branches are allowed.
When both start
and end
of a loop are constant, the loop is a constant loop. The loop body will be unrolled. This
optimization saves 1 instruction per iteration.
In static programs, only constant loops are allowed.
!!Attention!!: Break support for constant loops is not perfect. It brings some restrictions which require developers' awareness.:
- If you want to use
break
in a possibly constant loop, you need to use.for_each_may_break
instead of.for_each
. - If you want to use
break
in a branch inside a loop, you need to use.then_may_break
/.then_or_else_may_break
instead of.for_each
/.then_or_else
. - Inside a constant loop, you cannot use a non-constant branch to break.