FPGA開発日記

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

MLIRの勉強 (5. MLIRGenにおけるスコープ)

MLIRについて勉強している。

独自言語を作成し、その中間表現をMLIRを使って表現してみることに挑戦する。

ここで想定する流れは以下の通りだ。

  1. 独自言語(MYSV : System Verilogオリジナル改造バージョン) を読み込んで、独自形式でASTを作成する
  2. MYSVのASTをMLIRのツリーに変換する
  3. MLIRのツリーをダンプする

msyksphinz.hatenablog.com

前回の問題は変数Aのスコープの問題になっていて、スコープをどこに設定するかという話だった。文の中だけでスコープを持っていると、その文が終了すると変数も消えてしまっている。

/// Emit a new function and add it to the MLIR module.
  mlir::Value mlirGen(AssignExprAST &assignAST) {
    // 本当はここにスコープが入っていた。assigASTでスコープを持っていても、そのassignが消えるとスコープが消えてしまっていた。
    // // Create a scope in the symbol table to hold variable declarations.
    // ScopedHashTableScope<llvm::StringRef, mlir::Value> varScope(symbolTable);

    // Create an MLIR function for the given prototype.
    builder.setInsertionPointToEnd(theModule.getBody());
...

モジュールのレベルでスコープを設定しておくだけで十分だった。

/// Public API: convert the AST for a Mysv module (source file) to an MLIR
  /// Module operation.
  mlir::ModuleOp mlirGen(ModuleAST &moduleAST) {
    // moduleASTのレベルでスコープを設定しておくだけで十分
    // Create a scope in the symbol table to hold variable declarations.
    ScopedHashTableScope<llvm::StringRef, mlir::Value> varScope(symbolTable);

    // We create an empty MLIR module and codegen functions one at a time and
    // add them to the module.
    theModule = mlir::ModuleOp::create(builder.getUnknownLoc());

例えばこういう感じのプログラムをダンプしてみる。

assign A = 3;
assign Hoge = A;
assign B = 4;
assign Hoge = B;
./bin/mysv --emit=ast ../mlir/examples/mysv/test/assign_var.sv

  Module:
    assign A @../mlir/examples/mysv/test/assign_var.sv:1:1
      3 @../mlir/examples/mysv/test/assign_var.sv:1:12
    assign Hoge @../mlir/examples/mysv/test/assign_var.sv:2:1
      A @../mlir/examples/mysv/test/assign_var.sv:2:15
    assign B @../mlir/examples/mysv/test/assign_var.sv:3:1
      4 @../mlir/examples/mysv/test/assign_var.sv:3:12
    assign Hoge @../mlir/examples/mysv/test/assign_var.sv:4:1
      B @../mlir/examples/mysv/test/assign_var.sv:4:15

無事にダンプされた。次はMLIRだ。

$ ./bin/mysv --emit=mlir ../mlir/examples/mysv/test/assign_var.sv

module {
  %0 = "mysv.constant"() {value = 3 : si64} : () -> i64
  %1 = "mysv.constant"() {value = 4 : si64} : () -> i64
}

あれ?勝手に最適化されてしまった。本当はCh3の最適化をこう言うのでやってみたかったんだけど… もうちょっと複雑な物を作らないとダメだろうか。