16 Interface
An interface is a typed API contract through which generic MLIR infrastructure can ask a dialect operation, type, or attribute about behavior without depending on its concrete class. Interfaces are the bridge between reusable compiler algorithms and dialect-specific semantics.
16.1 Why Interfaces Exist
A pass that wants to move pure operations must know their effects. It should not contain a growing list of arithmetic, tensor, GPU, and external-dialect operation names. Instead it queries a memory-effects or other semantic interface. Each dialect implements the query in the way that matches its own operations, while the pass remains reusable.
Interfaces differ from traits. A trait is a static fact or shared mixin attached to an operation definition. An interface exposes behavior through methods and may compute a result from the particular operation instance. Use a trait for a stable structural rule; use an interface when generic code needs an operation- specific answer.
16.2 Important Interface Families
Operation interfaces cover call behavior, memory effects, regions, inlining, bufferization, symbol use, and more. Type interfaces let generic code reason about shaped or element types. Dialect interfaces let a dialect participate in framework-level behavior such as inlining or conversion materialization.
The exact interface is part of a transformation’s proof. Querying a call interface may identify callable operations, but it does not prove a call has no effects. Querying memory effects may report unknown effects, which must be treated conservatively. A pass should request the interface that answers its actual question and handle absent implementations explicitly.
16.3 Implementing And Using Interfaces Safely
An interface implementation is semantic code. Returning an incomplete effects list can let a generic optimization delete or reorder observable behavior. Returning overly conservative answers may lose optimization opportunities but keeps the compiler correct. Start conservative and add precision with tests.
When writing a generic pass, use the interface’s documented fallback behavior. Do not silently assume that an operation without an interface is pure, callable, or safe to inline. Absence usually means the pass lacks proof and must skip the operation or use a conservative default.