Question

I have the following program and it won't compile; it just gets stuck at Compiling Main. I am not sure why it freezes as it is either a bug or I am missing something?

import qualified Data.Vector.Unboxed as V

test :: [Int]
test = V.foldl' unique [] k
 where 
    n = 10000000
    k = V.generate n (\i -> i `div` 1000 * 1000)
    unique [] k = [k]
    unique acc@(ck:_) k
        | k == ck = acc
        | otherwise = k:acc     

main :: IO ()
main = print $ head test

ghc --make -O3 -Odph -fllvm test.hs

Was it helpful?

Solution

Yes, I think this is the bug: https://ghc.haskell.org/trac/ghc/ticket/5550

Using -v, you can see that GHC hangs when doing the SpecConstr optimization:

ghc-7.6.3 test.hs -O2 -fforce-recomp -v
Glasgow Haskell Compiler, Version 7.6.3, stage 2 booted by GHC version 7.0.4
Using binary package database: /nix/store/x5rdp4smhc6q3rxbw4x1akj10z3h0lvg-haskell-env-ghc-7.6.3/lib/ghc-7.6.3/package.conf.d/package.cache
hiding package Cabal-1.16.0 to avoid conflict with later version Cabal-1.18.1.3
hiding package QuickCheck-2.6 to avoid conflict with later version QuickCheck-2.7.3
hiding package binary-0.5.1.1 to avoid conflict with later version binary-0.7.1.0
wired-in package ghc-prim mapped to ghc-prim-0.3.0.0-d5221a8c8a269b66ab9a07bdc23317dd
wired-in package integer-gmp mapped to integer-gmp-0.5.0.0-2f15426f5b53fe4c6490832f9b20d8d7
wired-in package base mapped to base-4.6.0.1-02ac91ff7de681afee6a8fa62f0c87f3
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.8.0.0-0cee70fbb279a3d93dcc4ec502790a2b
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags: -static
*** Chasing dependencies:
Chasing modules from: *test.hs
Stable obj: []
Stable BCO: []
Ready for upsweep
  [NONREC
      ModSummary {
         ms_hs_date = 2014-04-15 18:43:29 UTC
         ms_mod = main:Main,
         ms_textual_imps = [import (implicit) Prelude,
                            import qualified Data.Vector.Unboxed as V]
         ms_srcimps = []
      }]
*** Deleting temp files:
Deleting: 
compile: input file test.hs
Created temporary directory: /tmp/ghc23870_0
*** Checking old interface for main:Main:
[1 of 1] Compiling Main             ( test.hs, test.o )
*** Parser:
*** Renamer/typechecker:
*** Desugar:
Result size of Desugar (after optimization)
  = {terms: 55, types: 44, coercions: 0}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 46, types: 34, coercions: 5}
Result size of Simplifier iteration=2
  = {terms: 48, types: 40, coercions: 5}
Result size of Simplifier = {terms: 48, types: 40, coercions: 5}
*** Specialise:
Result size of Specialise = {terms: 48, types: 40, coercions: 5}
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = False}):
Result size of Float out(FOS {Lam = Just 0,
                              Consts = True,
                              PAPs = False})
  = {terms: 66, types: 58, coercions: 5}
*** Float inwards:
Result size of Float inwards = {terms: 66, types: 58, coercions: 5}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 76, types: 66, coercions: 36}
Result size of Simplifier iteration=2
  = {terms: 71, types: 60, coercions: 26}
Result size of Simplifier = {terms: 71, types: 60, coercions: 26}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 143, types: 113, coercions: 33}
Result size of Simplifier iteration=2
  = {terms: 99, types: 79, coercions: 30}
Result size of Simplifier = {terms: 99, types: 79, coercions: 30}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 120, types: 88, coercions: 26}
Result size of Simplifier iteration=2
  = {terms: 90, types: 64, coercions: 16}
Result size of Simplifier iteration=3
  = {terms: 88, types: 63, coercions: 16}
Result size of Simplifier = {terms: 88, types: 63, coercions: 16}
*** Demand analysis:
Result size of Demand analysis
  = {terms: 88, types: 63, coercions: 16}
*** Worker Wrapper binds:
Result size of Worker Wrapper binds
  = {terms: 108, types: 80, coercions: 23}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 100, types: 72, coercions: 13}
Result size of Simplifier iteration=2
  = {terms: 91, types: 58, coercions: 9}
Result size of Simplifier = {terms: 91, types: 58, coercions: 9}
*** Float out(FOS {Lam = Just 0, Consts = True, PAPs = True}):
Result size of Float out(FOS {Lam = Just 0,
                              Consts = True,
                              PAPs = True})
  = {terms: 93, types: 59, coercions: 9}
*** Common sub-expression:
Result size of Common sub-expression
  = {terms: 93, types: 59, coercions: 9}
*** Float inwards:
Result size of Float inwards = {terms: 93, types: 59, coercions: 9}
*** Liberate case:
Result size of Liberate case = {terms: 93, types: 59, coercions: 9}
*** Simplifier:
Result size of Simplifier iteration=1
  = {terms: 93, types: 59, coercions: 9}
Result size of Simplifier = {terms: 93, types: 59, coercions: 9}
*** SpecConstr:
Result size of SpecConstr

You can also test that using -fno-spec-constr or -fno-enable-rewrite-rules makes the bug disappear. It tested it with latest GHC (7.8.2), and the issue appears to be fixed there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top