curry.backends.cxx.passthrough module
The variables of a step that the C++ backend reads as plain pointers.
A step of generated code builds a Variable for every argument it reads: the
slot that holds the node, the path to it from the redex, and the set guards
crossed on the way. An argument that the step only passes on to another call
needs none of that: nothing head-normalizes it from this step (the path), and
the value it denotes is the node in its slot (the guards). Such a variable is
a plain Node * in the generated code, read through Node::successor_node or
Variable::successor_node (see cyrt/graph/node.hxx and indexing.hxx).
The rule. A variable is plain when all of the following hold:
It is declared by IVarDecl. A free variable (IFreeDecl) is a plain pointer already.
It is assigned once, and the right side is a successor of the redex or of another variable with a path of one entry (IVarAccess), a node the step builds (a call, a partial application, a choice, a literal, or a string), or another plain variable.
Every use passes the value on: an argument of a call, of a partial application, or of a choice; the whole expression of a return; the right side of a node assignment (the patch of a recursive let).
A variable that a case scrutinizes keeps the Variable: hnf needs the path for
the scan and the guards for the escape set of a pull-tabbed choice. So does
the base of a successor path (the path continues from its target and its
guards) and the base of a node assignment (set_successor). Two variables of
a var-to-var assignment have one kind: both plain, or both Variables. A free
variable on the right side is a plain pointer and forces nothing on the left
side: a plain left side copies the pointer, and a Variable takes the node
as it takes a node the step builds (the optimizer inlines unknown to a
fresh free variable; see curry.icurry.analysis.inlining).
Why the guard rule holds. The redex of a step is a function node, never a set guard, so a slot of the redex holds the whole guarded argument, and a plain read keeps the guard. A successor of a Variable may lie under the guards the Variable crossed, which the ICurry does not show; for such a read Variable::successor_node decides at run time, and builds the guards again when it crossed any. A path of more than one entry stays a Variable.