diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-24 15:23:20 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-24 15:23:20 -0700 |
| commit | f49b184a093ab5f653ac36ccc4939c45515a2f4b (patch) | |
| tree | 36b7b0b688a6b03ceb1412fc45f79f32e7540002 /chapter25/README.ja.md | |
| parent | a216a23bbd4d6e05a40d86ec8e76c038e945f3ba (diff) | |
| download | Simple-f49b184a093ab5f653ac36ccc4939c45515a2f4b.tar.gz Simple-f49b184a093ab5f653ac36ccc4939c45515a2f4b.zip | |
Move combined chapter 25 baseline to chapter 28b
Diffstat (limited to 'chapter25/README.ja.md')
| -rw-r--r-- | chapter25/README.ja.md | 110 |
1 files changed, 0 insertions, 110 deletions
diff --git a/chapter25/README.ja.md b/chapter25/README.ja.md deleted file mode 100644 index 4feaee93..00000000 --- a/chapter25/README.ja.md +++ /dev/null @@ -1,110 +0,0 @@ -# 第25章: モジュール、分割コンパイル、SSA 構築 - -[English](README.md) | 日本語 - -この文書は [原文](README.md) の日本語訳です。 - -[前の章: 第24章](../chapter24/README.ja.md) | -[章の一覧](../README.ja.md#各章) - -この章では Simple のソースファイルを再利用可能なオブジェクトファイルへコンパイルし、その型と理想 IR を後のコンパイルに読み込み、別に構築したシステムライブラリとネイティブプログラムをリンクします。また、不完全な情報を扱うため、パーサー、型、メモリ SSA を大幅に再設計します。 - -この番号付きスナップショットは比較用に残しています。章の分割は進行中で、型未確定時の SSA 構築、オブジェクトの構築、エスケープ解析、モジュールを名前付きの章に分けました。[分割計画](../docs/chapter-split.md) と [バックポート待ち一覧](../docs/chapter-backports.md) を参照してください。 - -第21〜24章のメモリ処理はここにも引き継ぎます。Load 検索は読み取りをループ外へ移す前にマージの全枝を証明し、Phi の因数分解はメモリ破壊を確認し、スケジューリングはメモリ集合体を通じてエイリアスをたどります。検索は `EscapeNode` から非公開または公開メモリへ進み、未解決の Store エイリアスを待ちます。配列長の読み取りには要素の境界検査がなく、配列要素の読み取りは制御を保持します。整数値の Phi は、既存の型付き変換機構で、ループの拡大を通じてもロード幅を保持します。New は引き続き非公開のコンストラクタメモリを生成し、公開は Escape が扱います。以前の章の割り当て入力設計は、これを置き換えません。 - -[直線的な履歴](https://github.com/SeaOfNodes/Simple/tree/linear) で [この章](https://github.com/SeaOfNodes/Simple/tree/linear-chapter25) を読み、[第24章と比較](https://github.com/SeaOfNodes/Simple/compare/linear-chapter24...linear-chapter25) することもできます。 - -この章の[完全な言語文法](docs/25-grammar.ja.md)はこちらです。 - -## コンパイル単位と名前 - -`CompUnit` はソースまたはオブジェクトファイルを表します。`ParseAll` は依存関係を発見し、必要なソースを解析し、以前コンパイルした単位を読み込みます。ソースツリーとビルドツリーは対応する相対パスを使い、クラス名はドット区切りのパスを使います。たとえば `a/b/foo.smp` は名前空間 `a.b.foo` を供給します。 - -各単位は Start/Stop ノードを持ちます。関数がコンパイル単位に所有されることと、未知の外部呼び出し側を表す辺とは別です。出力のためにコードを保持することが、任意の呼び出し側から到達できることを意味してはいけません。 - -ドライバは入力パスからプロジェクトルートを推定し、出力の `-o` と外部 Simple オブジェクト検索パスの `-L` を受け付けます。検索パスにはオブジェクトファイルやディレクトリを指定できます。ヘルプには `--root` もありますが、この番号付きスナップショットでは未実装です。名前付きのモジュール章では使用できます。コンパイラはネイティブリンク用の外部 C シンボルも解決します。`_` で始まる名前と外側の名前は、未知の呼び出し元に公開するインターフェースを決めます。 - -明示的な数値型の C 宣言は、可変のネイティブ記憶領域へ直接束縛します。 - -```java -i32 counter = "C"; -counter += 1; -return counter; -``` - -ネイティブリンカが `counter` を解決します。読み書きはその C 変数にアクセスし、宣言はコピーも初期化もしません。繰り返した宣言とモジュールインポートは同じ記憶領域エイリアスを共有します。整数と浮動小数点データの束縛をサポートし、ポインタと集合体のデータ束縛はまだサポートしません。外部フィールドは記憶領域フラグを持ち、宣言元クラス内でバイトを占めません。配置はフィールドオフセットを `ExternOffset` シンボルへ解決し、命令選択はクラス先頭+オフセットをネイティブシンボルアドレスへ置き換えます。ネイティブオブジェクト出力は既存の AMD64 ELF ライタを使い、ARM と RISC-V はメモリ内リンカを通じてこれらのアドレスをサポートします。スレッドローカル変数と C マクロにはアクセサ関数が必要です。システムライブラリは小さなネイティブランタイムアクセサを通じ、`libc.errno()` を公開します。 - -## オブジェクトファイルは理想 IR を含む - -ELF ライタは、ネイティブコードと、正規化された型、理想グラフノード、依存関係を含む `.simple` セクションを保存します。リーダはそのグラフを再構築し、インポートした関数をインライン化などの最適化に参加させます。インライン化せず残った呼び出しは、ネイティブリンクで解決します。 - -`GlobalBits` はファイルの同一性とファイルごとのインデックスを、エイリアス、関数対象、戻り位置の局所的な密なインデックスへ対応付けます。独立したコンパイルの等しい局所番号を、等しい同一性と取り違えてはいけません。読み込み後に型を閉じて更新し、単位をまたぐ循環参照も扱います。 - -シリアライズは、宣言型を精密化されたフロー型とは別に保持します。意味を持つすべてのノード/型のフィールドには、対応する読み書きサポートが必要です。ソースにある高コストなシリアライズの全単射検査は現在無効で、より大きな増分再ビルドテスト `testModule0` は無視されています。どちらも有効な検証保証ではありません。 - -外部フィールドのフラグと記号的オフセットは、シリアライズされた配置を変更します。マジックは `C0DE` のままで、独立した形式バージョンはまだありません。このコンパイラへインポートする前に、すべての Simple オブジェクトファイルを再ビルドしてください。 - -## 型が完成する前の SSA 構築 - -Simple は引き続き AST を介さず直接 SSA に解析します。前方参照により、解析時点では式の最終的な型が利用できない場合があります。そのため構文と解決済みの字句的束縛でトポロジーを選び、後から型でグラフを精密化、最適化、検証します。 - -- 算術ノードは整数モードか浮動小数点モードかの選択を延期し、SCCP 後の再帰的グラフ成分を通じた解決も扱います。 -- Call は呼び出し先の種類が決まる前に、構文上のレシーバスロットを保持します。記号的なフィールド情報は配置依存の判断を延期します。 -- Load と通常の Phi は、パーサーが供給した下限型を持たなくなります。 -- `TypeScalar` は整数、浮動小数点、メモリポインタ、関数ポインタ値を、大域的な制御/メモリのボトムと区別して表します。 -- `TypeStruct._open` は不完全なフィールド集合を記述し、`_fref` は権威ある定義の欠如を記録します。フィールドを発見したことは、型を定義したことではありません。 -- ガードは入力の種類がわかる前に、分岐が証明したゼロ/非ゼロの事実を運びます。`FunPtrNode` は関数の戻りグラフへの明示的な辺を保持します。 - -ドライバはシリアライズとマシン選択の前に、解析、悲観的反復、SCCP、最終型検査を行います。単純でないインライン化は、常に即時のピープホール最適化として行うのではなく、反復と調整します。 - -## メモリと構築 - -パーサーは通常のバルクメモリを保持します。最適化器は `MemMerge`、`MemPhi`、`BulkMemPhi` で正確なエイリアスを復元します。バルク Phi は、並列の正確な Phi で表す除外分以外のすべてのエイリアスを覆います。各スライスはちょうど1回だけ覆われなければなりません。 - -ユーザーコンストラクタは次のように宣言し、呼び出します。 - -```java -struct Box { - i64[] values; - new Box = { i64[] initial -> values = initial; }; -}; -return new Box(new i64[1]); -``` - -宣言で割り当て補助関数を生成します。これは割り当てを行い、隠れた `<init>` とユーザーコンストラクタを順に呼び、`EscapeNode` を通じて初期化済みの非公開メモリを公開します。パーサーの `Var` メタデータは、早すぎるフィールド読み取りやコンストラクタ出口での未初期化を検出します。Store の幅は保存する値ではなく、対象の宣言から得ます。 - -ファイルレベルのコードは、インスタンス初期化とは異なるクラス初期化子(`<clinit>`)で表します。遅延初期化と循環検査については[英語版の説明](README.md#lazy-class-initialization)を参照してください。今後の計画は[英語版ロードマップ](ROADMAP.md#class-initialization-and-compiler-follow-ups)にあります。 - -## システムライブラリと例 - -以前の単一の `sys.smp` ライブラリは、libc 束縛、I/O、文字、スキャナ、配列、伸長可能なバッファ、ビット集合の単位に整理されました。ネイティブドライバは実際のプログラム引数をサポートします。`docs/examples` の例には Bubble Sort、Capitalize、Dijkstra、FileIO があります。 - -`Chapter25Test` は、意図的にインライン化せず残す Hello World 呼び出しを含め、ライブラリ読み込みとネイティブリンクを検証します。そのテストは `sys.o` とリンクする前に、クライアントの外部シンボルを確認します。ほかのテストは前方コンストラクタ、呼び出し経由のフィールド更新、リテラルのエスケープ、縮小したコンパイラ失敗を検証します。独立した回帰テストは以前の章へ移す候補です。 - -## ビルドと確認 - -このディレクトリで `make lib` は Java テスト依存関係を用意し、`make tests` は章の生のスイート、独立スイート、システムテスト、ファザー回帰テストを実行します。`make release` はコンパイラ jar とネイティブライブラリ成果物を構築し、`make tags` はエディタ用タグを構築します。ネイティブツールと選択した CPU/ABI は環境と一致する必要があります。Makefile は現在、既定で x86-64/win64 を使います。 - -シリアライズ IR は `C0DE` ヘッダを使います。ポインタ型は独立した読み取り専用アクセスビットを含みます。形式にはまだバージョン番号がないため、形式を変更したらオブジェクトファイルを再ビルドしてください。現在、後方互換性は保証していません。 - -コンパイラ変更は `sys.o` のシリアライズ IR とネイティブコードの両方を無効にする場合があります。リンクしたプログラムのテスト結果を解釈する前に再ビルドしてください。ソースだけの部分集合は、この章の完全な `make tests` と同等ではありません。 - -## RegAlloc の改良: 生存区間の面積と分割コスト - -第24章はループ Phi の高頻度辺を分割する前に、低頻度のコピーを試しました。この章ではさらに、スピルがスケジュール済みコードのどれだけをレジスタ圧力から解放するかを推定し、新しいコピーの推定コストで割ります。callee-save 区間は関数全体を覆います。複製可能な定数は使用の近くで再構築できます。ループ内のコピーは高コストなので、`8^loopDepth` で重み付けします。特に多数の使用を持つ値については、低コストな近似です。 - -複数の固定レジスタ使用を直接分割する規則や、一部の複数定義区間をより深く分割する規則など、第25章のほかの衝突処理はここに残します。サイズのしきい値はヒューリスティックであり、最初の割り当て器へバックポートすべき一般的不変条件ではありません。共有される合法性修正は、引き続き最も早い該当章から始めます。最終監査は第20〜25章の固定隣接ノードの色バイアス、第20〜21章の狭いストアマスク、第21〜25章の ARM レジスタバンク/浮動小数点メモリエンコーディングを修正しました。 - -第21章の隣接コピー転送も引き継ぎます。次の命令だけで使うコピーは、オペランドがコピー元レジスタを受け入れ、命令の結果に結び付けられていなければ除去します。 - -現在の比較は、固定したテスト群を行、コンパイラの章を列にした -[英語版の測定表](README.md#regalloc-improvements-live-range-area-and-split-cost) を参照してください。 -各セルは ARM/RISC-V の実行命令数、そのうち割り当て器が生成したコピーなどの命令数、 -x86 のループ重み付き移動数を示します。これらは異なる指標です。 -対象、入力、除外項目は [測定方法](../docs/regalloc-spills.md) にあります。 -古い測定群の集計値と混ぜて比較しないでください。 - -クラス初期化、インライン化、エスケープ解析、ライブラリの変更もグラフを変えます。 -章をまたぐ差を割り当て器だけの品質差と解釈せず、同じ入力とコンパイラで -ヒューリスティックを比較してください。 |
