Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,400
    • Issues 5,400
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 591
    • Merge requests 591
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #7109
Closed
Open
Issue created Aug 01, 2012 by dreixel@dreixel

Inlining depends on datatype size, even with INLINE pragmas

Consider the following code:

data Logic = T | F
           | Not Logic

instance GEq Logic

testEqLogic = geq (Not T) (Not F)

With a proper definitions of generic equality geq in class GEq, and an instance Generic Logic, we get the following core code with -O1:

Rec {
Bug.$fGEqLogic_$cgeq [Occ=LoopBreaker]
  :: Bug.Logic -> Bug.Logic -> GHC.Types.Bool
[GblId, Arity=2, Caf=NoCafRefs, Str=DmdType SS]
Bug.$fGEqLogic_$cgeq =
  \ (x_ap1 :: Bug.Logic) (y_ap2 :: Bug.Logic) ->
    case x_ap1 of _ {
      Bug.T ->
        case y_ap2 of _ {
          Bug.T -> GHC.Types.True;
          Bug.F -> GHC.Types.False;
          Bug.Not g1_aBc_ayJ -> GHC.Types.False
        };
      Bug.F ->
        case y_ap2 of _ {
          Bug.T -> GHC.Types.False;
          Bug.F -> GHC.Types.True;
          Bug.Not g1_aBc_ayJ -> GHC.Types.False
        };
      Bug.Not g1_aBc_ayJ ->
        case y_ap2 of _ {
          __DEFAULT -> GHC.Types.False;
          Bug.Not g1_aBc1_XAu -> Bug.$fGEqLogic_$cgeq g1_aBc_ayJ g1_aBc1_XAu
        }
    }
end Rec }

Nice and simple, looking just like what we would expect for an equality function for datatype Logic.

Now we add one more constructor to datatype Logic (and adapt the Generic instance accordingly):

data Logic = T | F
           | Not Logic 
           | And Logic Logic

GHC (HEAD) now generates 3000 lines of core code for the Bug.$fGEqLogic_$cgeq function, instead of something only slightly longer than above.

Why is this? The second version of our Logic datatype is as easy to optimise as the first version; only the terms involved will be slightly longer. Attached file Bug2.hs is the input which gives the correct behaviour, while Bug3.hs is the input with one added constructor. (You might wonder if it has to do with the fact that the added constructor has more than one argument, but this is not the source of the problem.) Both files have INLINE pragmas pretty much everywhere (in fact, we're not deriving Generic so that we can put INLINE pragmas on to and from).

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