FPGA開発日記

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

RISC-V 64-bit LLVM Backendを試す (9. IDAGtoDAGの実装)

LLVMにはすでにRISC-Vのバックエンドサポートが追加されている。しかし、勉強のために独自のRISC-V実装をLLVMに追加している。 前回までで独自アーキテクチャのオプション(MYRISCVX)をllcに表示できるようになった。

実行してみると、アサーションで落ちる問題がある。

$ ./bin/llc -march=myriscvx -relocation-model=pic -filetype=asm ch3.riscv64.bcllc: /home/msyksphinz/work/riscv/llvm-myriscvx64/lib/MC/SubtargetFeature.cpp:179: static void llvm::SubtargetFeatures::ApplyFeatureFlag(llvm::FeatureBitset&, llvm::StringRef, llvm::ArrayRef<llvm::SubtargetFeatureKV>): Assertion `hasFlag(Feature)' failed.
Stack dump:
0.      Program arguments: ./bin/llc -march=myriscvx -relocation-model=pic -filetype=asm ch3.riscv64.bc
#0 0x00007f4634d7373d llvm::sys::PrintStackTrace(llvm::raw_ostream&) /home/msyksphinz/work/riscv/llvm-myriscvx64/lib/Support/Unix/Signals.inc:490:0
#1 0x00007f4634d737d0 PrintStackTraceSignalHandler(void*) /home/msyksphinz/work/riscv/llvm-myriscvx64/lib/Support/Unix/Signals.inc:554:0
#2 0x00007f4634d7150c llvm::sys::RunSignalHandlers() /home/msyksphinz/work/riscv/llvm-myriscvx64/lib/Support/Signals.cpp:67:0

原因を調べていると、どうもFeatureの実装が問題らしい。MYRISCVXArchiFeatureには先頭に-+を付けなければらならないらしい。

commit 9f7fd922439614e40d4c5efc13c44539f50ac1f0 (HEAD -> riscv_msyksphinz)
Author: msyksphinz <msyksphinz_dev@gmail.com>
Date:   Sat Jan 12 13:36:02 2019 +0900

    Bug: fix flag description

diff --git a/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp b/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
index 13459c3b..b0befc56 100644
--- a/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
+++ b/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
@@ -46,7 +46,7 @@ static StringRef selectMYRISCVXArchFeature(const Triple &TT, StringRef CPU) {
   if (CPU.empty() || CPU == "generic") {
     if (TT.getArch() == Triple::myriscvx) {
       if (CPU.empty() || CPU == "myriscvx_impl") {
-        MYRISCVXArchFeature = "myriscvx64";
+        MYRISCVXArchFeature = "+myriscvx64";
       }
     }
   }

さらに、DAGToDAGのパスを追加する。これは、LLVM IRからターゲットのIRに変換するための処理らしい。

以下の資料を参考に実装する。

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

  • lib/Target/MYRISCVX/MYRISCVXInstrInfo.td
let isReturn=1, isTerminator=1, hasDelaySlot=0, isBarrier=1, hasCtrlDep=1 in
def RetLR : MYRISCVXPseudo<(outs), (ins), "", [(MYRISCVXRet)]>;

def RET     : RetBase<GPROut>;

GPROutというのは、汎用レジスタとして使用できるレジスタ群のことで、これを以下のように定義する。Cpu0ではSWを除去しているのだが、MYRISCVXでは汎用レジスタ群はすべて使用できる。

  • lib/Target/MYRISCVX/MYRISCVXGPROutForOther.td
//===----------------------------------------------------------------------===//
// Register Classes
//===----------------------------------------------------------------------===//

def GPROut : RegisterClass<"MYRISCVX", [i32], 32, (add CPURegs)>;
  • lib/Target/MYRISCVX/MYRISCXRegisterInfo.td
//===----------------------------------------------------------------------===//
//@Register Classes
//===----------------------------------------------------------------------===//

def CPURegs : RegisterClass<"MYRISCVX", [i32], 32, (add
  // Reserved
  ZERO,
  // Return Values and Arguments
  A0, A1, A2, A3, A4, A5, A6, A7,
  // Not preserved across procedure calls
  T0, T1, T2, T3, T4, T5, T6,
  // Callee save
  S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11,
  // Reserved
  RA, SP, GP, TP
  )>;

これでビルドを実行してプログラムを実行してみる。

% ./bin/llc -march=myriscvx -relocation-model=pic -filetype=asm ch3.riscv64.bc
Feature = +myriscvx64
Feature = +myriscvx64
ExpandIntegerResult #0: t2: i64 = FrameIndex<0>

Do not know how to expand the result of this operator!
UNREACHABLE executed at /home/masayuki/others/llvm/llvm-myriscvx/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp:1369!
Stack dump:
0.      Program arguments: ./bin/llc -march=myriscvx -relocation-model=pic -filetype=asm ch3.riscv64.bc
1.      Running pass 'Function Pass Manager' on module 'ch3.riscv64.bc'.
2.      Running pass 'MYRISCVX DAG->DAG Pattern Instruction Selection' on function '@main'

Assertionは落ちなくなったが、まだPassが足りないらしい。これから追加していこう。

https://jonathan2251.github.io/lbd/_images/dyn_reg.png