Last active
October 29, 2023 08:56
-
-
Save danidiaz/c6590ce5236578f58b696c0c4f60110c to your computer and use it in GitHub Desktop.
Example of how the case-of-known-constructor can remove the use of a record
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- https://www.reddit.com/r/haskell/comments/170f6qa/comment/k6spn9n/ | |
-- Compare the core of | |
-- ghc -O0 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- with the core of | |
-- ghc -O2 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- search for "foofun". | |
module Main (main) where | |
data Foo = Foo | |
{ aaa :: Int, | |
bbb :: Int, | |
ccc :: Int, | |
ddd :: Int | |
} | |
-- The function doesn't do anything meaningful, it's only for | |
-- testing that the Foo is optimized away. | |
foofun :: Foo -> Int -> Int | |
foofun Foo {aaa, bbb, ccc, ddd} 0 = aaa + bbb + ccc + ddd | |
foofun Foo {aaa, bbb, ccc, ddd} n = | |
foofun | |
Foo | |
{ aaa = aaa + 1, | |
bbb = bbb + 1, | |
ccc = ccc + 1, | |
ddd = ddd + 1 | |
} | |
(n - 1) | |
main :: IO () | |
main = print (foofun Foo {aaa = 1, bbb = 1, ccc = 1, ddd = 1} 7) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE OverloadedRecordDot #-} | |
-- https://www.reddit.com/r/haskell/comments/170f6qa/comment/k6spn9n/ | |
-- Compare the core of | |
-- ghc -O0 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- with the core of | |
-- ghc -O2 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- search for "foofun". | |
module Main (main) where | |
data Foo = Foo | |
{ aaa :: Int, | |
bbb :: Int, | |
ccc :: Int, | |
ddd :: Int | |
} | |
-- The function doesn't do anything meaningful, it's only for | |
-- testing that the Foo is optimized away. | |
foofun :: Foo -> Int -> Int | |
foofun foo 0 = foo.aaa + foo.bbb + foo.ccc + foo.ddd | |
foofun foo n = | |
foofun | |
Foo | |
{ aaa = foo.aaa + 1, | |
bbb = foo.bbb + 1, | |
ccc = foo.ccc + 1, | |
ddd = foo.ddd + 1 | |
} | |
(n - 1) | |
main :: IO () | |
main = print (foofun Foo {aaa = 1, bbb = 1, ccc = 1, ddd = 1} 7) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- https://www.reddit.com/r/haskell/comments/170f6qa/comment/k6spn9n/ | |
-- Compare the core of | |
-- ghc -O0 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- with the core of | |
-- ghc -O2 -c Main.hs -ddump-to-file -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes -fforce-recomp | |
-- search for "foofun". | |
module Main (main, foofun) where | |
data Foo = Foo | |
{ aaa :: Int, | |
bbb :: Int, | |
ccc :: Int, | |
ddd :: Int | |
} | |
-- The function doesn't do anything meaningful, it's only for | |
-- testing that the Foo is optimized away. | |
foofun :: Foo -> Int -> (Int, Int) | |
foofun Foo {aaa, bbb, ccc, ddd} 0 = do | |
let !x = aaa + bbb | |
let !y = ccc + ddd | |
-- Removing the stricness bangs result in way worse core. | |
-- The worker won't use unboxed Ints in the result tuple! | |
-- See https://www.youtube.com/watch?v=wC9cpQk7WWA | |
-- and https://ghc.gitlab.haskell.org/ghc/doc/users_guide/using-optimisation.html#ghc-flag--fstrictness | |
-- let x = aaa + bbb | |
-- let y = ccc + ddd | |
(x, y) | |
foofun Foo {aaa, bbb, ccc, ddd} n = | |
foofun | |
Foo | |
{ aaa = aaa + 1, | |
bbb = bbb + 1, | |
ccc = ccc + 1, | |
ddd = ddd + 1 | |
} | |
(n - 1) | |
main :: IO () | |
main = print (foofun Foo {aaa = 1, bbb = 1, ccc = 1, ddd = 1} 7) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rec { | |
-- RHS size: {terms: 49, types: 18, coercions: 0, joins: 0/0} | |
foofun :: Foo -> Int -> Int | |
foofun | |
= \ (ds :: Foo) (ds1 :: Int) -> | |
case ds of { Foo ds2 ds3 ds4 ds5 -> | |
case ds1 of wild1 { I# ds6 -> | |
case ds6 of { | |
__DEFAULT -> | |
foofun | |
(Foo | |
(+ $fNumInt ds2 (I# 1#)) | |
(+ $fNumInt ds3 (I# 1#)) | |
(+ $fNumInt ds4 (I# 1#)) | |
(+ $fNumInt ds5 (I# 1#))) | |
(- $fNumInt wild1 (I# 1#)); | |
0# -> + $fNumInt (+ $fNumInt (+ $fNumInt ds2 ds3) ds4) ds5 | |
} | |
} | |
} | |
end Rec } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rec { | |
-- RHS size: {terms: 32, types: 6, coercions: 0, joins: 0/0} | |
$wfoofun :: Int# -> Int# -> Int# -> Int# -> Int# -> Int# | |
$wfoofun | |
= \ (ww :: Int#) | |
(ww1 :: Int#) | |
(ww2 :: Int#) | |
(ww3 :: Int#) | |
(ww4 :: Int#) -> | |
case ww4 of ds { | |
__DEFAULT -> | |
$wfoofun (+# ww 1#) (+# ww1 1#) (+# ww2 1#) (+# ww3 1#) (-# ds 1#); | |
0# -> +# (+# (+# ww ww1) ww2) ww3 | |
} | |
end Rec } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment