MLIR入门

文章目录

  • [Build System (Getting Started)](#Build System (Getting Started))
  • [Running and Testing a Lowering](#Running and Testing a Lowering)
    • [Two example programs](#Two example programs)
    • [Lowerings and the math-to-funcs pass](#Lowerings and the math-to-funcs pass)
  • 参考

Build System (Getting Started)

采用cmake,而不采用bazel

MLIR 自 LLVM 14 (2022) 起正式进入 LLVM 稳定发布系列,所有稳定版中 Clang 与 MLIR 完全配套、ABI 稳定.

LLVM/Clang 版本 发布时间 MLIR 状态 推荐度
LLVM 19.x 2026 最新 MLIR 功能完整、稳定、bug 少 ★★★★★
LLVM 18.x 2025 稳定 工业级稳定,Ubuntu 22.04 首选 ★★★★★
LLVM 17.x 2024 稳定 成熟稳定 ★★★★☆
LLVM 16.x 2023 稳定 MLIR 核心框架成熟、API 稳定 ★★★★☆
LLVM 15.x 2022 稳定 可用、API 基本稳定 ★★★☆☆
LLVM 14.x 2022 稳定 首个官方稳定版(基础可用) ★★★☆☆
LLVM ≤ 13 更早 MLIR 未正式进入稳定版 ❌ 不推荐

LLVM 官方 APT 源

  • 测试系统:ubuntu22.04

  • 故采用llvm-18

    安装密钥与源

    wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
    sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main"
    sudo apt update

    安装 Clang + MLIR 开发包(完整工具链)

    sudo apt install -y
    clang-18 clang-tools-18 libclang-18-dev
    llvm-18 llvm-18-dev llvm-18-tools
    mlir-18-tools libmlir-18-dev

Running and Testing a Lowering

核心机制:传统编译器仅依靠单一中间表示(IR)完成程序转换、优化与机器码生成;而 MLIR 依托多类高低级方言与逐步降级的设计,拆分编译流程,分步完成代码下沉。

流程特点:MLIR 通过专属降级步骤逐层将高级方言转为低级方言,过程中穿插优化;且降级与优化流程无严格界限,统一为 IR 重写模块。

设计初衷:MLIR 诞生的重要原因是适配多面体优化、线性代数等专项优化需求;区别于传统编译器丢失循环高层结构、重构难度大的痛点,MLIR 在高级方言中保留程序原始结构以便高效优化,再于降级过程中舍弃结构。

Two example programs

例子:用32 位整数前导零计数的两段 MLIR 代码作为实例,入门理解 MLIR 基础语法与核心概念。

复制代码
func.func @main(%arg0: i32) -> i32 {
  %0 = math.ctlz %arg0 : i32
  func.return %0 : i32
}

代码直接调用math方言的ctlz原生算子,一行完成前导零计算,写法简洁高层。

MLIR 基础语法规则

  • 变量前缀%、函数前缀@;值后跟: 类型显式标注类型。
  • 算子格式固定:方言.算子(如math.ctlz),不同方言自定义自身语法解析规则。

关键核心概念

  • func 也是独立方言,函数定义func.func属于标准 MLIR 算子。
  • Region(区域):大括号包裹的代码范围;Basic Block(基本块):单入口、单出口的指令块,对标编译器经典基础块,用于控制流、跳转逻辑。

在 MLIR 中,随着程序逐渐降低到某个最终后端目标,多个方言通常会在同一程序中共存

例子:该程序的第二个版本实现了 ctlz 函数的软件版本并调用了它

复制代码
func.func @main(%arg0: i32) -> i32 {
  %0 = func.call @my_ctlz(%arg0) : (i32) -> i32
  func.return %0 : i32
}
func.func @my_ctlz(%arg0: i32) -> i32 {
  %c32_i32 = arith.constant 32 : i32
  %c0_i32 = arith.constant 0 : i32
  %0 = arith.cmpi eq, %arg0, %c0_i32 : i32
  %1 = scf.if %0 -> (i32) {
    scf.yield %c32_i32 : i32
  } else {
    %c1 = arith.constant 1 : index
    %c1_i32 = arith.constant 1 : i32
    %c32 = arith.constant 32 : index
    %c0_i32_0 = arith.constant 0 : i32
    %2:2 = scf.for %arg1 = %c1 to %c32 step %c1 iter_args(%arg2 = %arg0, %arg3 = %c0_i32_0) -> (i32, i32) {
      %3 = arith.cmpi slt, %arg2, %c0_i32 : i32
      %4:2 = scf.if %3 -> (i32, i32) {
        scf.yield %arg2, %arg3 : i32, i32
      } else {
        %5 = arith.addi %arg3, %c1_i32 : i32
        %6 = arith.shli %arg2, %c1_i32 : i32
        scf.yield %6, %5 : i32, i32
      }
      scf.yield %4#0, %4#1 : i32, i32
    }
    scf.yield %2#1 : i32
  }
  func.return %1 : i32
}

MLIR 代码拆分出自定义 my_ctlz 函数,主函数 main 调用它,纯软件逻辑实现 32 位整数前导零计数,不再直接使用高阶 math.ctlz 算子,是 MLIR 高阶算子向底层方言降级的示例。

核心算法

  • 特殊判定:输入为 0 时直接返回 32(32 位全零),避免死循环;
  • 核心逻辑:循环逐位左移输入数,判断是否变为负数(有符号数最高位为 1),累计移位次数,即为前导零个数

用到的 MLIR 方言

  • arith:底层算术、常量定义、数值比较、加减、左移等基础运算;
  • scf:结构化控制流,实现 if 分支、for 循环,通过 scf.yield 传出代码块 / 循环的返回值。

关键语法特性

  • 多元组:%2:2 绑定双值结果,%4#1 读取元组第二个分量;
  • 类型区分:i32 固定位宽整型,index 平台相关整型,专用于循环计数、边界、数组索引。

Lowerings and the math-to-funcs pass

例子:tests/ctlz.mlir

复制代码
func.func @main(%arg0: i32) {
  %0 = math.ctlz %arg0 : i32
  func.return
}

mlir-opt 工具对任何 MLIR 代码进行无参数运行,它会解析代码,验证其格式是否正确,并进行一些轻微的规范化处理后将其输出。在本例中,它会将代码封装在一个 module 中,这是一种命名空间隔离机制。

复制代码
➜ externals git:(main) mlir-opt-18 /home/wangji/code/mlir-tutorial/tests/ctlz.mlir
module {
  func.func @main(%arg0: i32) {
    %0 = math.ctlz %arg0 : i32
    return
  }
}

--convert-math-to-funcs=convert-ctlz:作用是 将 Math dialect 中的 ctlz 操作转换为具体的函数实现。

  • 使用 arith 和 scf dialect 实现了 count leading zeros 的完整逻辑

    ➜ externals git:(main) mlir-opt-18 --convert-math-to-funcs=convert-ctlz /home/wangji/code/mlir-tutorial/tests/ctlz.mlir
    module {
    func.func @main(%arg0: i32) {
    %0 = call @__mlir_math_ctlz_i32(%arg0) : (i32) -> i32
    return
    }
    func.func private @__mlir_math_ctlz_i32(%arg0: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
    %c32_i32 = arith.constant 32 : i32
    %c0_i32 = arith.constant 0 : i32
    %0 = arith.cmpi eq, %arg0, %c0_i32 : i32
    %1 = scf.if %0 -> (i32) {
    scf.yield %c32_i32 : i32
    } else {
    %c1 = arith.constant 1 : index
    %c1_i32 = arith.constant 1 : i32
    %c32 = arith.constant 32 : index
    %c0_i32_0 = arith.constant 0 : i32
    %2:2 = scf.for %arg1 = %c1 to %c32 step %c1 iter_args(%arg2 = %arg0, %arg3 = %c0_i32_0) -> (i32, i32) {
    %3 = arith.cmpi slt, %arg2, %c0_i32 : i32
    %4:2 = scf.if %3 -> (i32, i32) {
    scf.yield %arg2, %arg3 : i32, i32
    } else {
    %5 = arith.addi %arg3, %c1_i32 : i32
    %6 = arith.shli %arg2, %c1_i32 : i32
    scf.yield %6, %5 : i32, i32
    }
    scf.yield %4#0, %4#1 : i32, i32
    }
    scf.yield %2#1 : i32
    }
    return %1 : i32
    }
    }

MLIR 降级逻辑
同一 ctlz(前导零计数)程序有高低两个版本:硬件支持ctlz指令时,直接将高层math.ctlz映射为机器指令;无硬件指令时,降级(Lowering) 会把该高阶运算,拆解翻译为func/arith/scf这类底层方言与基础操作,用软件逻辑实现。

mlir-opt 工具作用

MLIR 核心命令行工具,是执行各类编译 Pass(转换 / 降级)的入口:

无参数运行:解析、校验 MLIR 代码,格式化并包裹module做命名空间隔离;

携带参数(如--convert-math-to-funcs):执行内置降级 Pass,自动把高阶算子转为底层代码实现。

Pass 调度方式

每个 MLIR 转换 Pass 都有独立命令行参数,支持单独调用,也可通过--pass-pipeline串联多个 Pass、按顺序流水线执行。

参考

相关推荐
HackTwoHub1 天前
AI大模型网关存在SQL注入、附 POC 复现、影响版本LiteLLM 1.81.16~1.83.7(CVE-2026-42208)
数据库·人工智能·sql·网络安全·系统安全·网络攻击模型·安全架构
l1t1 天前
DeepSeek总结的DuckLake构建基于 SQL 原生表格式的下一代数据湖仓
数据库·sql
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
TDengine (老段)1 天前
从施工监测到运营预警,桥科院用 TDengine 提升桥梁数据管理能力
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
S1998_1997111609•X1 天前
论mysql国盾shell-sfa犯罪行为集团下的分项工程及反向注入原理尐深度纳米算法下的鐌檵鄐鉎行为
网络·数据库·网络协议·百度·开闭原则
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
BU摆烂会噶1 天前
【LangGraph】持久化实现的三大能力——时间旅行
数据库·人工智能·python·postgresql·langchain
l1t1 天前
DeepSeek总结的DuckLake 入门
数据库
Joseph Cooper1 天前
RAG 与 AI Agent:智能体真的需要检索增强生成吗?
数据库·人工智能·ai·agent·rag·上下文工程
light blue bird1 天前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform