Beaver.Walker (beaver v0.4.0)

Provides traversal capabilities for MLIR structures.

This module implements traversal functionality for MLIR structures including:

It implements both the Enumerable protocol and the Access behavior to provide a familiar interface for working with MLIR structures.

Depth-first, pre-order and post-order walking

Allows traversing MLIR structures in depth-first order, visiting each node and its children before moving to siblings. Supports both pre-order (visit node before children) and post-order (visit children before node).

Mutation Support

It is possible to modifying the MLIR structure during traversal with CAPIs. It is recommended to use replace/2 to replace an operation to keep the traversal going.

Pattern-based Transformations

You can apply transformation patterns defined using Beaver.Pattern.defpat/2 to MLIR structures during traversal.

Access Syntax

  • Access behavior to provide convenient attribute access:
    op[:attr_name]
    op["attr_name"]
  • convenient access to get operands, results, regions
    operands(op)[0]

Summary

Functions

Returns an enumerable of the arguments of an Block.t()

Returns an enumerable of the attributes of an operation().

Returns an enumerable of the blocks of an Region.t()

Returns an enumerable of the operands of an operation().

Returns an enumerable of the operations of an Block.t()

Performs a depth-first, post-order traversal of a MLIR structure.

Performs a depth-first, post-order traversal of a MLIR structure using an accumulator.

Performs a depth-first, pre-order traversal of a MLIR structure.

Performs a depth-first, pre-order traversal of a MLIR structure using an accumulator.

Returns an enumerable of the regions of an operation().

Replace a operation with a value

Returns an enumerable of the results of an operation().

Returns an enumerable of the successor blocks of an operation().

Traverse and transform a container in MLIR, it could be a operation, region, block. You might expect this function works like Macro.traverse/4.

Returns an enumerable of the uses of an Value.t()

Types

container()

element()

element_module()

@type element_module() ::
  Beaver.MLIR.Operation
  | Beaver.MLIR.Region
  | Beaver.MLIR.Block
  | Beaver.MLIR.Value
  | Beaver.MLIR.Attribute

mlir()

@type mlir() :: container() | element()

operation()

t()

@type t() :: %Beaver.Walker{
  container: container(),
  element_equal:
    (element(), element() -> Beaver.Native.Bool.t() | bool()) | nil,
  element_module: element_module(),
  get_element: (container(), integer() -> element()) | nil,
  get_first: (container() -> element()) | nil,
  get_next: (element() -> element()) | nil,
  get_num: (container() -> Beaver.Native.I64.t() | integer()) | nil,
  get_parent: (element() -> container()) | nil,
  is_null: (element() -> Beaver.Native.Bool.t() | bool()) | nil,
  num: non_neg_integer() | nil,
  parent_equal: (element(), element() -> Beaver.Native.Bool.t() | bool()) | nil,
  this: element() | non_neg_integer() | nil
}

Functions

arguments(block)

@spec arguments(Beaver.MLIR.Block.t()) :: Enumerable.t()

Returns an enumerable of the arguments of an Block.t()

attributes(op)

@spec attributes(operation()) :: Enumerable.t()

Returns an enumerable of the attributes of an operation().

blocks(region)

@spec blocks(Beaver.MLIR.Region.t()) :: Enumerable.t()

Returns an enumerable of the blocks of an Region.t()

operands(op)

@spec operands(operation()) :: Enumerable.t()

Returns an enumerable of the operands of an operation().

operations(block)

@spec operations(Beaver.MLIR.Block.t()) :: Enumerable.t()

Returns an enumerable of the operations of an Block.t()

postwalk(ast, fun)

@spec postwalk(mlir(), (mlir() -> mlir())) :: mlir()

Performs a depth-first, post-order traversal of a MLIR structure.

postwalk(ast, acc, fun)

@spec postwalk(mlir(), any(), (mlir(), any() -> {mlir(), any()})) :: {mlir(), any()}

Performs a depth-first, post-order traversal of a MLIR structure using an accumulator.

prewalk(ast, fun)

@spec prewalk(mlir(), (mlir() -> mlir())) :: mlir()

Performs a depth-first, pre-order traversal of a MLIR structure.

prewalk(ast, acc, fun)

@spec prewalk(mlir(), any(), (mlir(), any() -> {mlir(), any()})) :: {mlir(), any()}

Performs a depth-first, pre-order traversal of a MLIR structure using an accumulator.

regions(op)

@spec regions(operation()) :: Enumerable.t()

Returns an enumerable of the regions of an operation().

replace(op, value, opts \\ [destroy: true])

Replace a operation with a value

results(op)

@spec results(operation()) :: Enumerable.t()

Returns an enumerable of the results of an operation().

successors(op)

@spec successors(operation()) :: Enumerable.t()

Returns an enumerable of the successor blocks of an operation().

traverse(mlir, acc, pre, post)

@spec traverse(mlir(), any(), (mlir(), any() -> {mlir(), any()}), (mlir(), any() ->
                                                               {mlir(), any()})) ::
  {mlir(), any()}

Traverse and transform a container in MLIR, it could be a operation, region, block. You might expect this function works like Macro.traverse/4.

More on manipulating the IR

During the traversal, there are generally two choices to manipulate the IR:

  • Use a pattern defined by macro Beaver.Pattern.defpat/2 to have the PDL interpreter transform the IR for you. You can use both if it is proper to do so.
  • Use Beaver.Walker.replace/2 to replace the operation and return a walker as placeholder if is replaced by value. It could be mind-boggling to think the IR is mutable but not an issue if your approach is very functional. Inappropriate mutation might cause crash or bugs if somewhere else is keeping a reference of the replace op.

Some tips

  • If your matching is very complicated, using with/1 in Elixir should cover it.
  • Use defpat if you want MLIR's greedy pattern application based on benefits instead of implementing something alike yourself.
  • You can run traversals in a MLIR pass by calling them in run/1 so that it joins the general MLIR pass manager's orchestration and will be run in parallel when possible.

uses(value)

@spec uses(Beaver.MLIR.Value.t()) :: Enumerable.t()

Returns an enumerable of the uses of an Value.t()