Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEC: support functions with more then 62 arguments #1727

Merged
merged 5 commits into from Mar 27, 2021

Conversation

leonschoorl
Copy link
Member

All (non-shared) arguments to DEC'ed functions are combined into tuples,
so they can all be defined via a single case expression.
But because GHC's tuples are limited to 62 elements, this fails for functions with many arguments.

This patch uses GHC's mkChunkified to create (2-levels of) nested tuples for a maximum of 62^2=3844 arguments.

Fixes #1669

Given
    topEntity :: Bool -> Bool -> Bool
    topEntity b x = case b of
        False -> f x False
        True  -> f x True

    f :: Eq a => a -> a -> Bool
    f = ...

DEC would do:
    Changes when applying rewrite to:
    case b[LocalId] of
      False  ->
        f[GlobalId] @Bool $fEqBool[GlobalId] x[LocalId]
          False
      True  ->
        f[GlobalId] @Bool $fEqBool[GlobalId] x[LocalId]
          True
    Result:
    letrec
      c$fOut :: Bool
      = f[GlobalId] @Bool
          (case b[LocalId] of
             False  ->
               $fEqBool[GlobalId]
             True  ->
               $fEqBool[GlobalId])
          x[LocalId]
          (case b[LocalId] of
             False  ->
               False
             True  ->
               True)
    in case b[LocalId] of
         False  ->
           c$fOut[LocalId]
         True  ->
           c$fOut[LocalId]

Because both f's gets the same x argument, in the result the single f 
gets the x directly.
But this sharing only worked for LocalId's, for GlobalId's like the 
$fEqBool(Eq class dictionary), but clash generates as argument to the 
new f:
          (case b[LocalId] of
             False  ->
               $fEqBool[GlobalId]
             True  ->
               $fEqBool[GlobalId])

With this patch we now generate:
    letrec
      c$fOut :: Bool
      = f[GlobalId] @Bool $fEqBool[GlobalId]
          x[LocalId]
          (case b[LocalId] of
             False  ->
               False
             True  ->
               True)
    in case b[LocalId] of
         False  ->
           c$fOut[LocalId]
         True  ->
           c$fOut[LocalId]
So in the next commit we can easily make wrappers around them for big tuples (>62 elements).
All (non-shared) arguments to DEC'ed functions are combined into tuples,
so they can all be defined via a single case expression.
But because GHC's tuples are limited to 62 elements, this fails for functions with many arguments.

This patch uses GHC's mkChunkified to create (2-levels of) nested tuples for a maximum of 62^2=3844 arguments.

Fixes #1669
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Non-exhaustive patterns in DEC
2 participants