CIRCT

Circuit IR Compilers and Tools

Interop Dialect

Provides interoperability between backends and tools This dialect defines the interop dialect which defines operations and interfaces necessary to provide interoperability between backends and and external tools without the need of writing custom pairwise interop solutions.

Operations

interop.procedural.alloc (::circt::interop::ProceduralAllocOp)

Represents persistent state to be allocated

Syntax:

operation ::= `interop.procedural.alloc` $interopMechanism ( `:` qualified(type($states))^ )? attr-dict

The interop.procedural.alloc operation returns a variadic list of values that represent persistent state, i.e., state that has to persist across multiple executions of the interop.procedural.update operation. For example, it can be lowered to C++ class fields that are persistent across multiple calls of a member function, or to global simulator state that persists over simulation cycles, etc.

Additionally, it has an attribute that specifies the interop mechanism under which the state types are valid. This is necessary to allow bridging patterns to map the types to valid types in the other interop mechanism, e.g., to an opaque pointer, if it does not support the same types.

Attributes:

AttributeMLIR TypeDescription
interopMechanism::InteropMechanismAttrinterface through which interoperability is achieved

Results:

ResultDescription
statesvariadic of any type

interop.procedural.dealloc (::circt::interop::ProceduralDeallocOp)

Performs some deallocation logic before the state is released

Syntax:

operation ::= `interop.procedural.dealloc` $interopMechanism ( $states^ `:` qualified(type($states)) )?
              attr-dict-with-keyword $deallocRegion

The interop.procedural.dealloc operation shall be executed right before the state requested by the interop.procedural.alloc operation is released. This allows the instance to do some cleanup, e.g., when the state type was a pointer and the instance performed some malloc.

Structurally the operation is the same as the interop.procedural.update operation, but without input and output values. The state is also passed by value.

Traits: NoTerminator, SingleBlock

Attributes:

AttributeMLIR TypeDescription
interopMechanism::InteropMechanismAttrinterface through which interoperability is achieved

Operands:

OperandDescription
statesvariadic of any type

interop.procedural.init (::circt::interop::ProceduralInitOp)

Computes the initial values for the allocated state

Syntax:

operation ::= `interop.procedural.init` $interopMechanism ( $states^ `:` qualified(type($states)) )?
              attr-dict-with-keyword $initRegion

The interop.procedural.init operation takes the variadic list of states from the interop.procedural.alloc operation as operands and has a body with a interop.return operation that has a variadic list of operands that matches the types of the states and represent the initial values to be assigned to the state values. The assignment will be inserted by the container-side lowering of the interop operations. The operation also has an interop mechanism attribute to allow bridging patterns to map the types to valid types in another interop mechanism and to wrap the operations in the body in a way to make them executable in the other interop mechanism, e.g., wrap them in a extern "C" function to make it callable from C or LLVM IR.

Traits: SingleBlock

Attributes:

AttributeMLIR TypeDescription
interopMechanism::InteropMechanismAttrinterface through which interoperability is achieved

Operands:

OperandDescription
statesvariadic of any type

interop.procedural.update (::circt::interop::ProceduralUpdateOp)

Takes some persistent state and inputs to compute some results

Syntax:

operation ::= `interop.procedural.update` $interopMechanism ( ` ` `[` $states^ `]` )? ( `(` $inputs^ `)` )? `:`
              (`[` qualified(type($states))^ `]`)? functional-type($inputs, $outputs)
              attr-dict-with-keyword $updateRegion

The interop.procedural.update operation has an interop mechanism attribute to allow bridging patterns to map the types to valid types in another interop mechanism and to wrap the operations in the body in a way to make them executable using the other interop mechanism.

It takes the state values returned by the interop.procedural.allocas operands and passes them on to the body via block arguments using pass-by-value semantics. In addition to the state values, it also takes a variadic list of inputs and also passes them on to the body. The interop.return inside the body then returns the result values after doing some computation inside the body.

If the state needs to be mutated, it has to be a pointer type.

Traits: AttrSizedOperandSegments, SingleBlock

Attributes:

AttributeMLIR TypeDescription
interopMechanism::InteropMechanismAttrinterface through which interoperability is achieved

Operands:

OperandDescription
statesvariadic of any type
inputsvariadic of any type

Results:

ResultDescription
outputsvariadic of any type

interop.return (::circt::interop::ReturnOp)

A return operation

Syntax:

operation ::= `interop.return` attr-dict ($returnValues^ `:` type($returnValues))?

The interop.return operation lists the computed initial values when inside the init operation or the computed results when inside the update operation.

Traits: HasParent<ProceduralInitOp, ProceduralUpdateOp>, ReturnLike, Terminator

Interfaces: RegionBranchTerminatorOpInterface

Operands:

OperandDescription
returnValuesvariadic of any type

Interop Dialect Docs