FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

"Creating an LLVM Backend for the Cpu0 Architecture"をやってみる(2. Cpu0の最初のビルド)

f:id:msyksphinz:20181123225150p:plain

Cpu0のインポートを実施したLLVMの最初のビルドを実施してみる。参考にしたのは以下だ。

Cpu0 architecture and LLVM structure — Tutorial: Creating an LLVM Backend for the Cpu0 Architecture

チュートリアルLLVMのバージョンはどうも古いようで、きちんとパッチが当たらない。 いろいろ改造したので、GitHubに7.0.0に対応したものを構築した。

github.com

一番驚いたのは、llvm/Support/ELFRelocs/Cpu0.definclude/llvm/BinaryFormat/ELFRelocs/Cpu0.defに移動されていたこと。 かなり手こずった。

ここから先はLLVM 7.0.0をベースに構築している。

git clone https://github.com/msyksphinz/llvm.git --branch cpu0_chapter2
cd llvm/tools
git clone https://git.llvm.org/git/clang.git -b release_70
cd ../../
mkdir build-cpu0
cmake -G Ninja -DCMAKE_BUILD_TYPE="Debug" --DLLVM_TARGETS_TO_BUILD="Cpu0" ../llvm
cmake --build . -- -j32

無事にビルドが完了する。次に、llcのバージョンを確認する。

./bin/llc --version
$ ./bin/llc --version
LLVM (http://llvm.org/):
  LLVM version 7.0.1
  DEBUG build with assertions.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: haswell

  Registered Targets:
...
    bpfel      - BPF (little endian)
    cpu0       - CPU0 (32-bit big endian)
    cpu0el     - CPU0 (32-bit little endian)
    hexagon    - Hexagon

cpu0が入っていることを確認できた。

次に、以下のプログラムをコンパイルしてみる。LLVM-IRに相当するもの?をllvm-disで生成してみる。

$ cat ch3.cpp
int main()
{
  return 0;
}
./bin/clang -target mips-unknown-linux-gnu -c ch3.cpp -emit-llvm -o ch3.bc
$ ./bin/llvm-dis ch3.bc -o -
; ModuleID = 'ch3.bc'
source_filename = "ch3.cpp"
target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
target triple = "mips-unknown-linux-gnu"

; Function Attrs: noinline norecurse nounwind optnone
define dso_local i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  ret i32 0
}

attributes #0 = { noinline norecurse nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="mips32r2" "target-features"="+mips32r2,-noabicalls" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 7.0.1 (https://git.llvm.org/git/clang.git 64485e37ac4b73bdf0b1834164dee90f7cae2eea) (https://github.com/msyksphinz/llvm.git 5e092d55ef0917451923bc25e05e0b9b50cacff6)"}

とりあえず、それっぽいものが生成できていることは確認できた。

次に、llcコンパイルを行う。ターゲットとしてCpu0を指定した。

./bin/llc -march=cpu0 -relocation-model=pic -filetype=asm ch3.bc -o ch3.cpu0.s

llc: /home/masayuki/others/riscv/llvm/llvm-msyksphinz/tools/llc/llc.cpp:458: int compileModule(char**, llvm::LLVMContext&): Assertion `Target && "Could not allocate target machine!"' failed.
Stack dump:
0.      Program arguments: ./bin/llc -march=cpu0 -relocation-model=pic -filetype=asm ch3.bc -o ch3.cpu0.s
#0 0x00000000038e3a77 llvm::sys::PrintStackTrace(llvm::raw_ostream&) /home/masayuki/others/riscv/llvm/llvm-msyksphinz/lib/Support/Unix/Signals.inc:490:0
#1 0x00000000038e3b08 PrintStackTraceSignalHandler(void*) /home/masayuki/others/riscv/llvm/llvm-msyksphinz/lib/Support/Unix/Signals.inc:554:0
#2 0x00000000038e1b59 llvm::sys::RunSignalHandlers() /home/masayuki/others/riscv/llvm/llvm-msyksphinz/lib/Support/Signals.cpp:67:0
#3 0x00000000038e351c SignalHandler(int) /home/masayuki/others/riscv/llvm/llvm-msyksphinz/lib/Support/Unix/Signals.inc:353:0

"Could not allocate target machine!"というエラーが出てきたが、これは想定内のようだ。 とりあえず、先に進むことにしよう。