[GHC] #5997: GHC fails to make function tail recursive
GHC
cvs-ghc at haskell.org
Wed Apr 11 16:15:42 CEST 2012
#5997: GHC fails to make function tail recursive
------------------------------+---------------------------------------------
Reporter: Khudyakov | Owner:
Type: bug | Status: new
Priority: normal | Component: Compiler
Version: 7.4.1 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: None/Unknown | Testcase:
Blockedby: | Blocking:
Related: |
------------------------------+---------------------------------------------
Sometimes GHC does not compile function as tail recursive despite it looks
like tail recursive. Here is simplified example.
{{{
{-# LANGUAGE BangPatterns #-}
incompleteBetaWorker :: Double -> Double
incompleteBetaWorker _ = loop 1 1 1 1
where
-- Constants
eps = 1e-15
-- Loop
loop :: Double -> Int -> Double -> Double -> Double
loop !psq !ns !term !betain
| done = betain'
| otherwise = loop psq' (ns - 1) term' betain'
where
-- New values
term' = term
betain' = betain
psq' = if ns < 0 then psq + 1 else psq
-- This condition cause stack overflow
done = db <= eps && db <= eps*betain' where db = abs term'
-- With this it loops endlessly
-- done = db <= eps * betain' where db = abs term'
main :: IO ()
main = print $ incompleteBetaWorker 0
}}}
If second equation for done is used function is tail recursive and works
in constant space. if first one (uncommented) is used it isn't. From
looking at the it looks loop is converted to several corecursive
functions.
Such loops appear frequently in numerical code and it's important to
ensure that worker function is tail recursive since getting answer may
require a lot of iteration.
I've tested it with GHC 7.2.2 and 7.4.1. Both are affected. Example was
compiled with -O2.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5997>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list