Composes two VarTypes, resulting into the VarType with the higher of each characteristic and composed guards: CompVar > NonCompVar Dynamic > Static Required > Optional For example: - OptionalStaticCompVar(g).and(NonCompVar) -> OptionalStaticCompVar(g) - RequiredStaticCompVar(g1).and(OptionalDynamicCompVar(g2)) -> RequiredDynamicCompVar(g1.and(g2))
A VarType describes the free variables of a DSL program that are used in compilation. Variables which aren't used in any compilation decisions should be marked as
NonCompVarand will result in holes in the compiled DSL. There are fourCompVartypes, each with an associated guard function that decides when recompilation is triggered.Firstly, a variable can be static or dynamic. If it is static, then values with different executions always need recompilation. But if for example we have multiplication variants for sparse and dense matrices, then we only need to recompile when the new value doesn't fall into the same category. So variables need to be marked as dynamic if some values don't require recompilation but should lead to a different execution anyhow (they appear as variables in the compiled code instead of being fixed to the value used when compiling). In this case, the DSL needs to implement the function: LiftEvidence[T: TypeTag, Ret].mixed(v: T, hole: Ret): Ret The value v is used for optimization decisions (e.g. sparse vs. dense matrix), and the hole as variable in the generated code.
The second characteristic is whether a variable is required for compilation or optional. For required variables, optimized code will always be generated. For optional variables, runtime statistics are being collected and optimized code is only generated when a variable is sufficiently stable, otherwise generic code with a variable should be generated. Optional variables are also represented as mixed nodes in the DSL body. The stable variables are passed as a set of holeIds to the generateCode method and can be treated like required variables, respecting their static/dynamic nature, and will be guarded with the provided guard function. For the unstable ones, generic code only using the hole and not the value of the mixed node has to be generated. The value will not be guarded.