Skip to content

Use native operations for Enum Int64 and Enum Word64 on 32-bit platforms #187

@noughtmare

Description

@noughtmare

Situation

Currently, the instances Enum Int64 and Enum Word64 conditionally compile like this:

#if WORD_SIZE_IN_BITS < 64
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFrom #-}
    enumFrom            = integralEnumFrom
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFromThen #-}
    enumFromThen        = integralEnumFromThen
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFromTo #-}
    enumFromTo          = integralEnumFromTo
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFromThenTo #-}
    enumFromThenTo      = integralEnumFromThenTo
#else
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFrom #-}
    enumFrom            = boundedEnumFrom
    -- See Note [Stable Unfolding for list producers] in GHC.Enum
    {-# INLINE enumFromThen #-}
    enumFromThen        = boundedEnumFromThen
#endif

So, it uses a slow Integer-based fallback on 32-bit platforms.

Motivation

Now two things have happened that might make use reevaluate this decision:

  • GHC is getting a JavaScript back end which uses 32-bit words.
  • I have recently implemented code generation for 64-bit operations in the i386 back end (!10771).

So 32-bit platforms will become more common and there is now more performance to gain on i386.

Concrete Changes

I propose to write custom Enum Int64 and Enum Word64 instances that use native operations instead of falling back to Integer-based operations. Essentially, this means copying the implementation of Enum Int and Enum Word and replacing all occurrences of Int with Int64 and the same for Word.

Implementation

I've already implemented the required changes in !10825.

Impact

This is purely a performance change. I expect it will almost always have a positive impact on performance, but it might cause things to inline differently. I have done benchmarks for i386 which shows a 1.5x performance improvement and also for JS which shows a 5.6x performance improvement.

One other impact is that this adds a bit of maintenance burden on the GHC developers. But this part of the code has been very stable, so we don't expect this to be a problem.

Alternatives

  1. Keep status quo. This means bad performance.

  2. Reduce duplication using CPP trickery. This makes it harder to navigate the source code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedApproved by CLC votebase-4.20Implemented in base-4.20 (GHC 9.10)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions