关于 mlir-development
mlir-development 是面向编译器开发者的 MLIR 参考 Skill,涵盖领域专用编译器和优化流水线。内容包括方言、Pass、降级、测试及 ML/AI 编译示例。
主要功能
- 01设计 MLIR 方言与操作
- 02编写 Pass 和模式重写
- 03方言转换与逐级降级
- 04使用 FileCheck 和单元测试
- 05ML/AI 编译示例
适用场景
- 01设计自定义 MLIR 方言
- 02实现优化或重写 Pass
- 03在不同方言间降级操作
- 04测试编译器转换
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gmh5225/ awesome-llvm-security --skill mlir-development安装后在 Claude Code 中输入/mlir-development确认已加载。
详细介绍
MLIR 开发技能
此技能涵盖 MLIR(多级中间表示)开发,用于构建领域专用编译器和高级优化流水线。
MLIR 概述
什么是 MLIR?
MLIR 是一种编译器基础设施,可用于构建可复用且可扩展的编译器组件。它提供:
- 分层、多级 IR 表示
- 可扩展的操作和类型系统
- 在不同抽象层级间逐步降低
- 丰富的转换基础设施
架构
High-Level DSL
↓
Domain-Specific Dialects (e.g., TensorFlow, PyTorch)
↓
Mid-Level Dialects (e.g., Linalg, Affine)
↓
Low-Level Dialects (e.g., LLVM, GPU)
↓
Target Code
核心概念
方言
方言是对操作、类型和属性的分组:
// Define a custom dialect
class MyDialect : public mlir::Dialect {
public:
explicit MyDialect(mlir::MLIRContext *context)
: Dialect("my_dialect", context,
mlir::TypeID::get<MyDialect>()) {
addOperations<
MyAddOp,
MyMulOp,
MyFuncOp
>();
addTypes<MyTensorType>();
}
static llvm::StringRef getDialectNamespace() {
return "my_dialect";
}
};
操作
// Define using ODS (Operation Definition Specification)
// In TableGen file (.td)
def MyAddOp : Op<MyDialect, "add", [Pure]> {
let summary = "Add two tensors";
let description = [{
Performs element-wise addition of two tensors.
}];
let arguments = (ins
AnyTensor:$lhs,
AnyTensor:$rhs
);
let results = (outs
AnyTensor:$result
);
let assemblyFormat = [{
$lhs `,` $rhs attr-dict `:` type($result)
}];
}
类型和属性
// Custom type definition
class MyTensorType : public mlir::Type::TypeBase<
MyTensorType, mlir::Type, MyTensorTypeStorage> {
public:
using Base::Base;
static MyTensorType get(mlir::MLIRContext *context,
llvm::ArrayRef<int64_t> shape,
mlir::Type elementType) {
return Base::get(context, shape, elementType);
}
llvm::ArrayRef<int64_t> getShape() const;
mlir::Type getElementType() const;
};
编写 MLIR Pass
转换 Pass
#include "mlir/Pass/Pass.h"
#include "mlir/IR/PatternMatch.h"
struct MyOptimizationPass
: public mlir::PassWrapper<MyOptimizationPass,
mlir::OperationPass<mlir::func::FuncOp>> {
void runOnOperation() override {
mlir::func::FuncOp func = getOperation();
// Walk all operations
func.walk([](mlir::Operation *op) {
// Transform operations
if (auto addOp = llvm::dyn_cast<MyAddOp>(op)) {
optimizeAdd(addOp);
}
});
}
llvm::StringRef getArgument() const final {
return "my-optimization";
}
llvm::StringRef getDescription() const final {
return "My custom optimization pass";
}
};
基于模式的重写
// Define rewrite pattern
struct SimplifyRedundantAdd : public mlir::OpRewritePattern<MyAddOp> {
using OpRewritePattern<MyAddOp>::OpRewritePattern;
mlir::LogicalResult matchAndRewrite(
MyAddOp op,
mlir::PatternRewriter &rewriter) const override {
// Match: add(x, 0) -> x
if (auto constOp = op.getRhs().getDefiningOp<ConstantOp>()) {
if (isZero(constOp)) {
rewriter.replaceOp(op, op.getLhs());
return mlir::success();
}
}
return mlir::failure();
}
};
// Apply patterns
void runOnOperation() override {
mlir::RewritePatternSet patterns(&getContext());
patterns.add<SimplifyRedundantAdd>(&getContext());
if (mlir::failed(mlir::applyPatternsAndFoldGreedily(
getOperation(), std::move(patterns)))) {
signalPassFailure();
}
}
方言转换
方言间的降低
// Convert high-level ops to lower-level ops
struct MyAddOpLowering : public mlir::OpConversionPattern<MyAddOp> {
using OpConversionPattern<MyAddOp>::OpConversionPattern;
mlir::LogicalResult matchAndRewrite(
MyAddOp op,
OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
// Lower to arith dialect
rewriter.replaceOpWithNewOp<mlir::arith::AddFOp>(
op, adaptor.getLhs(), adaptor.getRhs());
return mlir::success();
}
};
// Conversion pass
struct LowerToArithPass : public mlir::PassWrapper<
LowerToArithPass,
mlir::OperationPass<mlir::ModuleOp>> {
void runOnOperation() override {
mlir::ConversionTarget target(getContext());
target.addLegalDialect<mlir::arith::ArithDialect>();
target.addIllegalDialect<MyDialect>();
mlir::RewritePatternSet patterns(&getContext());
patterns.add<MyAddOpLowering>(&getContext());
if (mlir::failed(mlir::applyPartialConversion(
getOperation(), target, std::move(patterns)))) {
signalPassFailure();
}
}
};
内置方言
Affine 方言
用于多面体编译和循环优化:
affine.for %i = 0 to 100 {
affine.for %j = 0 to 100 {
%val = affine.load %A[%i, %j] : memref<100x100xf32>
affine.store %val, %B[%j, %i] : memref<100x100xf32>
}
}
Linalg 方言
用于线性代数操作:
linalg.matmul ins(%A, %B : tensor<MxKxf32>, tensor<KxNxf32>)
outs(%C : tensor<MxNxf32>) -> tensor<MxNxf32>
SCF 方言(结构化控制流)
%result = scf.for %i = %lb to %ub step %step iter_args(%sum = %init) {
%val = memref.load %A[%i] : memref<?xf32>
%new_sum = arith.addf %sum, %val : f32
scf.yield %new_sum : f32
}
CIR(Clang IR)
概述
CIR 是一种基于 MLIR 的 C/C++ 表示,具有以下特点:
- 比 LLVM IR 更高层级的表示
- 更好的调试和工具支持
- 语言特定的优化
// CIR example
cir.func @add(%a: !s32i, %b: !s32i) -> !s32i {
%result = cir.binop(add, %a, %b) : !s32i
cir.return %result : !s32i
}
CIR 项目
- llvm/clangir:官方 ClangIR 实现
- facebookincubator/clangir:Facebook 的 CIR 实验项目
ML/AI 编译
TensorFlow MLIR
// TensorFlow dialect
%result = "tf.MatMul"(%A, %B) {
transpose_a = false,
transpose_b = false
} : (tensor<4x8xf32>, tensor<8x16xf32>) -> tensor<4x16xf32>
PyTorch MLIR(torch-mlir)
// Torch dialect
%result = torch.aten.mm %A, %B :
!torch.vtensor<[4,8],f32>, !torch.vtensor<[8,16],f32>
-> !torch.vtensor<[4,16],f32>
IREE(中间表示执行环境)
面向 ML 模型的端到端 MLIR 编译器:
- 可移植部署
- 高效运行时执行
- 支持多种目标平台(CPU、GPU、TPU)
测试 MLIR
FileCheck 测试
// RUN: mlir-opt %s -my-pass | FileCheck %s
// CHECK-LABEL: func @test_optimization
// CHECK: arith.addi
// CHECK-NOT: my_dialect.add
func @test_optimization(%a: i32, %b: i32) -> i32 {
%result = my_dialect.add %a, %b : i32
return %result : i32
}
单元测试
TEST(MyDialect, AddOpConstantFolding) {
mlir::MLIRContext context;
context.loadDialect<MyDialect>();
mlir::OpBuilder builder(&context);
auto loc = builder.getUnknownLoc();
// Create and test operations
auto constA = builder.create<ConstantOp>(loc, 5);
auto constB = builder.create<ConstantOp>(loc, 3);
auto add = builder.create<MyAddOp>(loc, constA, constB);
// Verify folding
EXPECT_TRUE(add.fold().succeeded());
}
开发工具
mlir-opt
# Run passes
mlir-opt input.mlir -my-pass -o output.mlir
# Convert between dialects
mlir-opt input.mlir -convert-my-to-llvm
# Debug printing
mlir-opt input.mlir -debug-only=my-pass
mlir-translate
# MLIR to LLVM IR
mlir-translate input.mlir --mlir-to-llvmir -o output.ll
# LLVM IR to MLIR
mlir-translate input.ll --import-llvm -o output.mlir
最佳实践
- 逐步降低:分多个阶段降低,不要直接降低到 LLVM
- 保留语义:每次降低都应保留语义
- 使用 ODS:在 TableGen 中定义操作,以保持一致性
- 充分测试:使用 FileCheck 测试转换
- 记录方言:清晰记录操作语义
资源
有关教程和示例项目,请参阅 README.md 中的 MLIR 和 CIR 部分。
获取详细信息
需要详细且最新的资源链接、工具列表或项目参考资料时,请从以下位置获取最新数据:
https://raw.githubusercontent.com/gmh5225/awesome-llvm-security/refs/heads/main/README.md
此 README 包含经过全面整理的列表:
- MLIR 教程和示例方言(MLIR 部分)
- CIR(Clang IR)项目和文档(CIR 部分)
- ML/AI 编译器框架(torch-mlir、IREE、XLA)
评论
支持 Markdown