我们以toy实例作为例子,有两个文件:ToyCombine.cpp和ToyCombine.td,这里对应了两种方式:手动匹配重写和DDR自动生成匹配与重写。DDR自动生成匹配与重写我们先看ToyCombine.td://===- ToyCombine.td - Pattern Match Optimizations for Toy -*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines language-specific pattern match optimizations for Toy using // Declarative Rewrite Rules (DRR) specified using TableGen records. // //===----------------------------------------------------------------------===// #ifndef TOY_COMBINE #define TOY_COMBINE include "mlir/IR/PatternBase.td" include "toy/Ops.td" /// Note: The DRR definition used for defining patterns is shown below: /// /// class Pattern /// dag sourcePattern, listdag resultPatterns, /// listdag additionalConstraints = [], /// dag benefitsAdded = (addBenefit 0) /// ; //===----------------------------------------------------------------------===// // Basic Pattern-Match and Rewrite //===----------------------------------------------------------------------===// // Reshape(Reshape(x)) = Reshape(x) def ReshapeReshapeOptPattern : Pat(ReshapeOp(ReshapeOp $arg)), (ReshapeOp $arg); //===----------------------------------------------------------------------===// // Pattern-Match and Rewrite using Native Code Call //===----------------------------------------------------------------------===// // Native Code Calls may be used for more complex transformations using inline // C++ and C++ helper functions. // Reshape(Constant(x)) = x' def ReshapeConstant : NativeCodeCall"$0.reshape(::llvm::castShapedType($1.getType()))"; def FoldConstantReshapeOptPattern : Pat (ReshapeOp:$res (ConstantOp $arg)), (ConstantOp (ReshapeConstant $arg, $res)); //===----------------------------------------------------------------------===// // Pattern-Match and Rewrite with Constraints //===----------------------------------------------------------------------===// // DRR allows for constraint checking when the transformation is conditional // on operand properties. // Reshape(x) = x, where input and output shapes are identical def TypesAreIdentical : ConstraintCPred"$0.getType() == $1.getType()"; def RedundantReshapeOptPattern : Pat (ReshapeOp:$res $arg), (replaceWithValue $arg), [(TypesAreIdentical $res, $arg)]; #endif // TOY_COMBINE这个文件用 DRR (Declarative Rewrite Rules,声明式重写规则)定义了 Toy 方言的 模式匹配优化 。相当于用 TableGen 语法声明"看到什么模式,就替换成什么"。首先include两个文件:include "mlir/IR/PatternBase.td" // 引入 Pattern 基础定义 include "toy/Ops.td" // 引入 Toy 操作定义三种优化模式模式一基本模式匹配 —— ReshapeReshapeOptPatterndef ReshapeReshapeOptPattern : Pat (ReshapeOp (ReshapeOp $arg)), // 源模式:嵌套 Reshape (ReshapeOp $arg) // 目标模式:单次 Reshape ;优化 :连续两次 reshape 等价于只做一次。优化前: 优化后: Reshape(Reshape(x)) → Reshape(x) %1 = toy.reshape(%0) %1 = toy.reshape(%0) %2 = toy.reshape(%1)模式二Native Code Call —— FoldConstantReshapeOptPatterndef ReshapeConstant : NativeCodeCall"$0.reshape(::llvm::castShapedType($1.getType()))"; def FoldConstantReshapeOptPattern : Pat (ReshapeOp:$res (ConstantOp $arg)), // 源模式:Reshape(Constant) (ConstantOp (ReshapeConstant $arg, $res)) // 目标:直接计算新常量 ;(ReshapeOp:$res (ConstantOp $arg)) 解析:这是一个 DAG(有向无环图) ,表示操作的嵌套关系:(ReshapeOp:$res (ConstantOp $arg)) │ │ │ │ │ │ │ └── 绑定名称:$arg │ │ └── 内层操作:ConstantOp │ └── 绑定名称:$res └── 外层操作:ReshapeOp