LLVMを利用してCbCコンパイラを開発した時のメモ

LLVMを利用してCbCコンパイラを開発した時のメモ

# インストール

  • まずLLVMを取得する。
    • [[llvm.org:http://llvm.org]]から純粋なLLVMを取ってくる場合 (この場合clangも)
1
2
3
 % git clone http://llvm.org/git/llvm.git (保存先。指定しない場合./llvmになる)
 % cd llvm/tools
 % git clone http://llvm.org/git/clang.git
  • 研究室のmercurialからCbCをコンパイルできるよう拡張されたllvmを取ってくる場合
1
 % hg clone ssh://one@www.cr.ie.u-ryukyu.ac.jp/hg/CbC/CbC_llvm (保存先。指定しない場合./CbC_llvmになる)
  • 次にインストール先のディレクトリを作る。ついでにそこに移動。 (!! 必ずCbC_llvmの外に作ってね! !!)
1
2
 % mkdir (いんすとーるするとこ)
 % cd (↑でつくったとこ)

# Cmakeを使う方法

詳しくはcross compilerのとこ

  • cmakeする このときにビルドするディレクトリに移動すること.

llvm-project の直下に llvm と clang がある。llvm の下で cmake する。

1
2
3
4
5
6

   export CC=/usr/local/llvm/bin/clang
   export CXX=/usr/local/llvm/bin/clang++
   export LLVM_DIR=CbC_llvm
   export PATH=$PATH:usr/local/llvm/bin
 %cmake3 -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/cbclang -DLLVM_ENABLE_PROJECTS=clang;lld"  --sysroot=/usr/arm-linux-gnu/sys-root   /src/CbC_llvm  

インストールパスは$PWDで良い

  • ninja
1
  % ninja-build

ちなみにubuntuで行う場合はninja-buildでいれないとaptに登録されているninjaが古いという問題がある

# LLVM 10 on macOS

元から入っているclangではcompileできないので、brew install llvm で入れたものを使う。

1
2
3
   export CC=/usr/local/llvm/bin/clang
   export CXX=/usr/local/llvm/bin/clang++
   cmake ... .../clang

ninja で build すれば良いが MRT.appという macOS のmulware検出システムが暴走してしまう。

1
   sudo launchctl stop com.apple.MRTd

で止めてから build する。

# インストールされたかチェックする。

1
 % (インストールした場所)/Debug+Asserts/bin/clang -v

正しくインストールされていればバージョンが見れるはず。見れたら適当なコードで正しく動くか確認すること。

# インストールしないでllvmのバージョンを調べる方法

makeすると時間かかるからね。

1
 % configure -V

# gdbで動かす場合の手順

  • まず動かすときの引数を得る
1
 % (CbC_LLVM) (source file) -### |& grep cc1

これで実際に実行されるコマンドと引数が取れるので引数だけコピーする。

debug buildであれば SEGV した時に再現用のscriptが生成されるので、それを編集して実行して良い。この時に、include の様子をdebugしたければ Original command の方を用いる。

  • gdbを動かす
1
 % gdb --args (さっきコピーしたものを貼る)

これでうごくはず。正しく動かない場合はmakeがちゃんとできているか、configureのオプションを間違えていないかなどを確認する。

# lldbで動かす場合の手順

実行時の引数は一緒なのでgdbで動かす場合のとこ見て。

  • lldbを動かす
1
 % lldb (clangのパス)
  • 実行
1
 (lldb) r (コピーしたやつ)

# gdbのちょっとしたテクニック

# 何度も引っかかるタイプのブレークポイントの最後の一回が見たいとき

  • まずコンテニューかけまくる
1
 (gdb) c 9999
  • おそらくは9999回もコンテニューせずに実行が終了する。ここでbreak pointの情報を見る
1
 (gdb) info b

見たいとこが何回止まったのかを確認する。already hit 〜 とかかかれているはず。

  • 最後の一回で止まるように仕向ける 通常実行したらさっき見た数字分break pointを通過するということなので、その回数-1回分無視するようにする。
1
 (gdb) ignore (break pointの番号) (さっきの数字-1)

これで止まるはず。

# distcleanについて

LLVMの場合distcleanではなくdist-clean。なのでconfigureからやり直したかったりで綺麗にしたい場合は

1
 % make dist-clean

但し間違ってソースファイルと同じ場所に入れちゃった場合はできない。

##clang ASTを見る方法

1
 % clang -cc1 -ast-dump (source file)

もしくは

1
 % clang -Xclang -ast-dump -c (source file)

# 最終的に生成されるASTと対応したコードの出力方法

1
 % clang -cc1 -ast-print (source file)

内部でコードを生成したときにそれが実際に上手くいったかどうか確認するときとか使える。

# LLVM IRのアセンブリ表現として出力する方法

1
 % clang (source file) -S -emit-llvm

# LLVM IRをlliで実行するためのバイナリとして出力する方法

1
 % llvm-as (アセンブリ表現のbit code)

# Machine Codeを見る方法

1
 % llc -print-machineinstrs (LLVM IR file)

標準エラー出力に出力される。

# CbC on LLVM のアップデート方法

  • まず最新版のLLVM, clangを取得する。
1
2
3
 % git clone http://llvm.org/git/llvm.git (保存先。指定しない場合./llvmになる)
 % cd llvm/tools
 % git clone http://llvm.org/git/clang.git
  • 研究室のmercurialにオリジナルのLLVMを置いたリポジトリがあるので、その中身を最新版で置き換える。
1
2
3
4
 % hg clone ssh://one@www.cr.ie.u-ryukyu.ac.jp/hg/CbC/LLVM_original
 % cd LLVM_original
 % rm -rf ./*
 % mv ../llvm/* ./
  • リポジトリの状態を確認し、消えてるものは消す、新しく増えたものは登録する。
1
2
3
4
5
 % hg status
 % hg remove --after
 % hg add (新しく増えたファイルで必要なもの。)
 % hg commit
 % hg push
  • タグを付ける。
1
 % hg tag -r (リビジョン番号) "LLVM X.X"
  • CbC on LLVM の方のディレクトリに移動し、更新作業を行う。
    • emacs の場合 ediff-merge を使うと少し楽かも。
1
2
3
4
 % cd ../CbC_LLVM
 % hg incoming ../LLVM_original
 % hg pull ../LLVM_original
 % hg merge
  • 動くようになったら commit, push して終了。
1
2
 % hg commit
 % hg push
  • cmake
1
 % cmake -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:PATH=`pwd`   /hg/CbC/LLVM_original 

# memo

# ヘッダファイルが見つからないと言われた時(stdio.h file not found 等)

  • command line tools がインストールされてない可能性があるのでインストールする
  • 以下のようにclangを実行することでclangの見るパスがわかるので確認してみる
1
 % clang -print-search-dirs

# homebrewでのインストール方法

1
2
 % brew tap ie-developers/ie
 % brew install cbc

でcbcがインストールされる。

1
 % brew install cbc --HEAD

でRepositoryのHEADがインストールされる.

# llvm 3.8.0 lldb 用tar ball

http://www.cr.ie.u-ryukyu.ac.jp/software/debug/CbCM.tgz

lldbがソースを見つけられるようにsymbolic link が必要。

1
2
3
  % sudo  mkdir  -p  /Users/kono/src/public
  % sudo   ln -s `pwd`/CbC  /Users/kono/src/public
  % sudo  ln -s `pwd`/CbC_llvm  /Users/kono/src/public

で、

1
  %  sudo lldb -- ./Debug+Asserts/bin/clang -cc1 -S hello.c

l main で main が表示されれば Ok 。

# 最近のLLVMのビルド

  • dalmoreでstdlibが古いと文句を付けられる
    • cmakeの実行時にrpathとLのオプションビルドしたgcc9に指定する
1
$cmake3 -G Ninja -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:PATH=/usr/local/llvm  -DLLVM_ENABLE_PROJECTS="clang;libgcc;libcxx;libcxxabi" -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,/usr/local/gcc9/lib64 -L$HOME/usr/local/gcc9/lib64"  ~/src/LLVM_original/llvm

# テクニック

# helpをもっと表示する

../bin/clang --help-hidden |less

# 実行フェーズを確認する

1
2
3
4
5
6
7
$ ../bin/clang -ccc-print-phases fact-e.c 
            +- 0: input, "fact-e.c", c
         +- 1: preprocessor, {0}, cpp-output
      +- 2: compiler, {1}, ir
   +- 3: backend, {2}, assembler
+- 4: assembler, {3}, object
5: linker, {4}, image

# debug-pass

1
2
3
../bin/clang -O  -mllvm -debug-pass=Arguments fact-e.c 
../bin/clang -O  -mllvm -debug-pass=Structure fact-e.c 
-mllvm -debug-pass=Executions 
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy