FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages/

高速C++コンパイラZapccの試行(1. 現プロジェクトのインポート)

https://www.zapcc.com/wp-content/uploads/2018/06/xcopy-zapcc-logo.png.pagespeed.ic.HTEiBd-jW-.webp

興味本位ではあるが、高速C++コンパイラとしてオープンソース化されたZapccが非常に気になっている。

LLVMがベースとなっていることだし、いつも新しいコンパイラプラットフォームが公開されたときはRISC-Vの対応について見てしまうので、アーキテクチャの移行という点でもどのようなものなのか気になっている。現状のC++プロジェクトをZapccに移行して試行してみることにした。

Zapcc – A (Much) Faster C++ Compiler

そもそもZapccは何故高速なのか

以下の記事を見るといろいろと書いてある。

Caching Clang-Based C++ Compiler Zapcc Open-Sourced

Zapccの高速化におけるカギとなるアイデアは、コンパイルサーバ(zapccs)を用意するということだ。 このコンパイルサーバはメモリチュウに常駐し、クライアントからコンパイルコマンドを受け付ける。 zapccsはC+ヘッダファイルを一度だけ解析し、すべてのテンプレートインスタンスと、生成されたコードをメモリ中に保持する。 この点について、zapccは、ステロイド剤としてプリコンパイルされたヘッダの類を使用しているとみることができるが、プリコンパイルされたヘッダよりも多くの情報をメモリ中にキャッシュすることができる。

ははあ、コンパイルアルゴリズムがどうのこうのというより、コンパイルフロー中で生成されるファイル群をより多くメモリ中に保持することで高速化を図っているのか。

既存のプロジェクトをZapccに移行する

ここでは、開発中の自作RISC-Vシミュレータを、

  1. GCC
  2. LLVM/Clang
  3. Zapcc

の順番で移行してみることにした。移行方法としては、CMakeを使っているのでターゲットコンパイラを変えるだけである。

$ cmake . -DCMAKE_CXX_COMPILER=[ターゲットC++コンパイラ] && make -j4

Clangへの移行

GCC→Clangの移行は簡単に終わった。

$ cmake . -DCMAKE_CXX_COMPILER=clang++ && make -j4

一方で、Clang→Zapccでは最後のリンク時に怒られてしまった。これはなんでだろう?

$ cmake . -DCMAKE_CXX_COMPILER=zapcc++ && make -j4
...
/usr/bin/cmake -E cmake_link_script CMakeFiles/riscvforest.dir/link.txt --verbose=1
/home/msyksphinz/work/zapcc/build/bin/zapcc++   -O0 -g -Wall -fstack-protector -g  -rdynamic CMakeFiles/riscvforest.dir/home/msyksphinz/work/forest/riscv_forest_zapcc/src/swimmer_main.cpp.o CMakeFiles/riscvforest.dir/home/msyksphinz/work/forest/riscv_forest_zapcc/src/ris
cv_bfd_env.cpp.o  -o riscvforest  -L/home/msyksphinz/work/forest/riscv_forest_zapcc/build_riscvforest/../vendor/gflags/lib  -L/home/msyksphinz/work/forest/riscv_forest_zapcc/build_riscvforest/../vendor/softfloat/build -Wl,-rpath,/home/msyksphinz/work/forest/riscv_forest_
zapcc/build_riscvforest/../vendor/gflags/lib:/home/msyksphinz/work/forest/riscv_forest_zapcc/build_riscvforest/../vendor/softfloat/build libriscv_cedar.a -lgflags -lpthread -lbfd -lsoftfloat -lgmp -lgmpxx
libriscv_cedar.a(inst_ops_riscv.cpp.o): In function `InstOps::FloatMadd(int, int, int, unsigned int*)':
/home/msyksphinz/work/forest/riscv_forest_zapcc/src/inst_ops_riscv.cpp:693: undefined reference to `f32_mul(float32_t, float32_t)'
/home/msyksphinz/work/forest/riscv_forest_zapcc/src/inst_ops_riscv.cpp:693: undefined reference to `f32_add(float32_t, float32_t)'
libriscv_cedar.a(inst_ops_riscv.cpp.o): In function `InstOps::FloatAdd(int, int, unsigned char, unsigned int*)':