Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • 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 4,826
    • Issues 4,826
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 449
    • Merge requests 449
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #19878

Closed
Open
Created May 20, 2021 by Sebastian Graf@sgraf812Developer

WorkWrap Idea: Unboxing higher-order function results based on strictness

Consider

{-# OPTIONS_GHC -O2 -fforce-recomp #-}

module Lib where

import System.Environment

f :: (Int -> Int) -> [Int] -> Int
f g [] = 0
f g (x:xs) = g x + f g xs

main = do
  (n:_)<- map read <$> getArgs
  print $ f (*n) [1..1000]

Currently, we get the following w/w split for f:

$wf :: (Int -> Int) -> [Int] -> Int#
$wf g xs = ... case g x of I# n -> n +# ...
f g xs = I# ($wf g xs)

What I want is

$wf :: (Int -> Int#) -> [Int] -> Int#
$wf g' xs = ... case g' x :: Int# of n -> n +# ...
f g xs = I# ($wf (\n -> case g n of I# m -> m) xs)

Thus one fewer box to pass from g to f.

Note that polarity changes whether we can unbox args or results based on strictness. Here we may unbox the result of the higher-order function because we never use its box. Note also that we allocate an additional closure for the new lambda if f doesn't inline, so this might not be ideal. Nevertheless, worth considering. With boxity analysis (#19871 (closed)), we should have all the demand analysis machinery we need to exploit this. E.g., f puts a demand of LCL(!1L) on g, so we see that its result is used unboxed.

It's not unlike WW'ing for arity, where the wrapper has to allocate a closure for the squiggly lambda wrapper around the non-squiggly lambda call to g. Here, we simply extend the idea to unbox the result of that call to g.

Edited May 21, 2021 by Sebastian Graf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking