# loki.ir.expr_visitors

Visitor classes for traversing and transforming all expression trees in Loki’s internal representation (IR).

Classes

`AttachScopes`([fail]) | Scoping visitor that traverses the control flow tree and uses `AttachScopesMapper` to update all `TypedSymbol` expression tree nodes with a pointer to their corresponding scope.
`ExpressionFinder`([unique, with_ir_node]) | Base class visitor to collect specific sub-expressions, eg.
`ExpressionTransformer`([mapper, ...]) | The `Transformer` base class for manipulating expressions.
`FindExpressions`([unique, with_ir_node]) | A visitor to collect all expression tree nodes (i.e., `pymbolic.primitives.Expression`) in an IR tree.
`FindInlineCalls`([unique, with_ir_node]) | A visitor to collect all `InlineCall` symbols used in an IR tree.
`FindLiterals`([unique, with_ir_node]) | A visitor to collect all literals (which includes `FloatLiteral`, `IntLiteral`, `LogicLiteral`, `StringLiteral`, and `IntrinsicLiteral`) used in an IR tree.
`FindRealLiterals`([unique, with_ir_node]) | A visitor to collect all real/float literals (which includes `FloatLiteral`) used in an IR tree.
`FindTypedSymbols`([unique, with_ir_node]) | A visitor to collect all `TypedSymbol` used in an IR tree.
`FindVariables`([unique, with_ir_node]) | A visitor to collect all variables used in an IR tree
`SubstituteExpressions`(expr_map[, ...]) | A dedicated visitor to perform expression substitution in all IR nodes
`SubstituteStringExpressions`(str_map, scope) | Extension to `SubstituteExpressions` that allows symbol substitution of pure string mappings via `parse_expr`.

class ExpressionFinder(unique=True, with_ir_node=False)

  Bases: `Visitor`

  Base class visitor to collect specific sub-expressions, eg. functions or symbols, from all nodes in an IR tree.

  Note that specialized `FindXXX` classes are provided in `loki.expression` to find some of the most common sub-expression types, eg. symbols, functions and variables.

  retriever

    An implementation of an expression mapper, e.g., `ExpressionRetriever`, that is used to search expression trees. Note that it needs to provide a `retrieve` method to initiate the traversal and retrieve the list of expressions.

    Type:

      `pymbolic.mapper.Mapper`

  Parameters:

    - unique (bool, optional) – If True the visitor will return a set of unique sub-expression instead of a list of possibly repeated instances.

    - with_ir_node (bool, optional) – If True the visitor will return tuples which contain the sub-expression and the corresponding IR node in which the expression is contained.

  retriever = <loki.expression.mappers.ExpressionRetriever object>
  find_uniques(variables)

    Reduces the number of matched sub-expressions to a set of unique sub-expressions, if self.unique is True.

    Currently, two sub-expressions are considered NOT to be unique if they have the same - `name` - `parent.name` (or None) - `dimensions` (for `Array`)

  classmethod retrieve(expr)

    Internal retrieval function used on expressions.

  default_retval

    alias of `tuple`

  visit_tuple(o, **kwargs)

    Visit all elements in a tuple and return the results as a tuple.

  visit_list(o, **kwargs)

    Visit all elements in a tuple and return the results as a tuple.

  visit_Expression(o, **kwargs)
  visit_Node(o, **kwargs)

    Visit all children of a `Node`.

  visit_TypeDef(o, **kwargs)

    Custom handler for `TypeDef` nodes that does not traverse the body (reason being that discovering variables used or declared inside the type definition would be unexpected if called on a containing `Subroutine` or `Module`)

  visit_VariableDeclaration(o, **kwargs)

class FindExpressions(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all expression tree nodes (i.e., `pymbolic.primitives.Expression`) in an IR tree.

  See `ExpressionFinder`

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class FindVariables(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all variables used in an IR tree

  This refers to expression tree nodes `Scalar`, `Array` and also `DeferredTypeSymbol`.

  See `ExpressionFinder` for further details

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class FindTypedSymbols(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all `TypedSymbol` used in an IR tree.

  See `ExpressionFinder`

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class FindInlineCalls(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all `InlineCall` symbols used in an IR tree.

  See `ExpressionFinder`

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class FindLiterals(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all literals (which includes `FloatLiteral`, `IntLiteral`, `LogicLiteral`, `StringLiteral`, and `IntrinsicLiteral`) used in an IR tree.

  See `ExpressionFinder`

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class FindRealLiterals(unique=True, with_ir_node=False)

  Bases: `ExpressionFinder`

  A visitor to collect all real/float literals (which includes `FloatLiteral`) used in an IR tree.

  See `ExpressionFinder`

  retriever = <loki.expression.mappers.ExpressionRetriever object>

class ExpressionTransformer(mapper=None, invalidate_source=True, inplace=False, rebuild_scopes=False)

  Bases: `Transformer`

  The `Transformer` base class for manipulating expressions.

  This transformer uses the class attribute `expr_mapper` to map an existing expression sub-tree to an new one. By default, it uses the `LokiIdentityMapper` to replicate the existing tree.

  expr_mapper

    An implementation of an expression mapper, e.g., `SubstituteExpressionsMapper`, that is used to map an expression tree to a new one.

    Type:

      `pymbolic.mapper.Mapper`

  Parameters:

    inplace (bool, optional) – If set to True, all updates are performed on existing `Node` objects, instead of rebuilding them, keeping the original tree intact.

  expr_mapper = <loki.expression.mappers.LokiIdentityMapper object>
  visit_Expression(o, **kwargs)

    Call the associated mapper for the given expression node

class SubstituteExpressions(expr_map, invalidate_source=True, **kwargs)

  Bases: `ExpressionTransformer`

  A dedicated visitor to perform expression substitution in all IR nodes

  It applies `SubstituteExpressionsMapper` with the provided `expr_map` to every expression in the traversed IR tree.

  Note

  No recursion is performed on substituted expression nodes, they are taken as-is from the map. Otherwise substitutions that involve the original node would result in infinite recursion - for example a replacement that wraps a variable in an inline call: `my_var -> wrapped_in_call(my_var)`.

  When there is a need to recursively apply the mapping, the mapping needs to be applied to itself first. A potential use-case is renaming of variables, which may appear as the name of an array subscript as well as in the `dimensions` attribute of the same expression: `SOME_ARR(SOME_ARR > SOME_VAL)`. The mapping can be applied to itself using the utility function `recursive_expression_map_update`.

  Parameters:

    - expr_map (dict) – Expression mapping to apply to the expression tree.

    - invalidate_source (bool, optional) – By default the `source` property of nodes is discarded when rebuilding the node, setting this to False allows to retain that information

  visit_Import(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

  visit_VariableDeclaration(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

  visit_ProcedureDeclaration(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

class SubstituteStringExpressions(str_map, scope, invalidate_source=True)

  Bases: `SubstituteExpressions`

  Extension to `SubstituteExpressions` that allows symbol substitution of pure string mappings via `parse_expr`.

  In addition to the input string mapping this requires a `Scope` (eg. `Subroutine` or `Module`) to parse the respective strings.

  Parameters:

    - expr_map (dict) – String-to-string mapping of expressions to apply to the expression tree.

    - scope (`Scope`) – The scope to which symbol names inside the expression belong

    - invalidate_source (bool, optional) – By default the `source` property of nodes is discarded when rebuilding the node, setting this to False allows to retain that information

class AttachScopes(fail=False)

  Bases: `Visitor`

  Scoping visitor that traverses the control flow tree and uses `AttachScopesMapper` to update all `TypedSymbol` expression tree nodes with a pointer to their corresponding scope.

  Parameters:

    fail (bool, optional) – If set to True, this lets the visitor fail if it encounters a node without a declaration or an entry in any of the symbol tables (default: False).

  visit_object(o, **kwargs)

    Return any foreign object unchanged.

  visit(o, *args, **kwargs)

    Default visitor method that dispatches the node-specific handler

  visit_Expression(o, **kwargs)

    Dispatch `AttachScopesMapper` for `Expression` tree nodes

  visit_list(o, **kwargs)

    Visit each entry in a list and return as a tuple

  visit_tuple(o, **kwargs)

    Visit each entry in a list and return as a tuple

  visit_Node(o, **kwargs)

    Generic handler for IR `Node` objects

    Recurses to children and updates the node

  visit_Import(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

  visit_VariableDeclaration(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

  visit_ProcedureDeclaration(o, **kwargs)

    For `Import` (as well as `VariableDeclaration` and `ProcedureDeclaration`) we set `recurse_to_declaration_attributes=True` to make sure properties in the symbol table are updated during dispatch to the expression mapper

  visit_Scope(o, **kwargs)

    Generic handler for `Scope` objects

    Makes sure that declared variables and imported symbols have an entry in that node’s symbol table before recursing to children with this node as new scope.

  visit_Subroutine(o, **kwargs)

    Handler for `Subroutine` nodes

    Makes sure that declared variables and imported symbols have an entry in the routine’s symbol table before recursing to spec, body, and member routines with this routine as new scope.

  visit_Module(o, **kwargs)

    Handler for `Module` nodes

    Makes sure that declared variables and imported symbols have an entry in the module’s symbol table before recursing to spec, and member routines with this module as new scope.