Skip to content

Record field selectors are not optimized

It seems that record field selectors are not optimized. Usually this doesn't matter, but when there are unpacked fields this leaves suboptimal code. The equivalent code using the data type constructor is optimized.

For example:

module Test where

data Test = Test { getR :: {-# UNPACK #-} !Int }
getC (Test a) = a

Generates the following core (with -O2 -ddump-simpl):

Test.getR :: Test.Test -> GHC.Base.Int
[RecSel]
[Arity 1
 NoCafRefs
 Str: DmdType U(L)m]
Test.getR =
  \ (tpl_B1 :: Test.Test) ->
    case tpl_B1 of tpl1_B2 { Test.Test rb_B4 ->
    let {
      ipv_B3 [Just S] :: GHC.Base.Int
      [Str: DmdType m]
      ipv_B3 = GHC.Base.I# rb_B4
    } in  ipv_B3
    }

Test.getC :: Test.Test -> GHC.Base.Int
[GlobalId]
[Arity 1
 NoCafRefs
 Str: DmdType U(L)m]
Test.getC =
  \ (ds_d5Q :: Test.Test) ->
    case ds_d5Q of wild_B1 { Test.Test rb_d5S -> GHC.Base.I# rb_d5S }

After further investigation, it seems that getR is not passed through the optimizer at all, earlier simplifier passes (-ddump-simpl-iterations, -ddump-cse, -ddump-occur-anal) do not include the function.

Trac metadata
Trac field Value
Version 6.9
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system Unknown
Architecture Unknown
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information