MLIRについて勉強している。
いくつかの最適化について実装してみたくて、例えばA-A
を自動的に0としてくれるみたいなのは簡単に作れそうなのだけれども、MLIRのrewriter
というのを使うらしい。
/// This method attempts to match a pattern and rewrite it. The rewriter /// argument is the orchestrator of the sequence of rewrites. The pattern is /// expected to interact with it to perform any changes to the IR from here. mlir::LogicalResult matchAndRewrite(TransposeOp op, mlir::PatternRewriter &rewriter) const override { // Look through the input of the current transpose. mlir::Value transposeInput = op.getOperand(); TransposeOp transposeInputOp = transposeInput.getDefiningOp<TransposeOp>(); // Input defined by another transpose? If not, no match. if (!transposeInputOp) return failure(); // Otherwise, we have a redundant transpose. Use the rewriter. rewriter.replaceOp(op, {transposeInputOp.getOperand()}); return success(); } };
このrewriter
を使えば何かできると思うのだが、「削除」ではなく「追加」するとすればどうやればいいんだろう。
mlir::LogicalResult matchAndRewrite(SubOp op, mlir::PatternRewriter &rewriter) const override { // Look through the input of the current transpose. mlir::Value op0 = op.getOperand(0); mlir::Value op1 = op.getOperand(1); mlir::Type elementType = rewriter.getI64Type(); mlir::Value zero = rewriter.create<ConstantOp>(op.getLoc(), elementType, /*value=*/0); rewriter.replaceOp(op, zero); return success(); }
あれ、何にも変わらなかった。
$ ./bin/mysv --emit=mlir ../mlir/examples/mysv/test/assign_ops2.sv module { %0 = "mysv.constant"() {value = 3 : si64} : () -> i64 %1 = "mysv.constant"() {value = 4 : si64} : () -> i64 %2 = "mysv.sub"(%0, %0) : (i64, i64) -> i64 %3 = "mysv.add"(%2, %1) : (i64, i64) -> i64 %4 = "mysv.mul"(%0, %1) : (i64, i64) -> i64 }