0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TableGenの自動生成ファイルは2回includeする必要がある

Posted at

TL; DR

  • TableGenの自動生成ファイルは2か所でincludeが必要
  • マクロ定義によって挿入される内容が切り替わる(クラス定義 or クラス名一覧)ため

はじめに

MLIRで言語処理系を作っていたところ1、TableGenの自動生成ファイルを利用するために同じファイルを2回includeする必要が出てきました。

lib/CodeGen/Dialect.cpp
// 同じファイルを2回インクルードしている!
#define GET_OP_CLASSES
#include "filskalang/CodeGen/Ops.cpp.inc"

void FilskalangDialect::initialize() {
  addOperations<
#define GET_OP_LIST
#include "filskalang/CodeGen/Ops.cpp.inc"
      >();
}

上記は公式チュートリアルのtoy言語実装を参考にして作成したものです。
はじめはチュートリアルの誤植かと思い片方を消してみたら、コンパイルエラーが発生してしまいました。

そこで本記事では、なぜ2回includeが必要なのか調べてみました。

自動生成ファイルの内容

Ops.cpp.inc の中身は以下のような形式になっていました。

include/filskalang/CodeGen/Ops.cpp.inc
#ifdef GET_OP_LIST
#undef GET_OP_LIST

mlir::filskalang::HltOp,
mlir::filskalang::PrtOp,
mlir::filskalang::SetOp,
mlir::filskalang::SubprogramOp
#endif  // GET_OP_LIST

#ifdef GET_OP_CLASSES
#undef GET_OP_CLASSES

namespace mlir {
namespace filskalang {

static ::mlir::LogicalResult __mlir_ods_local_attr_constraint_Ops0(
    ::mlir::Attribute attr, ::llvm::StringRef attrName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {
  if (attr && !((::llvm::isa<::mlir::StringAttr>(attr))))
    return emitError() << "attribute '" << attrName
        << "' failed to satisfy constraint: string attribute";
  return ::mlir::success();
}
// ...
} // namespace filskalang
} // namespace mlir
MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::filskalang::SubprogramOp)


#endif  // GET_OP_CLASSES

役割の詳細は本題ではないので割愛しますが、ファイル内はマクロ定義によって大きく2つの部分に分かれています。

GET_OP_CLASSES

GET_OP_CLASSES が定義されている場合は、クラスや関数の定義のみ挿入されます。include で想像する一般的な使い方です。

挿入されるコード
namespace mlir {
namespace filskalang {

static ::mlir::LogicalResult __mlir_ods_local_attr_constraint_Ops0( /*...*/) {
    // ...
}
// ...
} // namespace filskalang
} // namespace mlir

GET_OP_CLASSES

一方、GET_OP_CLASSES が定義されている場合は、クラス一覧のみ挿入されます。

挿入されるコード
mlir::filskalang::HltOp,
mlir::filskalang::PrtOp,
mlir::filskalang::SetOp,
mlir::filskalang::SubprogramOp

このクラス一覧は addOperations のテンプレート引数として使用されます。

これが
void FilskalangDialect::initialize() {
  addOperations<
#define GET_OP_LIST
#include "filskalang/CodeGen/Ops.cpp.inc"
      >();
}
こうなる
void FilskalangDialect::initialize() {
  addOperations<
    mlir::filskalang::HltOp,
    mlir::filskalang::PrtOp,
    mlir::filskalang::SetOp,
    mlir::filskalang::SubprogramOp
      >();
}

1つのファイルに異なる2通りの役割を持たせて、マクロによって用途を切り替えていたというわけです。

addOperations のテンプレート引数はDialectにクラスを登録するために使用されています。
想像ですが、この登録を手軽に行えるようにするため上記のような2回includeする設計を取っていると思われます。
https://mlir.llvm.org/doxygen/classmlir_1_1Dialect.html#a60d2c0fbecac1d2f2714b8387466cfaa

  1. ストレンジコード」のFilska言語をMLIRへ移植しています。https://qiita.com/Syuparn/items/e8f4046c4a5b551db310

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?