Submit Search
Upload
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
•
Download as PPTX, PDF
•
1 like
•
2,296 views
uchan_nos
Follow
OpeLa プロジェクトの概要と OpeLa 言語、コンパイラの内部仕様を紹介します。2021 年 7 月の Kernel/VM online3 向けの発表資料です。
Read less
Read more
Software
Report
Share
Report
Share
1 of 41
Download now
Recommended
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
Scapyで作る・解析するパケット
Scapyで作る・解析するパケット
Takaaki Hoyo
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
VirtualTech Japan Inc.
初心者がOpenIndianaで自宅サーバを作ったよって話
初心者がOpenIndianaで自宅サーバを作ったよって話
Masataka Tsukamoto
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす
Akihiro Suda
30分で分かる!OSの作り方
30分で分かる!OSの作り方
uchan_nos
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
30分でわかる! コンピュータネットワーク
30分でわかる! コンピュータネットワーク
Trainocate Japan, Ltd.
Recommended
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
Scapyで作る・解析するパケット
Scapyで作る・解析するパケット
Takaaki Hoyo
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
OpenStackをコマンドで攻める! 構築・運用とトラブル解決 - OpenStack最新情報セミナー 2014年6月
VirtualTech Japan Inc.
初心者がOpenIndianaで自宅サーバを作ったよって話
初心者がOpenIndianaで自宅サーバを作ったよって話
Masataka Tsukamoto
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす
Akihiro Suda
30分で分かる!OSの作り方
30分で分かる!OSの作り方
uchan_nos
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
30分でわかる! コンピュータネットワーク
30分でわかる! コンピュータネットワーク
Trainocate Japan, Ltd.
Redisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
Protocol Buffers 入門
Protocol Buffers 入門
Yuichi Ito
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
Masahito Zembutsu
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
Akihiro Suda
PenTesterが知っている危ないAWS環境の共通点
PenTesterが知っている危ないAWS環境の共通点
zaki4649
Play with UEFI
Play with UEFI
Takuya ASADA
Nmap 9つの真実
Nmap 9つの真実
abend_cve_9999_0001
目grep入門 +解説
目grep入門 +解説
murachue
不揮発メモリ(NVDIMM)とLinuxの対応動向について
不揮発メモリ(NVDIMM)とLinuxの対応動向について
Yasunori Goto
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
Tomoya Kawanishi
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
Fixstars Corporation
DPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキング
Tomoya Hibi
How to run P4 BMv2
How to run P4 BMv2
Kentaro Ebisawa
Kibanaでsysstatを可視化する
Kibanaでsysstatを可視化する
Kensuke Maeda
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
Developers Summit
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
Kumazaki Hiroki
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
Dockerイメージ管理の内部構造
Dockerイメージ管理の内部構造
Etsuji Nakai
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
Let's join in OpsWorks world!
Let's join in OpsWorks world!
Shigeo Nakano
More Related Content
What's hot
Redisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
Protocol Buffers 入門
Protocol Buffers 入門
Yuichi Ito
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
Masahito Zembutsu
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
Akihiro Suda
PenTesterが知っている危ないAWS環境の共通点
PenTesterが知っている危ないAWS環境の共通点
zaki4649
Play with UEFI
Play with UEFI
Takuya ASADA
Nmap 9つの真実
Nmap 9つの真実
abend_cve_9999_0001
目grep入門 +解説
目grep入門 +解説
murachue
不揮発メモリ(NVDIMM)とLinuxの対応動向について
不揮発メモリ(NVDIMM)とLinuxの対応動向について
Yasunori Goto
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
Tomoya Kawanishi
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
Fixstars Corporation
DPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキング
Tomoya Hibi
How to run P4 BMv2
How to run P4 BMv2
Kentaro Ebisawa
Kibanaでsysstatを可視化する
Kibanaでsysstatを可視化する
Kensuke Maeda
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
Developers Summit
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
Kumazaki Hiroki
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
Dockerイメージ管理の内部構造
Dockerイメージ管理の内部構造
Etsuji Nakai
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
What's hot
(20)
Redisの特徴と活用方法について
Redisの特徴と活用方法について
Protocol Buffers 入門
Protocol Buffers 入門
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
PenTesterが知っている危ないAWS環境の共通点
PenTesterが知っている危ないAWS環境の共通点
Play with UEFI
Play with UEFI
Nmap 9つの真実
Nmap 9つの真実
目grep入門 +解説
目grep入門 +解説
不揮発メモリ(NVDIMM)とLinuxの対応動向について
不揮発メモリ(NVDIMM)とLinuxの対応動向について
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
C++ マルチスレッド 入門
C++ マルチスレッド 入門
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
マルチレイヤコンパイラ基盤による、エッジ向けディープラーニングの実装と最適化について
DPDKによる高速コンテナネットワーキング
DPDKによる高速コンテナネットワーキング
How to run P4 BMv2
How to run P4 BMv2
Kibanaでsysstatを可視化する
Kibanaでsysstatを可視化する
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
【B-4】オープンソース開発で、フリー静的解析ツールを使ってみる
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Dockerイメージ管理の内部構造
Dockerイメージ管理の内部構造
冬のLock free祭り safe
冬のLock free祭り safe
Similar to OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
Let's join in OpsWorks world!
Let's join in OpsWorks world!
Shigeo Nakano
クラウド開発に役立つ OSS あれこれ
クラウド開発に役立つ OSS あれこれ
Masataka MIZUNO
Eclipse xtext 紹介
Eclipse xtext 紹介
Akira Tanaka
Clrh 110827 wfho
Clrh 110827 wfho
Tomoyuki Obi
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
Koichi Sakata
Startup JavaScript
Startup JavaScript
Akinari Tsugo
Mt basic as-os_on_danbot
Mt basic as-os_on_danbot
たけおか しょうぞう
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Ransui Iso
Linuxのsemaphoreとmutexを見る
Linuxのsemaphoreとmutexを見る
wata2ki
running-elixir-in-production
running-elixir-in-production
Tsunenori Oohara
Introduction of Python
Introduction of Python
Tomoya Nakayama
入門 シェル実装
入門 シェル実装
Yusuke Sangenya
オペレーティングシステム 第1回-公開用
オペレーティングシステム 第1回-公開用
Ruo Ando
Pythonの非同期処理を始める前に
Pythonの非同期処理を始める前に
koralle
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
Hideki Takase
NAO/Pepper 開発環境 について
NAO/Pepper 開発環境 について
Takuji Kawata
clominal
clominal
Masamitsu Oikawa
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Akiko Kosaka
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Kenji Hiranabe
Similar to OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
(20)
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Let's join in OpsWorks world!
Let's join in OpsWorks world!
クラウド開発に役立つ OSS あれこれ
クラウド開発に役立つ OSS あれこれ
Eclipse xtext 紹介
Eclipse xtext 紹介
Clrh 110827 wfho
Clrh 110827 wfho
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
Startup JavaScript
Startup JavaScript
Mt basic as-os_on_danbot
Mt basic as-os_on_danbot
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Linuxのsemaphoreとmutexを見る
Linuxのsemaphoreとmutexを見る
running-elixir-in-production
running-elixir-in-production
Introduction of Python
Introduction of Python
入門 シェル実装
入門 シェル実装
オペレーティングシステム 第1回-公開用
オペレーティングシステム 第1回-公開用
Pythonの非同期処理を始める前に
Pythonの非同期処理を始める前に
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
NAO/Pepper 開発環境 について
NAO/Pepper 開発環境 について
clominal
clominal
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
Tohnaka Giri Ninjo Programmer Tohnaka at AgileJpan 2011
More from uchan_nos
MikanOSと自作CPUをUSBで接続する
MikanOSと自作CPUをUSBで接続する
uchan_nos
OSを手作りするという趣味と仕事
OSを手作りするという趣味と仕事
uchan_nos
小型安価なFPGAボードの紹介と任意波形発生器
小型安価なFPGAボードの紹介と任意波形発生器
uchan_nos
トランジスタ回路:エミッタ接地増幅回路
トランジスタ回路:エミッタ接地増幅回路
uchan_nos
自作言語でお絵描き
自作言語でお絵描き
uchan_nos
OpeLa 進捗報告 at 第23回自作OSもくもく会
OpeLa 進捗報告 at 第23回自作OSもくもく会
uchan_nos
サイボウズ・ラボへ転籍して1年を振り返る
サイボウズ・ラボへ転籍して1年を振り返る
uchan_nos
USB3.0ドライバ開発の道
USB3.0ドライバ開発の道
uchan_nos
Security Nextcamp remote mob programming
Security Nextcamp remote mob programming
uchan_nos
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPS
uchan_nos
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作
uchan_nos
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装
uchan_nos
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG
uchan_nos
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free os
uchan_nos
Building libc++ for toy OS
Building libc++ for toy OS
uchan_nos
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019
uchan_nos
Introduction of security camp 2019
Introduction of security camp 2019
uchan_nos
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2
uchan_nos
Timers
Timers
uchan_nos
USB3 host driver program structure
USB3 host driver program structure
uchan_nos
More from uchan_nos
(20)
MikanOSと自作CPUをUSBで接続する
MikanOSと自作CPUをUSBで接続する
OSを手作りするという趣味と仕事
OSを手作りするという趣味と仕事
小型安価なFPGAボードの紹介と任意波形発生器
小型安価なFPGAボードの紹介と任意波形発生器
トランジスタ回路:エミッタ接地増幅回路
トランジスタ回路:エミッタ接地増幅回路
自作言語でお絵描き
自作言語でお絵描き
OpeLa 進捗報告 at 第23回自作OSもくもく会
OpeLa 進捗報告 at 第23回自作OSもくもく会
サイボウズ・ラボへ転籍して1年を振り返る
サイボウズ・ラボへ転籍して1年を振り返る
USB3.0ドライバ開発の道
USB3.0ドライバ開発の道
Security Nextcamp remote mob programming
Security Nextcamp remote mob programming
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPS
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free os
Building libc++ for toy OS
Building libc++ for toy OS
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019
Introduction of security camp 2019
Introduction of security camp 2019
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2
Timers
Timers
USB3 host driver program structure
USB3 host driver program structure
OpeLa: セルフホストなOSと言語処理系を作るプロジェクト
1.
OpeLa セルフホストなOSと言語処 理系を作るプロジェクト Kernel/VM探検隊online part3 2021年7月10日 @uchan_nos
2.
自己紹介 内田公太 @uchan_nos サイボウズ・ラボ株式会社 OSと言語処理系の研究開発 趣味:自作OSコミュニティ「osdev-jp」の運営 著書: ゼロからのOS自作入門 自作エミュレータで学ぶx86アーキテクチャ
3.
本日の発表のコンセプト 誰 何 と言ってもらいたい! 言語処理系やOSの自作やセルフホスト に興味がある人に OpeLaプロジェクトの存在と中身を知り 自分も設計や開発に参加してみたい
4.
目次 MikanOSとOpeLa OpeLa言語 OpeLaコンパイラの内部 構文に関する考察
5.
OpeLaとは……の前に、MikanOSとは 「ゼロからのOS自作入門」で作る サンプルOS 30章で作れる! 現代的な構成 UEFIによる起動 64ビットモード プリエンプティブマルチタスク ページングによるメモリ管理 FAT32ファイルシステム パイプ、リダイレクト 日本語の教科書が完備された、現 代的なPCで動作する教育用OS MikanOSの30章後の姿
6.
MikanOSはまだまだ進化中 「ゼロからのOS自作入門」の最後のバージョンを元に、GitHub上 で開発継続中 タスクバーの時計 マンデルブロ集合の描画アプリ USB CDCデバイスの(一部)サポート 各種バグ修正 プルリクエスト大歓迎 有用なプルリクなら受け取ります 見ていて面白いアプリ、便利なアプリ アプリが必要とするシステムコール ドキュメント、OSのロゴ これまでに(uchan除く)7人からプルリクを受け付けた
7.
改めて、OpeLaとは Operating & Language
processing system OSと言語処理系のセルフホストを目指すプロジェクト 言語処理系:コンパイラ、アセンブラ、リンカ、ライブラリ等 セルフホスト:自分自身をビルドすること GCC on LinuxでGCCとLinuxをビルドすることと同類 自作OS 自作言語処理系 OSの ソース コード 言語処 理系の ソース コード Linux GCC Linuxの ソース コード GCCの ソース コード
8.
OpeLaプロジェクトの目的 OS:MikanOSを採用予定 教科書が完備されていて学習しやすい 言語処理系:新しく作る 現在はOpeLaコンパイラを実装中 セルフホストを目指すことで、自ずと必要な機能が定まってくる OS:言語処理系が動く程度の機能 言語処理系:言語処理系やOSを記述できる程度の機能 1. コンピュータが動く仕組みを深く学びたい人の教材となる 2. uchanの技術的興味を満たす +
OpeLa
9.
OpeLaプロジェクトで作る物と順序 1. セルフホストなOpeLaコンパイラ(C++で実装) 2. アセンブラ、リンカ(OpeLaで実装) この時点で言語処理系が全部自作に切り替わる 3.
ビルドツール(makeみたいなやつ) 4. MikanOSをOpeLa言語に移植 5. 言語処理系にMikanOS向けアプリ生成オプション追加 6. 言語処理系をMikanOSに移植 作った物をできるだけ活用する、という方針で順序を決定
10.
目次 MikanOSとOpeLa OpeLa言語 OpeLaコンパイラの内部 構文に関する考察
11.
OpeLa言語 OSを書くための言語(ついでにアプリも書ける) 言語機能はCに近く、構文はGoに近い セフルホストを目指し、C++ on Ubuntuで実装中 設計と実装は道半ば func
main() int { printf("hello, worldn"); } extern "C" printf func(*byte, ...) int;
12.
OpeLaコンパイラの現状 OpeLaコンパイラの機能を一覧するなら、テストケース https://github.com/uchan-nos/opela/blob/master/compiler/v2/test.opl テストケース自体をOpeLa言語で実装してある 2021/07/05現在の主要な機能 四則演算、制御構文(if, for)、変数定義 任意ビット幅整数、ポインタ、配列、構造体、型変換 ジェネリック関数 同梱してるサンプルアプリ rpn: 逆ポーランド記法計算機 list:
線形リストの実装サンプル sdl: SDL2を使った画面表示デモ
13.
SDL2を使ったデモアプリ カーソルキーでロゴ 移動 スペースキーで背景 色変更 外部関数呼び出し機 能でSDLの関数を呼 び出す Cのヘッダファイル を読めないので、構 造体は自前で定義
14.
OpeLa言語の特徴 OSを書くために設計されている 「uint3」などの任意ビット幅の整数型 「アドレス型」という、整数とポインタのあいのこの型 構造体に関連する特殊な機能 マルチタスク未サポートで使えるコルーチン CPU固有命令をネイティブにサポート
15.
アドレス型 「@」は型変換演算子で、「値 @ 型」と使う address型の値は、任意のポインタに代入可能 Cのvoid*のような役目 アドレス値を直書きしている箇所をgrepしやすい! func
notifyEndOfInterrupt() { // 組み込みのアトミック読み書き関数を使ってレジスタアクセス var eoi *uint32 = 0xfee000b0 @ address; AtomicStore(eoi, 0); // same as: AtomicStore(0xfee000b0@address@*uint32, 0) }
16.
構造体に関連する特殊な機能 Offsetフィールドは分割されている 後方互換性のための工夫 type idtEntry packed_struct
{ Offset(15:0) address16; SegmentSelector uint16; IST uint3; _ uint5; Type uint4; _ uint1; DPL uint2; P uint1; Offset(31:16) address16; Offset(63:32) address32; _ uint32; };
17.
構造体に関連する特殊な機能 Offset(msb:lsb)でビット範囲を指定 共通の接頭辞がグループ化される Offsetは1つのフィールドを構成する グループ化されたフィールドは、連続 であるかのように読み書きできる idt[21] = { .Offset
= &intHandler21, .SegmentSelector = 1 * 8 .Type = 14, .DPL = 0, .P = 1 }; type idtEntry packed_struct { Offset(15:0) address16; SegmentSelector uint16; IST uint3; _ uint5; Type uint4; _ uint1; DPL uint2; P uint1; Offset(31:16) address16; Offset(63:32) address32; _ uint32; };
18.
OpeLa言語の設計方針 OSを書くために便利な機能を入れる セルフホストを達成するために必要な機能を入れる OSを書くのに不要な機能は入れない 例外やGCなど 機能の選択はバランスを考える 機能追加 コスト 機能の 便利さ
19.
目次 MikanOSとOpeLa OpeLa言語 OpeLaコンパイラの内部 構文に関する考察
20.
Ver.1とVer.2 OpeLaコンパイラは大きく2つのバージョンがある Ver.1: 2020年に作っていたスタックマシン型コンパイラ Ver.2: 2021年から作っているレジスタマシン型コンパイラ 機能は(やっと)Ver.2
> Ver.1 性能も Ver.2 > Ver.1
21.
スタックマシンでのコード生成 OpeLaコンパイラVer.1のコード生成は愚直に木をたどる Gen(N): // ノードを評価し、結果をスタックにPush If
N is 整数リテラル: Push(N) Else: Gen(Left) Gen(Right) Pop(RDI) Pop(RAX) Op(RAX, RDI) Push(RAX) ノードを評価した結果は、必ずスタックトップに書かれる N L R
22.
具体例:1+2+3 push 1 push 2 pop
rdi pop rax add rax, rdi push rax push 3 pop rdi pop rax add rax, rdi push rax + 1 2 3 + 抽象構文木 出力コード コンパイル対象の式 1+2+3
23.
愚直にレジスタマシンに変換してみる スタックにPushする代わりに、レジスタにMov Gen(R1, N): //
ノードを評価し、結果をレジスタR1に格納 If N is 整数リテラル: Mov(R1, N) Else: Gen(R1, Left) R2 = GetFreeReg() Gen(R2, Right) Op(R1, R2) AddFreeReg(R2) ノードの評価値の格納先をGenの引数で指定する N L R
24.
レジスタ消費が少ないケース 左側にだけ発達している木に対し、出力コードは次の通り mov rax, 1 mov
r10, 2 add rax, r10 mov r10, 3 add rax, r10 mov r10, 4 add rax, r10 レジスタ消費は高々2 + 1 2 + 3 + 4 RAX R10 RAX RAX RAX R10 R10 抽象構文木 出力コード コンパイル対象の式 1+2+3+4
25.
レジスタ消費が多いケース 右側に発達している木に対し、出力コードは次の通り mov rax, 1 mov
r10, 2 mov r11, 3 mov rdi, 4 add r11, rdi add r10, r11 add rax, r10 レジスタ消費は高々4 明らかに無駄なレジスタ割り付け + 4 3 + 2 + 1 RAX RAX R10 R10 R11 R11 RDI 抽象構文木 出力コード コンパイル対象の式 1+(2+(3+4))
26.
レジスタ割り付け戦略 A) スタックマシンとして構成したコンパイラを、愚直にレジスタマ シンに変換する 木の形によっては容易にレジスタが枯渇 レジスタが枯渇したらメモリに逃がす(spill) B) スタックマシンでIRを出力し、後からレジスタ割り付け IRでは仮想レジスタ(無限個ある)を使う IRを読み、仮想レジスタと物理レジスタの対応を頑張って決める C)
スタック使用を許しつつも、ある程度の最適化を達成する D) 木のたどり方を工夫して最適なレジスタ割り付けを決める
27.
最適なレジスタ割り付けを決める Ershov数を使うアルゴリズム 「コンパイラ―原理・技法・ツール」より Ershov数=そのノードを評価するのに必要なレジスタの数 + 6 5 + + + 3 2 2 1 1 3 1 2 1 2 1 1 1. すべての葉のラベルを「1」とする 2.
1つの子だけ持つ中間ノードのラベルは、 子と同じ数値とする 3. 2つの子を持つ中間ノードのラベルは a. 子の数値が異なる→大きい方と同じ数値 b. 子の数値が等しい→それより1大きい数値 Ershov数の求め方
28.
実装して実験 OpeLaコンパイラに実装して実験した echo 'func main()
int { return (1+2) + ((3+4) + (5+6)); }' | ./opelac mov eax, 3 mov edi, 4 add rax, rdi mov edi, 5 mov esi, 6 add rdi, rsi add rax, rdi mov edi, 1 mov esi, 2 add rdi, rsi add rax, rdi 生成された計算プログラムは 3つのレジスタを使う最適なものになった ※eaxなどのレジスタを使うのは 演算順序とは関係ない最適化を施したため
29.
Ver.1とVer.2の性能比較 func main() int
{ return fib(40) != 102334155; } func fib(n int) int { if n <= 1 { return n; } else { return fib(n-1) + fib(n-2); } } コンパイラ 実行時間 (5回の最良) アセンブラ行数 OpeLa Ver.1 1.36秒 104 OpeLa Ver.2 0.629秒 69 GCC 10.2 -O0 0.664秒 GCC 10.2 -O3 0.170秒 Python3 28.6秒 Core i7 1165G7 2.80GHz/32.0GB RAM/Ubuntu 20.04 on WSL2 使用したOpeLaは6/30の時点のもの コミットID eb6fd5643447858094263bb7d744de74189440ac GCC -O0に勝った!
30.
目次 MikanOSとOpeLa OpeLa言語 OpeLaコンパイラの内部 構文に関する考察
31.
定義を後置できることによる難しさ OpeLaでは変数、関数、型の定義を後置 できる 識別子を見た時点では区別できない Cの型変換は紛らわしい (foo)(bar) fooが変数名ならfooの評価結果を使った関数 呼び出し fooが型名なら型変換 ジェネリクスが登場するとなお難しい foo<bar>(0) (foo < bar)
> 0 かもしれない func main() MyInt { return Add(2, 3); } func Add(a, b int) int { return a + b; } type MyInt int64;
32.
型変換の構文 OpeLaでの型変換は「値 @ 型」 x
:= 42@int8; xは8ビット整数型となる @はC/C++で奇跡的に空いてる演算子だった ダブルミーニング 型変換→Cast→cAsT→AT→@ 型→Kata→kATa→@
33.
ジェネリクスの構文 C++では foo<bar> 構文解析時に意味解析の結果(fooやbarが指すものの情報)が必要 Rustでは foo::<bar> 通常は値を期待している文脈で型を指定するとき、::<>を使う ::<>
Turbofish構文(魚ロケット) OpeLaでは foo@<bar> 型変換演算子を拡張し、型リストを取れるようにした 「@の後ろには型が来る」という一貫性ある拡張
34.
協力者募集
35.
OpeLaプロジェクトは協力者募集中です OpeLaプロジェクトのロゴ製作 言語の設計に関する議論の話し相手 ex「a==bで両辺の型が違うとき、どこまで暗黙的な型変換を許すか」 OpeLa言語を使ったサンプルアプリ開発 コンパイラ開発 コンパイラのAArch64移植 アセンブラ、リンカ、ライブラリ、ビルドツール開発 OpeLa言語へのMikanOS移植 興味ある方はお声かけください。開発用Slackにご招待します。
36.
まとめ MikanOSとOpeLa OpeLaはセルフホストなOSと言語処理系を作るプロジェクト OpeLa言語 OSを書くのに便利な機能(アドレス型とか)がある OpeLaコンパイラの内部 Ershov数を用いたレジスタ割り当て 構文に関する考察 後方定義、型演算子@ 協力者募集
37.
質疑応答用スライド
38.
Ershov数を使ったコード生成 準備 レジスタに通し番号を振る:R[0], R[1], …… コード生成 ルートから開始し、再帰的に実行 ラベルkを持つ中間ノードのコード生成は、k個のレジスタだけを使う •
番号のベース値「b」から始まるk個:R[b], R[b+1], …… R[b+k-1] • 評価結果は常にR[b+k-1]に格納される + 6 5 + + + 3 2 2 1 1 3 1 2 1 2 1 1 0 1 2 評価結果が格納されるレジスタ
39.
2つの子のラベルが等しい場合 1. ベース値「b+1」を使い、右辺のコードを再帰的に生成 結果はR[b+k-1]に格納されることになる 2.
ベース値「b」を使い、左辺のコードを再帰的に生成 結果はR[b+k-2]に格納されることになる 3. Op(R[b+k-1], R[b+k-2]) + 6 5 + + + 3 2 2 1 1 2 1 2 1 1 評価対象ノードのラベルを「k」とすると、子のラベルは「k-1」である 0 1 2 0 1 2 0 2 1 0 1 2 0 1 2 0 2 1
40.
2つの子のラベルが異なる場合 1. ベース値「b」を使い、大きな子のコードを再帰的に生成 結果はR[b+k-1] 2.
ベース値「b」を使い、小さな子のコードを再帰的に生成 子のラベルをmとすると、結果はR[b+m-1] m<kなのでR[b+k-1]は使用されない 3. Op(R[b+k-1], R[b+m-1]) あるいは Op(R[b+m-1], R[b+k-1]) Mov(R[b+k-1], R[b+m-1]) 大きな子が左右どちらにあるかに応じて + 6 5 + + 3 2 2 1 1 評価対象ノードのラベルを「k」とすると、 大きい方の子は「k」、小さい方の子は「k-1」 0 1 2 0 1 2 0 2 1 1 3 m=1 <2
41.
Ver.1とVer.2の出力コードの比較 mov qword ptr
[rbp+-8], rdi push rax lea rax, [rbp-8] push qword ptr [rax] push 1 pop rdi pop rax cmp rax, rdi setle al movzx eax, al push rax pop rax test rax, rax jz LABEL0 mov qword ptr [rbp-8], rdi mov rax, qword ptr [rbp-8] mov edi, 1 cmp rax, rdi setle al movzx eax, al test rax, rax jz LABEL1 OpeLa Ver.1の出力 OpeLa Ver.2の出力 func fib(n int) int { if n <= 1 { return n; } else { 今回注目する部分
Download now