[LLVMdev] ARM support status (GHC/ARM new calling convention)

Karel Gardas karel.gardas at centrum.cz
Thu Jun 16 13:35:37 PDT 2011


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:
http://blog.llvm.org/2010/05/glasgow-haskell-compiler-and-llvm.html
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

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ghc-llvm-arm.diff
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110616/4aec0668/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ghc-cc.ll
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110616/4aec0668/attachment-0001.ksh>


More information about the llvm-dev mailing list