Beaver.Walker (beaver v0.4.8)

Copy Markdown

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

Walker callbacks should only traverse and inspect IR. Use Beaver.MLIR.PatternRewriter inside rewrite patterns, or collect matches and mutate them afterward with Beaver.MLIR.IRRewriter. Keeping traversal and mutation separate prevents callbacks from retaining invalidated operations.

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().

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

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

Traverse a container in MLIR; it can be an operation, region, or 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()

@type operation() :: Beaver.MLIR.Module.t() | Beaver.MLIR.Operation.t()

t()

@type t() :: %Beaver.Walker{
  container: container(),
  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().

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 a container in MLIR; it can be an operation, region, or block. You might expect this function works like Macro.traverse/4.

More on manipulating the IR

Keep mutation outside the active traversal. Use a pattern defined by Beaver.Pattern.defpat/2, an Elixir Beaver.MLIR.RewritePattern, or first collect the operations to change and then use Beaver.MLIR.IRRewriter.

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()