FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

MLIRの勉強 (8. rewriterの勉強3)

MLIRについて勉強している。うーん、どうしてもPassManagerが適用されない。

どうしても-optでOptimizerが動いてくれないのが、理由が分からない。toycはどのようにしているんだろう?

b SimplifyRedundantTranspose::matchAndRewrite
  * frame #0: 0x000000010007c77c toyc-ch3`SimplifyRedundantTranspose::matchAndRewrite(this=0x0000600002604060, op=TransposeOp @ 0x0000000170605c40, rewriter=0x00000001706065b0) const at ToyCombine.cpp:48:37
    frame #1: 0x000000010007c6dc toyc-ch3`mlir::detail::OpOrInterfaceRewritePatternBase<mlir::toy::TransposeOp>::matchAndRewrite(this=0x0000600002604060, op=0x0000600002c00290, rewriter=0x00000001706065b0) const at PatternMatch.h:329:12
    frame #2: 0x000000010065cb84 toyc-ch3`mlir::PatternApplicator::matchAndRewrite(this=0x00000001706065d8, op=0x0000600002c00290, rewriter=0x00000001706065b0, canApply=mlir::function_ref<bool (const mlir::Pattern &)> @ 0x0000000170605ec0, onFailure=mlir::function_ref<void (const mlir::Pattern &)> @ 0x0000000170605eb0, onSuccess=mlir::function_ref<mlir::LogicalResult (const mlir::Pattern &)> @ 0x0000000170605ea0)>, llvm::function_ref<void (mlir::Pattern const&)>, llvm::function_ref<mlir::LogicalResult (mlir::Pattern const&)>) at PatternApplicator.cpp:201:25
    frame #3: 0x00000001005df90c toyc-ch3`(anonymous namespace)::GreedyPatternRewriteDriver::simplify(this=0x00000001706065b0, regions=MutableArrayRef<mlir::Region> @ 0x0000000170606468) at GreedyPatternRewriteDriver.cpp:271:19
    frame #4: 0x00000001005df130 toyc-ch3`mlir::applyPatternsAndFoldGreedily(regions=MutableArrayRef<mlir::Region> @ 0x0000000170606598, patterns=0x0000000103809de8, config=GreedyRewriteConfig @ 0x0000000170606588) at GreedyPatternRewriteDriver.cpp:406:27
    frame #5: 0x00000001005d3a58 toyc-ch3`mlir::applyPatternsAndFoldGreedily(op=0x0000600002600480, patterns=0x0000000103809de8, config=GreedyRewriteConfig @ 0x0000000170606778) at GreedyPatternRewriteDriver.h:71:10
    frame #6: 0x00000001005c2608 toyc-ch3`(anonymous namespace)::Canonicalizer::runOnOperation(this=0x0000000103809800) at Canonicalizer.cpp:53:11
    frame #7: 0x0000000100546f20 toyc-ch3`mlir::detail::OpToOpPassAdaptor::run(pass=0x0000000103809800, op=0x0000600002600480, am=AnalysisManager @ 0x0000000170606918, verifyPasses=true, parentInitGeneration=1) at Pass.cpp:470:11
    frame #8: 0x00000001005476ac toyc-ch3`mlir::detail::OpToOpPassAdaptor::runPipeline(pm=0x0000000102d043f0, op=0x0000600002600480, am=AnalysisManager @ 0x0000000170606ba0, verifyPasses=true, parentInitGeneration=1, instrumentor=0x0000000000000000, parentInfo=0x000000016fdfd790) at Pass.cpp:534:16
    frame #9: 0x000000010055e190 toyc-ch3`mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(this=0x000000016fdfd730, opInfo=0x0000600000c04210)::$_12::operator()(mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo&) const at Pass.cpp:754:36
    frame #10: 0x0000000100566b28 toyc-ch3`mlir::LogicalResult mlir::failableParallelForEach<std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_12&>(this=0x0000600001704348)::OpPMInfo*>, std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_12&)::'lambda'()::operator()() const at Threading.h:62:18
    frame #11: 0x0000000100566a60 toyc-ch3`decltype(__f=0x0000600001704348)::OpPMInfo*>>(fp)()) std::__1::__invoke<mlir::LogicalResult mlir::failableParallelForEach<std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_12&>(mlir::MLIRContext*, std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>, std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_12&)::'lambda'()&>(std::__1::__wrap_iter<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*>&&) at type_traits:3918:1

いちおう引っかかる。

自分のデザインではどうだろう?

run -emit=mlir -opt ../mlir/examples/mysv/test/assign_ops2.sv
Process 5353 launched: '/Users/kimura/work/llvm/llvm-mlir-mysv/build/bin/mysv' (arm64)
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
}
Process 5353 exited with status = 0 (0x00000000)

うーんスルーされてしまう。念のためもう一つ全く逆のAddOpに対するOptimizerを追加してみた。

/// This is an example of a c++ rewrite pattern for the SubOp. It
/// optimizes the following scenario
struct PlusSameValue : public mlir::OpRewritePattern<AddOp> {
  /// We register this pattern to match every toy.transpose in the IR.
  /// The "benefit" is used by the framework to order the patterns and process
  /// them in order of profitability.
  PlusSameValue(mlir::MLIRContext *context)
      : OpRewritePattern<AddOp>(context, /*benefit=*/1) {}

  /// 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(AddOp 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);

    LLVM_DEBUG(llvm::dbgs() << "PlusSameValue::matchAndReWrite\n");

    mlir::Type elementType = rewriter.getI64Type();

    mlir::Value zero = rewriter.create<ConstantOp>(op.getLoc(), elementType, /*value=*/0);

    rewriter.replaceOp(op, zero);
    return success();
  }
};

/// Register our patterns as "canonicalization" patterns on the AddOp so
/// that they can be picked up by the Canonicalization framework.
void AddOp::getCanonicalizationPatterns(RewritePatternSet &results,
                                        MLIRContext *context) {
  LLVM_DEBUG(llvm::dbgs() << "Registered AddOp\n");
  results.add<PlusSameValue>(context);
}

これもやはり適用されない。根本的なところが間違っているのかもしれない。Toyから外れずにとりあえずチュートリアルを完走した方がいいのかな。