Factory.ai

Open-Source Wikis

/

LLVM

/

Subprojects

/

mlir

llvm/llvm-project

mlir

MLIR — the Multi-Level Intermediate Representation — is a generalized compiler-IR framework. Unlike LLVM IR, which is one specific IR with a fixed instruction set, MLIR is a toolkit for building IRs out of user-defined "dialects". Several dialects ship in this repo (func, arith, tensor, linalg, memref, gpu, llvm, ...) and out-of-tree projects (TensorFlow, IREE, CIRCT, the Polygeist family, several hardware vendors) define their own.

Purpose

MLIR exists because lowering high-level program representations (tensor programs, polyhedral loops, hardware descriptions) directly to LLVM IR loses information that downstream optimizations need. MLIR lets a compiler hold and rewrite multiple representations in the same IR framework, lowering between them progressively until it reaches the llvm dialect, which translates 1:1 to LLVM IR.

Directory layout

mlir/
├── include/mlir/     # Public headers
├── lib/              # Implementation
│   ├── IR/           # Core IR — Operation, Type, Attribute, Region, Block
│   ├── Dialect/      # Built-in dialects (one subdirectory each)
│   ├── Conversion/   # Dialect-to-dialect conversion passes
│   ├── Transforms/   # Generic passes (CSE, canonicalization, inliner, ...)
│   ├── Analysis/
│   ├── Pass/         # Pass infrastructure
│   ├── Parser/, AsmParser/, ToolBindings/, Tools/, Bytecode/, Translation/, Target/, ...
│   └── Bindings/, Debug/, Reducer/, Query/, Rewrite/, Support/, TableGen/, Interfaces/
├── tools/            # mlir-opt, mlir-translate, mlir-tblgen, mlir-lsp-server, etc.
├── test/             # lit regression tests
├── unittests/
├── examples/         # Standalone tutorials (Toy, Standalone)
├── docs/
└── utils/

The Dialect/ tree is the bulk of MLIR by line count. Each dialect ships:

  • *.td files declaring its operations, types, attributes, interfaces
  • C++ implementation in *.cpp
  • Conversion passes lowering it to other dialects
  • lit tests under mlir/test/Dialect/<Name>/

Built-in dialects

A non-exhaustive list, ordered by what most users encounter first:

  • arith — basic integer/float arithmetic
  • func — functions
  • cf — control flow (branches, conditional branches)
  • scf — structured control flow (scf.for, scf.if, scf.while, scf.parallel)
  • tensor — value-semantic n-d arrays
  • memref — reference-semantic n-d arrays (mutable, with strides)
  • linalg — linear algebra (matmul, conv, generic-form rewriting)
  • vector — SIMD-style vectors with shape/affine ops
  • affine — polyhedral compilation primitives
  • bufferization — tensor → memref lowering
  • gpu, nvvm, rocdl, spirv, amdgpu, nvgpu — accelerator targets
  • llvm — a 1:1 mirror of LLVM IR; the bottom of most lowering pipelines
  • async, transform, pdl, irdl, tosa, complex, math, index, ml_program, quant, sparse_tensor, mesh, mpi, omp, acc, emitc, dlti, ptr, ub, polynomial, tile, xevm, xegpu, ... — domain-specific or experimental
  • shape — shape computations, kept separate from tensor for analysis purposes

Key abstractions

Type File Role
mlir::Operation mlir/include/mlir/IR/Operation.h Generic operation carrying operands, results, regions, attributes
mlir::Region / mlir::Block mlir/include/mlir/IR/ Nested scopes
mlir::Type / mlir::Attribute mlir/include/mlir/IR/Types.h, Attributes.h First-class types and named constants
mlir::OpInterface TableGen-generated Mixin interfaces ops can implement (e.g., MemoryEffectOpInterface)
mlir::PassManager mlir/include/mlir/Pass/PassManager.h Drives a pipeline
mlir::OpRewritePattern<> mlir/include/mlir/IR/PatternMatch.h The standard rewrite pattern
mlir::ConversionPatternRewriter mlir/include/mlir/Transforms/DialectConversion.h Dialect-conversion driver

How it works

graph LR
    src[High-level dialect] --> rewrite[Rewrite passes<br/>+ canonicalization]
    rewrite --> conv1[Conversion passes]
    conv1 --> mid[Mid-level dialect]
    mid --> conv2[Further conversions]
    conv2 --> llvm[llvm dialect]
    llvm --> trans[Translation:<br/>llvm dialect → LLVM IR]
    trans --> ir[LLVM IR]
    ir --> codegen[LLVM CodeGen]

The "translation" step (mlir-translate --mlir-to-llvmir) lives in mlir/lib/Target/LLVMIR/. After translation, MLIR's job is done and the LLVM core takes over.

Tools

  • mlir-opt — the canonical pass runner; reads MLIR, runs passes, prints MLIR.
  • mlir-translate — moves MLIR ↔ LLVM IR / SPIR-V / external formats.
  • mlir-tblgen — TableGen backends for ops, types, attributes, interfaces.
  • mlir-lsp-server — LSP server for .mlir files, used by editor extensions.
  • mlir-pdll-lsp-server, mlir-tblgen-lsp-server — LSP for the PDLL pattern language and TableGen sources.
  • mlir-reduce — input reducer for crashing pipelines.

Integration points

  • LLVM core (llvm) — every pipeline that wants to produce machine code ends with translation to LLVM IR.
  • Flang (flang) — its own fir/hlfir dialects lower through cf, scf, and friends to llvm.
  • Clang (clang) — the CIR (clang/lib/CIR/) pipeline emits MLIR.
  • Out-of-tree projects depend on the public APIs in mlir/include/mlir/.

Entry points for modification

  • Adding an operation to a dialect: extend the dialect's <Name>Ops.td, regenerate, implement any C++ verifier or canonicalizer overrides.
  • Adding a dialect: copy mlir/examples/Standalone/ (the canonical out-of-tree dialect template) or look at a small in-tree dialect such as mesh or index.
  • Adding a conversion: write OpConversionPattern<>s under mlir/lib/Conversion/<Source>To<Target>/ and a pass that registers them with a ConversionTarget.
  • Adding a transform pass: a class deriving OperationPass<> registered via TableGen in mlir/include/mlir/Transforms/Passes.td (or the dialect's local Passes.td).

Reference

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

mlir – LLVM wiki | Factory