Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 45 additions & 12 deletions .github/workflows/linearize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ git init -q -b main

repo=..

# The donated Japanese index accompanies the English one when present.
readmes=(README.md)
if [[ -f "$repo/README.ja.md" ]]; then
readmes+=(README.ja.md)
fi

last_committer_date='0 +0000'

git -C "$repo" ls-tree HEAD --name-only | grep '^chapter' |
Expand Down Expand Up @@ -47,7 +53,7 @@ while read -r chapter; do
done <<< "$all_authors"

# Get the first and last dates this chapter was modified.
root_files=(README.md LICENSE pom.xml .gitignore .dir-locals.el transpile-tests graph print isa build-support)
root_files=("${readmes[@]}" LICENSE pom.xml .gitignore .dir-locals.el transpile-tests graph print isa build-support)
author_root_files=()
if [[ $chapter = chapter01 ]]; then
# Only include the commit date of the root files for chapter01.
Expand All @@ -65,29 +71,47 @@ while read -r chapter; do
git rm -qr --ignore-unmatch .
cp -R "$repo/$chapter/." .
mkdir -p docs
mv README.md docs/
# Grammar documents now sit beside their chapter README.
for doc in docs/*.md; do
[[ -f "$doc" ]] || continue
sed -Ei 's,\(\.\./README(\.ja)?\.md([#)]),(README\1.md\2,g' "$doc"
sed -Ei 's,\(\.\./\.\./(chapter[0-9]+[a-z]?)/docs/,(../\1/,g' "$doc"
done
# Keep the READMEs and supporting notes together, including Japanese copies.
mv *.md docs/
mv docs chapter_docs
if [[ -d appendix ]]; then
mv appendix chapter_docs/
sed -Ei 's,\(\.\./docs/,(../,g' chapter_docs/appendix/*.md
fi
rm pom.xml || :
git add .

# Add the shared files in the root, except for README.md and pom.xml.
# Add the shared files in the root, except for the indexes and pom.xml.
root_files=(LICENSE .gitignore .dir-locals.el transpile-tests graph print isa build-support)
cp -R "${root_files[@]/#/"$repo/"}" .
git add "${root_files[@]}"

# Fix README.md, docs/chapter??/README.md, and pom.xml.
# Fix the English/Japanese indexes, chapter READMEs, and pom.xml.
if git rev-parse HEAD >/dev/null 2>/dev/null; then
# Restore the documentation and pom.xml from the previous chapter.
git diff --staged --diff-filter=D --name-only -- docs README.md pom.xml | xargs git checkout -q HEAD
git diff --staged --diff-filter=D --name-only -- docs "${readmes[@]}" pom.xml | xargs git checkout -q HEAD
else
# This is the first commit; setup shared files.
cp "$repo"/{README.md,pom.xml} .
cp "${readmes[@]/#/"$repo/"}" "$repo/pom.xml" .
mkdir docs
# Shared type-domain illustrations are referenced from chapter READMEs.
cp "$repo"/docs/type-*.svg docs/
git add docs/type-*.svg
if [[ -f "$repo/docs/japanese-translation.md" ]]; then
cp "$repo/docs/japanese-translation.md" docs/
git add docs/japanese-translation.md
fi
# Remove links to chapters.
sed -Ei 's,\[Chapter ([0-9]+[a-z]?)\]\(chapter0?\1/README\.md\),Chapter \1,' README.md
if [[ -f README.ja.md ]]; then
sed -Ei 's,\[([^]]+)\]\(chapter[0-9]+[a-z]?/README(\.ja)?\.md\),\1,g' README.ja.md
fi
# Change to a JAR and delete the modules, for a single-project structure.
sed -i -e 's,<packaging>pom</packaging>,<packaging>jar</packaging>,' \
-e '/<modules>/,/^$/d' pom.xml
Expand All @@ -107,13 +131,22 @@ while read -r chapter; do
git mv chapter_docs "docs/$chapter"
# Restore the link to this chapter.
sed -Ei "s,^\* Chapter $chapter_number: ,* [Chapter $chapter_number](docs/$chapter/README.md): ," README.md
if [[ -f README.ja.md ]]; then
translated=README.md
if [[ -f "docs/$chapter/README.ja.md" ]]; then
translated=README.ja.md
fi
sed -Ei "s,^\* 第${chapter_number}章:,* [第${chapter_number}章](docs/$chapter/$translated):," README.ja.md
fi
# Repair links for this chapter.
sed -Ei 's,\bdocs/,,' "docs/$chapter/README.md"
sed -Ei 's,\(\.\./isa/,(../../isa/,g' "docs/$chapter/README.md"
# Source links are chapter-relative in the main tree; sources live at the
# repository root in a standalone chapter checkout.
sed -Ei 's,\((\./)?src/,(../../src/,g' "docs/$chapter/README.md"
git add README.md "docs/$chapter/README.md" pom.xml
for doc in "docs/$chapter"/README*.md; do
sed -Ei 's,\bdocs/,,g' "$doc"
sed -Ei 's,\(\.\./(isa|graph|print)/,(../../\1/,g' "$doc"
sed -Ei 's,\(\.\./README(\.ja)?\.md([#)]),(../../README\1.md\2,g' "$doc"
# Sources live at the root in a standalone chapter checkout.
sed -Ei 's,\((\./)?src/,(../../src/,g' "$doc"
done
git add "${readmes[@]}" "docs/$chapter" pom.xml

# Create a commit for the chapter, using the metadata.
if [[ ! "$first_author" =~ ^(.*)\ \<(.*)\>$ ]]; then
Expand Down
102 changes: 102 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Simple

[English](README.md) | 日本語 | [翻訳について](docs/japanese-translation.md)

この文書は [Simple の README](README.md) の日本語訳です。

Sea of Nodes コンパイラ中間表現(IR)を紹介する Simple

このリポジトリは、Sea of Nodes コンパイラ IR を実演するためのものです。

Sea of Nodes は、HotSpot の C2 コンパイラ、Google の V8 コンパイラ、
Sun/Oracle の Graal コンパイラで使われる中核的な IR です。

SoN IR の紹介が目的なので、実装する*言語*そのものの重要性は高くありません。
C や Java に似た、機能がずっと少ない非常に単純な言語を使います。
Simple は強い型付けを持つオブジェクト指向言語で、*クロージャ*ではなく*関数*が第一級の値です。
オブジェクト参照はポインタであり、型システムによって null ポインタ例外を禁止します。
配列にもいずれ範囲チェックが導入されると考えられ、その場合 Simple は完全に安全な言語になります。
Simple の構文は最小限で、再帰下降パーサーで解析できます。

実用システムでは Sea of Nodes を機械語生成に使いますが、
この実演ではバックエンドの実装は難しく、重要性も比較的低くなります。
このリポジトリは x86-64、RISC-V、ARM64 を対象に事前(AOT)コンパイルを行いますが、
JIT コンパイルも視野に入れています。

このリポジトリは、どの意味でも完全な言語を目指してはいません。
そのため、バックエンドは SoN IR を直接解釈する Java の評価器から始まります
(第8章で初めて導入します)。コード生成は第19章で初めて登場します。

## 各章

以下は大まかな計画であり、変更されることがあります。

各章は自己完結した完全な実装です。Simple 言語の一部を完全に実装し、
前の章で作成したものをすべて含みます。また、各章には Sea of Nodes
中間表現の関連する側面について詳しい解説を付けます。

Simple 言語のスタイルは、C または Java のサブセットに倣っています。

* [第1章](chapter01/README.ja.md):整数リテラルを返すスクリプト。引数を受け取らず、整数値を1つ返す空の関数。`return` 文。
* [第2章](chapter02/README.ja.md):定数を使う加算、減算、乗算、除算などの単純な二項算術演算。ピープホール最適化と単純な定数畳み込み。
* [第3章](chapter03/README.ja.md):ローカル変数と代入文。右辺での読み取り、SSA、ローカル変数が定数の場合の追加のピープホール最適化。
* [第4章](chapter04/README.ja.md):`arg` という名前の、定数ではない外部入力変数。定数と `arg` を使う二項演算と比較演算。ゼロ以外の値は真とみなします。代数的簡約によるピープホール最適化。
* [第5章](chapter05/README.ja.md):`if` 文。制御フローグラフ(CFG)の構築。
* [第6章](chapter06/README.ja.md):実行されない制御フローに対するピープホール最適化。
* [第7章](chapter07/README.ja.md):`while` 文。ループ構造と先行的な Phi の導入。
* [第8章](chapter08/README.ja.md):ループ構造の続き。必要時の Phi の生成、`break` 文と `continue` 文。
* [第9章](chapter09/README.ja.md):大域的値番号付け。不動点に達するまでのピープホール最適化の反復。ワークリスト。
* [第10章](chapter10/README.ja.md):ユーザー定義の構造体、ポインタ、null 解析。SSA で表す単一のメモリ値。ロード、ストア、実行可能な評価器。
* [第11章](chapter11/README.ja.md):同値類によるエイリアス解析。`MemMerge`、`MemPhi`、`BulkMemPhi` による必要時のメモリ分割。
* [第12章](chapter12/README.ja.md):参照フィールド、前方参照、再帰的な構造体。
* [第13章](chapter13/README.ja.md):大域的コード移動とスケジューリング。
* [第14章](chapter14/README.ja.md):数値型。浮動小数点数、狭い整数型、範囲、`f32` への丸め。
* [第15章](chapter15/README.ja.md):静的な長さを持つ一次元配列型。配列のロードとストア。
* [第16章](chapter16/README.ja.md):コンストラクタ。
* [第17a章](chapter17a/README.ja.md):束縛の可変性、参照の権限、深い読み取り専用ビュー。
* [第17b章](chapter17b/README.ja.md):糖衣構文。`var`、`val`、`x+=y`、`for(init; test; next) body`。
* [第18章](chapter18/README.ja.md):関数と呼び出し。
* [第19章](chapter19/README.ja.md):命令選択と移植可能なコンパイル。
* [第20章](chapter20/README.ja.md):グラフ彩色によるレジスタ割り当て。
* [第21章](chapter21/README.ja.md):命令エンコーディングと ELF。
* [第22章](chapter22/README.ja.md):Simple の Hello, World!
* [第23章](chapter23/README.ja.md):メソッドと型の再検討。
* [第24章](chapter24/README.ja.md):連鎖した条件分岐と SCCP。
* [第25章](chapter25/README.ja.md):モジュール、分割コンパイル、不完全な型を使う SSA の構築。

## 章をまたぐビルド

任意で使える[対話的なグラフビューア(英語)](graph/README.md)は `graph/` で共有しています。
第1〜25章では、章のディレクトリで `make view` を実行して起動します。

[デバッグ用プリンタ(英語)](print/README.md)は `print/` で共有しています。
第2章で必要なのは1行の式形式だけです。共通の `BaseNode` が、プリンタとビューアの両方に
ノードの同一性とエッジへのアクセスを提供します。IR が拡張されるにつれて、
各章のアダプタが意味に関する詳細を追加します。

[命令エンコーダ(英語)](isa/README.md)は、第21〜25章の x86-64、ARM、RISC-V の
バイト出力処理と、ARM/RISC-V のテスト用評価器を共有します。
機械命令ノードの選択、レジスタ割り当て、コード配置は各章に残ります。
共通層は具体的なオペランドを受け取り、バイト列を書き出します。

最上位の Makefile は、各章の `tests`、`tags`(または `tag`)、`release`、`lib` ターゲットを実行します。
新しく取得したチェックアウトでは、まず `make lib`、続いて `make tests` を実行してください。

CI は Linux と JDK 21 で `make lib tests CTAGS=` を実行します。
Make のターゲットは、それらを使うテストの実行前に、第25章のネイティブランタイムと
`sys` ライブラリもビルドします。Maven の Java ビルドだけでは、これらの前提となる成果物は生成されません。

[章へのバックポート一覧(英語)](docs/chapter-backports.md)には、提案された小さな修正と
各章のテスト・レビューワークフローを記録しています。大規模なアーキテクチャ変更は、そこで別に管理します。
第10〜14章は現在、メモリ全体、必要時のエイリアス分割、参照、GCM、数値型の順に構成されています。
このメモリ表現は第25章まで引き継がれています。

メモリに関する章だけをビルドしてテストするには、次を実行します。

```sh
make lib tests release CHAPTERS="chapter10 chapter11 chapter12"
```

ルートの Maven リアクターはすべての章を含みます。
第10〜14章には、共通の `graph` と `print` モジュールに依存する、移植可能な IDEA モジュール記述子があります。
Make と直線的な履歴を作るワークフローは、番号付きの章ディレクトリを検出します。
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Simple
English | [日本語](README.ja.md)

A Simple showcase for the Sea-of-Nodes compiler IR

This repo is intended to demonstrate the Sea-of-Nodes compiler IR.
Expand Down
Loading
Loading