Slide 1

Slide 1 text

TableGenと和解せよ 2023/08/21 Ando Shin / @Arata

Slide 2

Slide 2 text

TableGenとは ● コンパイラ基盤LLVMの内部で使用されているDSL ● レジスタや命令など、ターゲットマシン固有の情報を 記述するために用いられることが多い ● 一般にはC++のコードに変換される 2

Slide 3

Slide 3 text

https://github.com/llvm/llvm-project/blob/1c822e1e8278ebefdb7701249bdfe51f1ed03d7d/llvm/lib/Target/X86/X86RegisterInfo.td#L163-L184 例: TableGenでX86のレジスタを記述 3

Slide 4

Slide 4 text

TableGen嫌われがち問題 4

Slide 5

Slide 5 text

● エディタの支援を受けられない ● 情報がまとまっていない ● C++と組み合わせてのビルドに手間がかかる なぜTableGenは嫌われているのか 5

Slide 6

Slide 6 text

● エディタの支援を受けられない ● 情報がまとまっていない ● C++と組み合わせてのビルドに手間がかかる なぜTableGenは嫌われているのか 6

Slide 7

Slide 7 text

2022年5月から言語サーバーが実装され始める 今日までに実装された機能: ● シンタックスハイライト ● エラー表示 ● 定義へ移動 ● 参照へ移動 ● ホバー表示 エディタ支援の現状 7

Slide 8

Slide 8 text

2022年5月から言語サーバーが実装され始める 今日までに実装された機能: ● シンタックスハイライト ● エラー表示 ● 定義へ移動 ● 参照へ移動 ● ホバー表示 コードの入力補完が実装されていない エディタ支援の現状 8

Slide 9

Slide 9 text

入力補完を実装した 9

Slide 10

Slide 10 text

● 言語サーバーの応答性が悪い ● 一部のコードで支援機能を提供できない ● 内部実装が言語サーバー向きではない 現状の言語サーバーの問題点 10

Slide 11

Slide 11 text

エラー表示・補完候補が更新されるまで時間がかかる様子 問題点1: 言語サーバーの応答性が悪い 11

Slide 12

Slide 12 text

考えられる原因: ● 言語サーバーがシングルスレッドで動いている ● パースと同時に評価を行っている ○ コードが変更されるたびにすべてのシンボルの解決処理が走る 問題点1: 言語サーバーの応答性が悪い 12

Slide 13

Slide 13 text

● これはコード側に原因がある ● includeが適切に行われないためシンボルを解決できない 問題点2: 一部のコードで支援機能を提供できない 13 A.td B.td ※Registerはllvm/Target/Target.tdで定義

Slide 14

Slide 14 text

コードの構造を保持するための方法にASTとCSTがある ● AST: Abstract Syntax Tree (rustcで使われる) ● CST: Concrete Syntax Tree (rust-analyzerで使われる) TableGenではASTが使われているため、以下の問題がある ● トークンの場所やコメントなどの情報が失われてしまう ● 構文エラーがあった場所でパースが止まってしまう 問題点3: 内部実装が言語サーバー向きではない 14

Slide 15

Slide 15 text

RustでTableGenの新たな言語サーバーを実装しています 目指すところ: ● キャッシュを使った処理の高速化 ● エラーからの回復機能を持つパーサーの実装 ● 一般的な支援機能の実装 ● (TableGenのパーサーを提供して誰かがTableGen2.0を 作ってくれることを期待) 今していること 15