MLIRはMulti Level Intermediate Representationの略で、LLVM IRよりも更にメタ化したような中間言語だ。LLVM IRでは吸収しきれないような各言語で定義される中間表現を、許容するために開発された。
これを使ってみたいので、まずはToyに似たような言語を使って自分でMLIRを生成できるようになりたい。いくつか試行をしている。
MYSVというVerilogに等価な言語を作って、まずはそれをParseしてDumpできるようにする。これまMLIRを生成する前段階だ。
assign A = 0; assign Hoge = 2;
ASTは簡単なものを作って、AST.h
を作成する。classof
を作成しないと、クラスの動的な処理?が入るらしくコンパイルできない。
RTTI、つまり実行時型情報、の対応だな(よく分かっていない)。
/// Base class for all expression nodes. class ExprAST { public: enum ExprASTKind { Expr_Assign, Expr_Num, }; ExprAST(ExprASTKind kind, Location location) : kind(kind), location(std::move(location)) {} virtual ~ExprAST() = default; ExprASTKind getKind() const { return kind; } const Location &loc() { return location; } private: const ExprASTKind kind; Location location; }; /// Expression class for numeric literals like "1". class NumberExprAST : public ExprAST { uint64_t val; public: NumberExprAST(Location loc, uint64_t val) : ExprAST(Expr_Num, std::move(loc)), val(val) {} uint64_t getValue() { return val; } /// LLVM style RTTI static bool classof(const ExprAST *c) { return c->getKind() == Expr_Num; } };
とりあえず簡単なものなら、ファイルから読み込んで、ダンプできるようになった。
./bin/mysv ../mlir/examples/mysv/test/assign.sv -emit=ast Module: assign A @../mlir/examples/mysv/test/assign.sv:1:1 0 @../mlir/examples/mysv/test/assign.sv:1:12 assign Hoge @../mlir/examples/mysv/test/assign.sv:2:1 2 @../mlir/examples/mysv/test/assign.sv:2:15