
#14170: 8.2.1 regression: GHC fails to simplify `natVal` -------------------------------------+------------------------------------- Reporter: vagarenko | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.2 Component: Compiler | Version: 8.2.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): OK here's the deal. * In the olden days we represented in `Integer` literal, say 3, in Core by `S# 3#`; that is, we exposed its reprsentation. That made constant folding of `plusInteger 3 5` hard, becuase it meant inlining `plusInteger` which is remarkably big. Result: tons of useless clutter. * Nowadays an `Integer` literal, say 3, is represented in GHC by `Lit (LitInteger 3)`, and ''not'' by an application of the data constructor `S#`. This latter expansion is done right at the end, by `CorePrep`. * That makes constant-folding, like `3+4` rewriting to `7` much, much easier. * We refrain from inlining things like `plusInteger`, `negateInteger` etc until a later stage, and instead add constant-folding rwerite rules for each of these functions. By delaying inlining, the constant-folding rewrite rules (all in `compiler/prelude/PrelRules`) have a decent chance to fire first. * However, in introducing `Natural` we failed to do any of this. The code {{{ foo :: Natural foo = 0 }}} turns into `foo = naturalFromInteger (0::Integer)`, and `naturalFromInteger` has an INLINE pragma. The right thing is presumably to treat `Natural` just like we treat `Integer`: * Keep it as a `LitInteger`. Conveniently `LitInteger` already stores its type, so we can distinguish literal integers from naturals. * Expand the literal in `CorePrep`. * Delay the inlining of `Natural` operations. * Add constant-folding rewrite rules to `PrelRules` I suppose we could also consider making `exprIsConApp_maybe` on an `Integer` literal return `S# n` or whatnot; just possibly that'd be useful anyway, but only for funcions that lack a constant-fold rewrite rule. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14170#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler