[GHC] #9387: LLVM backend: redundant code for functions calling themselves
GHC
ghc-devs at haskell.org
Wed Jul 30 17:34:36 UTC 2014
#9387: LLVM backend: redundant code for functions calling themselves
-----------------------------------+---------------------------------------
Reporter: jmoy | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler (LLVM) | Version: 7.6.3
Keywords: | Operating System: Linux
Architecture: x86_64 (amd64) | Type of failure: None/Unknown
Difficulty: Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions:
-----------------------------------+---------------------------------------
It seems that the LLVM backed does not recognize when a function calls
itself. As a result it generates redundant load and store instructions.
I am compiling the following simple recursive Fibonacci function
{{{
fib::Int->Int
fib n
= loop n 0 1
where
loop !n !a !b
= if n==1 then
a
else
loop (n-1) b (a+b)
}}}
I am attaching the files produced by
{{{
ghc -c -O3 -fllvm -ddump-stg -ddump-cmm -ddump-llvm -ddump-to-file Fib.hs
}}}
I rename the generated LLVM file with a `.ll` extension and run `llc -O3`
on it to generate the attached `.s` file (LLVM version 3.4.2).
The actual work gets done in `Fib_zdwloop_info`. It begins as:
{{{
Fib_zdwloop_info: # @Fib_zdwloop_info
# BB#0: # %css
pushq %rax
movq %r13, (%rsp)
movq %rbp, -8(%rsp)
movq %r12, -16(%rsp)
movq %rbx, -24(%rsp)
movq %r14, -32(%rsp)
movq %rsi, -40(%rsp)
movq %rdi, -48(%rsp)
movq %r8, -56(%rsp)
movq %r9, -64(%rsp)
movq %r15, -72(%rsp)
movss %xmm1, -76(%rsp)
movss %xmm2, -80(%rsp)
movss %xmm3, -84(%rsp)
movss %xmm4, -88(%rsp)
movsd %xmm5, -96(%rsp)
movsd %xmm6, -104(%rsp)
}}}
Later on when the function makes a recursive call to itself the code
generated is
{{{
movq -8(%rsp), %rbp
movq -16(%rsp), %r12
movq -24(%rsp), %rbx
movq -32(%rsp), %r14
movq -40(%rsp), %rsi
movq -72(%rsp), %r15
popq %rax
jmp Fib_zdwloop_info # TAILCALL
}}}
Given that the values are being loaded from the stack to the registers in
the second excerpt, it is redundant to re-store the same values into the
stack at the entry of the function.
It seems to me that this is happening because LLVM uses a general function
call instruction to translate a function calling itself. I was wondering
if it is possible to recognize this special case in the LLVM backed or
earlier so that instead of a function call we can translate this as the
LLVM level as a jump to some point after the function entry.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9387>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list