Hello,
I'm working on implementing GHC specific call convention into LLVM 2.9. I've chosen LLVM 2.9 as a kind of stable reference point and I would like to know how mature is ARM code generation chain inside this release. I've had a hope that perhaps Apple as a main sponsor of LLVM is using LLVM for their ARM based iOS software development, but I'm not sure if I'm right at this.
Anyway what I need to do is already done for x86/x64 by David Terei last year. He describes it well here:
and he submitted the patch here:
http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20100307/714e5c37/attachment-0001.obj
Please bear with me, I'm neither LLVM nor GHC nor ARM expert but this is my own hobby project to start learning at least Haskell and ARM. My current state of the work is attached in the form of patch against LLVM 2.9. Basically speaking I'm just trying to mimic work done by David for x86 and do the similar thing for ARM. This is also the case of ghc-cc.ll testcase which I've directly got from David's x64 version -- so instructions with CHECK/CHECK-NEXT are still from x86. I just would like to get testcase run through the llc which is still not the case. In fact llc crashes with:
(gdb) set args < /export/home/karel/vcs/llvm-2.9/test/CodeGen/ARM/ghc-cc.ll -tailcallopt -mtriple=arm-linux-gnu
(gdb) run
Starting program: /export/home/karel/vcs/llvm-2.9/Debug/bin/llc < /export/home/karel/vcs/llvm-2.9/test/CodeGen/ARM/ghc-cc.ll -tailcallopt -mtriple=arm-linux-gnu
warning: Lowest section in /lib/libpthread.so.1 is .dynamic at 00000074
.syntax unified
.eabi_attribute 6, 2
.eabi_attribute 8, 1
.eabi_attribute 9, 1
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.file "<stdin>"
.text
.globl zap
.align 2
.type zap,%function
zap: @ @zap
@ BB#0: @ %entry
push {r4, r5, lr}
mov r4, r0
mov r5, r1
bl addtwo
bl foo
pop {r4, r5, lr}
bx lr
.Ltmp0:
.size zap, .Ltmp0-zap
.globl addtwo
.align 2
.type addtwo,%function
addtwo: @ @addtwo
@ BB#0: @ %entry
str lr, [sp, #-4]!
add r4, r4, r5
ldr lr, [sp], #4
bx lr
.Ltmp1:
.size addtwo, .Ltmp1-addtwo
UNREACHABLE executed!
Program received signal SIGABRT, Aborted.
0xfeda2945 in _lwp_kill () from /lib/libc.so.1
(gdb) where
#0 0xfeda2945 in _lwp_kill () from /lib/libc.so.1
#1 0xfed9b27c in thr_kill () from /lib/libc.so.1
#2 0xfed49f4a in raise () from /lib/libc.so.1
#3 0xfed2197c in abort () from /lib/libc.so.1
#4 0x08fc40fa in llvm::llvm_unreachable_internal (msg=0x0, file=0x0, line=0) at ErrorHandling.cpp:99
#5 0x08bcbf19 in llvm::CCState::AnalyzeCallOperands (this=0x8045c80, Outs=@0x8046350,
Fn=0x88c7838 <ARM_AAPCS_GHC>) at CallingConvLower.cpp:126
#6 0x088cb08a in llvm::ARMTargetLowering::LowerCall (this=0x92b4c58, Chain=
{Node = 0x92d1b50, ResNo = 0}, Callee={Node = 0x92d1c60, ResNo = 0},
CallConv=llvm::CallingConv::GHC, isVarArg=false, isTailCall=@0x804656b, Outs=@0x8046350,
OutVals=@0x8046230, Ins=@0x8045f30, dl={LineCol = 0, ScopeIdx = 0}, DAG=@0x92bdea8,
InVals=@0x80461f0) at ARMISelLowering.cpp:1209
#7 0x08aece19 in llvm::TargetLowering::LowerCallTo (this=0x92b4c58, Chain=
{Node = 0x92d1b50, ResNo = 0}, RetTy=0x92aee1c, RetSExt=false, RetZExt=false, isVarArg=false,
isInreg=false, NumFixedArgs=7, CallConv=llvm::CallingConv::GHC, isTailCall=false,
isReturnValueUsed=false, Callee={Node = 0x92d1c60, ResNo = 0}, Args=@0x80468d0, DAG=@0x92bdea8,
dl={LineCol = 0, ScopeIdx = 0}) at SelectionDAGBuilder.cpp:6135
#8 0x08ae73df in llvm::SelectionDAGBuilder::LowerCallTo (this=0x92be358, CS=
{<llvm::CallSiteBase<const llvm::Function,const llvm::Value,const llvm::User,const llvm::Instruction,const llvm::CallInst,const llvm::InvokeInst,const llvm::Use*>> = {I = {Value = 153830658}}, <No data fields>}, Callee={Node = 0x92d1c60, ResNo = 0}, isTailCall=true, LandingPad=0x0)
at SelectionDAGBuilder.cpp:4880
#9 0x08ae9302 in llvm::SelectionDAGBuilder::visitCall (this=0x92be358, I=@0x92b4500)
at SelectionDAGBuilder.cpp:5211
#10 0x08acfc5c in llvm::SelectionDAGBuilder::visit (this=0x92be358, Opcode=45, I=@0x92b4500)
at /export/home/karel/vcs/llvm-2.9/include/llvm/Instruction.def:161
#11 0x08acf7be in llvm::SelectionDAGBuilder::visit (this=0x92be358, I=@0x92b4500)
at SelectionDAGBuilder.cpp:864
#12 0x08b02903 in llvm::SelectionDAGISel::SelectBasicBlock (this=0x92bdb50, Begin=
{<std::iterator<std::bidirectional_iterator_tag,const llvm::Instruction,ptrdiff_t,const llvm::Instruction*,const llvm::Instruction&>> = {<No data fields>}, NodePtr = 0x92b41ac}, End=
{<std::iterator<std::bidirectional_iterator_tag,const llvm::Instruction,ptrdiff_t,const llvm::Instruction*,const llvm::Instruction&>> = {<No data fields>}, NodePtr = 0x92af688},
HadTailCall=@0x8046c7b) at SelectionDAGISel.cpp:432
#13 0x08b0442e in llvm::SelectionDAGISel::SelectAllBasicBlocks (this=0x92bdb50, Fn=@0x92b3f50)
at SelectionDAGISel.cpp:981
#14 0x08b01f7c in llvm::SelectionDAGISel::runOnMachineFunction (this=0x92bdb50, mf=@0x92ce000)
at SelectionDAGISel.cpp:307
#15 0x08c0ddc3 in llvm::MachineFunctionPass::runOnFunction (this=0x92bdb50, F=@0x92b3f50)
at MachineFunctionPass.cpp:33
#16 0x08f18f30 in llvm::FPPassManager::runOnFunction (this=0x92ba4d8, F=@0x92b3f50)
at PassManager.cpp:1483
#17 0x08f190c3 in llvm::FPPassManager::runOnModule (this=0x92ba4d8, M=@0x92b3428)
at PassManager.cpp:1503
#18 0x08f193b5 in llvm::MPPassManager::runOnModule (this=0x92b8438, M=@0x92b3428)
at PassManager.cpp:1557
#19 0x08f197ad in llvm::PassManagerImpl::run (this=0x92b8288, M=@0x92b3428) at PassManager.cpp:1638
#20 0x08f19cde in llvm::PassManager::run (this=0x8047030, M=@0x92b3428) at PassManager.cpp:1682
#21 0x086e8ed1 in main (argc=3, argv=0x8047170) at llc.cpp:341
(gdb)
it seems my modified LLVM does not like passing i32 type argument into function @foo. If I comment out line:
%6 = load i32* @splim
llc does not crash. Also in the llvm::ARMTargetLowering::LowerCall I see a comment about disabling tailcalls just to not break things.
I'm quite curious if this is still the case since tailcalls are used in GHC, that's also the reason why I ask about status of LLVM on ARM platform above. If the status is all right, then could someone here be so kind and guide me thorough the LLVM doc and recommend what to read and what not in order to perform my task of LLVM modification for GHC calling convention on ARM platform? So far I'm just blindly attempting to fix things which just crashes... Also is there any way how to convince llc to support -debug argument? I've build debug build, but it looks like -debug is missing...
Thanks a lot!
Karel
ghc-llvm-arm.diff (4.36 KB)
ghc-cc.ll (2.76 KB)