MLIR学习系列1-MLIR概述
MLIR学习系列1-MLIR概述
MLIR自2019年发布后就成为编译界的新贵,不仅仅AI编译器、领域编译器、新型硬件公司和新型语言都在尝试使用MLIR,其中以AI编译器取得的成果最为显著。本文简单介绍MLIR的基础知识、MLIR构建和MLIR相关工具的使用。
MLIR是什么?
MLIR是Multi-Level Intermediate Representation的缩写。MLIR提供一套新的编译基础架构,方便编译器开发人员定义多层IR,并基于IR进行优化。
MLIR定义的IR通过方言(Dialect)进行管理,Dialect又包含了Operation,而Operation是IR对于的操作,因此可以认为Dialect是Operation的集合。
通过Dialect的定义,可以将代码转换至对应的方言,再通过对方言的降级和优化,最后下降至LLVM IR,重用LLVM的编译框架完成优化、代码生成。
MLIR构建
MLIR是LLVM的子项目,默认情况下构建LLVM时并不会构建MLIR子项目。所以为了使用MLIR在构建LLVM时需要添加额外的参数。编译命令如下:
1 | git clone https://github.com/llvm/llvm-project.git |
在构建时主要添加构建参数-DLLVM_ENABLE_PROJECTS=mlir即可。编译完成后就可以看到MLIR配套相关的工具。
MLIR相关工具使用
MLIR项目构建完成后会生成一些工具。其中最主要的包括:
- mlir-tblgen:将TD文件转换C++代码,和MLIR’框架配合使用
- mlir-opt:对MLIR方言进行下降或者执行优化
- mlir-translate:将LLVM方言转换为LLVM IR;
另外,其它还有一些工具,例如mlir-pdll、mlir-cpu-runner等在后续的blog中涉及到相关内容再进行介绍。
MLIR使用示例
下面通过一个简单的示例演示MLIR的工作流程。
使用MLIR定义一个Hello MLIR的代码
1 | module { |
在这个例子中,使用4个方言,分别是memref、func、arith和llvm(例如代码中memerf.global表示memref方言中的global operation)。通过memref定义一个全局变量的字符串“Hello,MLIR!”
使用llvm方言引用一个外部函数put;
使用func方言定义main函数,并在main函数获取字符串,并将其作为put函数的参数,调用put函数。
将MLIR方言下降至LLVM方言
在MLIR世界中,需要将其它的方言下降至LLVM方言(包含LLVM和后端硬件方言,烈日ArmSVE方言),在本例中需要将func、arith、memref下降到LLVM方言,使用命令如下:mlir-opt -convert-func-to-llvm -finalize-memref-to-llvm -convert-arith-to-llvm -reconcile-unrealized-casts hello.mlir
这个代码如下:
1 | module attributes {llvm.data_layout = ""} { |
该代码只包含了LLVM方言
将LLVM方言转换为LLVM IR
将LLVM方言转换为LLVM IR,使用命令如下mlir-translate --mlir-to-llvmir ***.mlir
生成的LLVM IR如下
1 | ; ModuleID = 'LLVMDialectModule' |
运行测试LLVM IR
生成的LLVM IR就可以接入到LLVM体系中,可以使用LLVM的优化、代码生成、汇编、反汇编工具。例如可以使用lli直接运行上述的LLVM IR,可以得到如下结果:Hello, MLIR!
小结
本文作为MLIR概述的第一篇,简单介绍MLIR的基本概念和工具,通过一个示例演示通过MLIR工具生成LLVM IR的过程。后续我们将逐步展开介绍MLIR方言、模式匹配、方言降级和优化等工作。