LLVM 10.0がリリースされた。メジャーバージョンアップの頻度が3か月に1回程度となっており追いかけるのも大変だ。 また、メジャーバージョンがアップデートされる度にAPIの仕様が大きく変更されており、プロジェクトを移行させるのも並大抵ではない。
LLVMのバックエンドに自作ターゲットアーキテクチャを追加するプロジェクト、これまではLLVM 8.0ベースで作業していたものを10.0ベースに移行するとどうなるのか、一応作業記録として残しておくことにした。
LLVM 8.0をベースに組み立てた作業コミットを、cherry-pickしながら10.0ベースに移行するだけの話じゃないのか、というとそれだけの簡単な話ではなく、いろいろAPIの修正が必要となる。すべての作業を終えてコンパイルが成功するのを確認するのに丸一日かかってしまったので、作業記録として残しておくことにした。
ちなみに、複数のGitコミットログをまとめてcherry-pickするのは以下の記事が参考になる。
この記事にある通り、注意点としては始点となるGitコミットの1つ前のコミットを指定すること。
TargetFrameLowering
の仕様変更
llvm/lib/Target/MYRISCVX/MYRISCVXFrameLowering.h
In file included from /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXSubtarget.h:17, from /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXTargetMachine.h:18, from /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXTargetMachine.cpp:15: /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXFrameLowering.h: In constructor 'llvm::MYRISCVXFrameLowering::MYRISCVXFrameLowering(const llvm::MYRISCVXSubtarget&)': /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXFrameLowering.h:32:18: error: no matching function for call to 'llvm::TargetFrameLowering::TargetFrameLowering(llvm::TargetFrameLowering::StackDirection, int, int)' STI(sti) { ^
アライメントを示す引数がint
型からAlign
型に変更になっている。
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl = Align::None(), bool StackReal = true) : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl), LocalAreaOffset(LAO), StackRealignable(StackReal) {}
- 解決方法
引数をAlign()
型でラップする。
explicit MYRISCVXFrameLowering(const MYRISCVXSubtarget &sti) : TargetFrameLowering(StackGrowsDown, /*StackAlignment=*/Align(16), /*LocalAreaOffset=*/0), STI(sti) { }
同様に、setMinFuncitonAlignment()
も修正しないとエラーが発生する。
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXISelLowering.cpp:72:28: error: no matching function for call to 'llvm::MYRISCVXTargetLowering::setMinFunctionAlignment(int)' setMinFunctionAlignment(2); In file included from /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXISelLowering.h:24, from /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXISelLowering.cpp:14: /home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/include/llvm/CodeGen/TargetLowering.h:2106:8: note: candidate: 'void llvm::TargetLoweringBase::setMinFunctionAlignment(llvm::Align)' void setMinFunctionAlignment(Align Alignment) { ^~~~~~~~~~~~~~~~~~~~~~~
修正後:
//- Set .align 2 // It will emit .align 2 later const Align FunctionAlignment(2); setMinFunctionAlignment(FunctionAlignment);
getFrameRegister()
getFrameRegister()
の仕様変更。戻り値の方の修正など。
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXRegisterInfo.h:52:14: error: conflicting return type specified for 'virtual unsigned int llvm::MYRISCVXRegisterInfo::getFrameRegister(const llvm::MachineFunction&) const' unsigned getFrameRegister(const MachineFunction &MF) const override; ^~~~~~~~~~~~~~~~
これまでunsigned int
で指定指定たレジスタの情報をRegister
型に置き換えることで修正する。
Register MYRISCVXRegisterInfo:: getFrameRegister(const MachineFunction &MF) const { const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); return TFI->hasFP(MF) ? (MYRISCVX::FP) : (MYRISCVX::SP); }
copyPhysReg()
の仕様変更
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXInstrInfo.h:54:8: error: 'void llvm::MYRISCVXInstrInfo::copyPhysReg(llvm::MachineBasicBlock&, llvm::MachineBasicBlock::iterator, const llvm::DebugLoc&, unsigned int, unsigned int, bool) const' marked 'override', but does not override void copyPhysReg(MachineBasicBlock &MBB, ^~~~~~~~~~~
引数の型がいくつか変更になっており修正する。
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DstReg, unsigned SrcReg, bool KillSrc) const override;
修正後:
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) const override; void MYRISCVXInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) const {
make_unique()
がこのままでは使えない
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MYRISCVXTargetMachine.cpp:82:12: error: 'make_unique' was not declared in this scope TLOF(make_unique<MYRISCVXTargetObjectFile>()), ^~~~~~~~~~~
//- Default is big endian : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS, Options, getEffectiveRelocModel(JIT, RM), getEffectiveCodeModel(CM, CodeModel::Small), OL), TLOF(make_unique<MYRISCVXTargetObjectFile>()), ABI(MYRISCVXABIInfo::computeTargetABI(Options.MCOptions.getABIName())), DefaultSubtarget(TT, CPU, FS, *this) { initAsmInfo();
修正後:
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT,
CPU, FS, Options, getEffectiveRelocModel(JIT, RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(std::make_unique<MYRISCVXTargetObjectFile>()),
ABI(MYRISCVXABIInfo::computeTargetABI(Options.MCOptions.getABIName())),
DefaultSubtarget(TT, CPU, FS, *this) {
initAsmInfo();
printInst()
の修正
これも仕様が変更となっている。
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/InstPrinter/MYRISCVXInstPrinter.h:37:10: error: 'void llvm::MYRISCVXInstPrinter::printInst(const llvm::MCInst*, llvm::raw_ostream&, llvm::StringRef, const llvm::MCSubtargetInfo&)' marked 'override', but does not override void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, ^~~~~~~~~
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override;
以下のように修正を加える。結構抜本的に変更となっている。
void MYRISCVXInstPrinter::printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) { // Try to print any aliases first. if (!printAliasInstr(MI, O)) //@1 } //- printInstruction(MI, O) defined in MYRISCVXGenAsmWriter.inc which came from // MYRISCVX.td indicate. printInstruction(MI, Address, O); printAnnotation(O, Annot); }
createMYRISCVXMCAsmInfo()
の仕様変更
引数が追加となっている。
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp:131:54: error: invalid conversion from 'llvm::MCAsmInfo* (*)(const llvm::MCRegisterInfo&, const llvm::Triple&)' to 'llvm::Target::MCAsmInfoCtorFnTy' {aka 'llvm::MCAsmInfo* (*)(const llvm::MCRegisterInfo&, const llvm::Triple&, const llvm::MCTargetOptions&)'} [-fpermissive] RegisterMCAsmInfoFn X(*T, createMYRISCVXMCAsmInfo); ^
static MCAsmInfo *createMYRISCVXMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT) { MCAsmInfo *MAI = new MYRISCVXMCAsmInfo(TT); unsigned SP = MRI.getDwarfRegNum(MYRISCVX::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
変更後。MCTargetOptions &Options
を引数として追加したが使っていない。これでいいのか?
static MCAsmInfo *createMYRISCVXMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT, const MCTargetOptions &Options) { MCAsmInfo *MAI = new MYRISCVXMCAsmInfo(TT); unsigned SP = MRI.getDwarfRegNum(MYRISCVX::SP, true); MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0); MAI->addInitialFrameState(Inst); return MAI; }
InstPrinterの廃止とMCTargetDescへの移行
これが一番手こずった。vtable
の不足。これがなんだか良く分からない。必要な関数はすべて追加したと思うのだが...
/home/msyksphinz/work/llvm/llvm-myriscvx100/llvm/lib/Target/MYRISCVX/InstPrinter/MYRISCVXInstPrinter.h:30: undefined reference to `vtable for llvm::MYRISCVXInstPrinter'
色々試行した他結果、どうやらInstPrinter
ディレクトリは廃止されており、その代わりにInstPrinter.{h,cpp}
はMCTargetDesc
ディレクトリに移動する必要があるらしい。そのための修正を行う。
最終的に、lib/Target/MYRISCVX
以下のサブディレクトリはMCTargetDesc
とTargetInfo
の2つとなった。
ここまでで、無事にビルドが終了するようになった。
$ tree . -L 1 . |-- CMakeLists.txt |-- LLVMBuild.txt |-- MCTargetDesc |-- MYRISCVX.h |-- MYRISCVX.td |-- MYRISCVXAsmPrinter.cpp |-- MYRISCVXAsmPrinter.h |-- MYRISCVXCallingConv.td |-- MYRISCVXFrameLowering.cpp |-- MYRISCVXFrameLowering.h |-- MYRISCVXISelDAGToDAG.cpp |-- MYRISCVXISelDAGToDAG.h |-- MYRISCVXISelLowering.cpp |-- MYRISCVXISelLowering.h |-- MYRISCVXInstrFormats.td |-- MYRISCVXInstrInfo.cpp |-- MYRISCVXInstrInfo.h |-- MYRISCVXInstrInfo.td |-- MYRISCVXMCInstLower.cpp |-- MYRISCVXMCInstLower.h |-- MYRISCVXMachineFunction.cpp |-- MYRISCVXMachineFunction.h |-- MYRISCVXRegisterInfo.cpp |-- MYRISCVXRegisterInfo.h |-- MYRISCVXRegisterInfo.td |-- MYRISCVXSchedule.td |-- MYRISCVXSubtarget.cpp |-- MYRISCVXSubtarget.h |-- MYRISCVXTargetMachine.cpp |-- MYRISCVXTargetMachine.h |-- MYRISCVXTargetObjectFile.cpp |-- MYRISCVXTargetObjectFile.h `-- TargetInfo