diff options
author | Michal Terepeta <michal.terepeta@gmail.com> | 2017-10-29 20:49:32 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-10-29 21:51:05 -0400 |
commit | cca2d6b78f97bfb79bef4dc3f75d6c4d15b94680 (patch) | |
tree | 9be80ec91082ad99ba79d21a6cd0aac68309a236 /testsuite/tests/primops/should_run | |
parent | 85aa1f4253163985fe07d172f8da73b784bb7b4b (diff) | |
download | haskell-cca2d6b78f97bfb79bef4dc3f75d6c4d15b94680.tar.gz |
Allow packing constructor fields
This is another step for fixing #13825 and is based on D38 by Simon
Marlow.
The change allows storing multiple constructor fields within the same
word. This currently applies only to `Float`s, e.g.,
```
data Foo = Foo {-# UNPACK #-} !Float {-# UNPACK #-} !Float
```
on 64-bit arch, will now store both fields within the same constructor
word. For `WordX/IntX` we'll need to introduce new primop types.
Main changes:
- We now use sizes in bytes when we compute the offsets for
constructor fields in `StgCmmLayout` and introduce padding if
necessary (word-sized fields are still word-aligned)
- `ByteCodeGen` had to be updated to correctly construct the data
types. This required some new bytecode instructions to allow pushing
things that are not full words onto the stack (and updating
`Interpreter.c`). Note that we only use the packed stuff when
constructing data types (i.e., for `PACK`), in all other cases the
behavior should not change.
- `RtClosureInspect` was changed to handle the new layout when
extracting subterms. This seems to be used by things like `:print`.
I've also added a test for this.
- I deviated slightly from Simon's approach and use `PrimRep` instead
of `ArgRep` for computing the size of fields. This seemed more
natural and in the future we'll probably want to introduce new
primitive types (e.g., `Int8#`) and `PrimRep` seems like a better
place to do that (where we already have `Int64Rep` for example).
`ArgRep` on the other hand seems to be more focused on calling
functions.
Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com>
Test Plan: ./validate
Reviewers: bgamari, simonmar, austin, hvr, goldfire, erikd
Reviewed By: bgamari
Subscribers: maoe, rwbarton, thomie
GHC Trac Issues: #13825
Differential Revision: https://phabricator.haskell.org/D3809
Diffstat (limited to 'testsuite/tests/primops/should_run')
-rw-r--r-- | testsuite/tests/primops/should_run/T13825-compile.hs | 66 | ||||
-rw-r--r-- | testsuite/tests/primops/should_run/T13825-compile.stdout | 3 | ||||
-rw-r--r-- | testsuite/tests/primops/should_run/all.T | 1 |
3 files changed, 70 insertions, 0 deletions
diff --git a/testsuite/tests/primops/should_run/T13825-compile.hs b/testsuite/tests/primops/should_run/T13825-compile.hs new file mode 100644 index 0000000000..04a72b38e9 --- /dev/null +++ b/testsuite/tests/primops/should_run/T13825-compile.hs @@ -0,0 +1,66 @@ +{-# LANGUAGE MagicHash #-} +module Main where + +import GHC.Exts +import Data.Word +import Data.Int + +data Packed1 = Packed1 Float# Float# Int# Float# + deriving Show + +data Packed2 = + Packed2 + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + {-# UNPACK #-} !Int + {-# UNPACK #-} !Float + deriving Show + +data Packed3 = + Packed3 + {-# UNPACK #-} !Word8 + {-# UNPACK #-} !Int8 + {-# UNPACK #-} !Int64 + {-# UNPACK #-} !Float + {-# UNPACK #-} !Word64 + {-# UNPACK #-} !Word32 + {-# UNPACK #-} !Float + {-# UNPACK #-} !Double + deriving Show + +packed1 = go 0.0# 1.0# 2# 3.0# + where + go a b c d = + Packed1 a b c d + : go (a `plusFloat#` 1.0#) + (b `plusFloat#` 1.0#) + (c +# 1#) + (d `plusFloat#` 1.0#) + +packed2 = + [ Packed2 + (fromIntegral i) + (fromIntegral (i + 1)) + (fromIntegral (i + 2)) + (fromIntegral (i + 3)) + | i <- [0..] + ] + +packed3 = + [ Packed3 + (fromIntegral i) + (fromIntegral (i + 1)) + (fromIntegral (i + 2)) + (fromIntegral (i + 3)) + (fromIntegral (i + 4)) + (fromIntegral (i + 5)) + (fromIntegral (i + 6)) + (fromIntegral (i + 6)) + | i <- [0..] + ] + +main :: IO () +main = do + print (take 3 packed1) + print (take 3 packed2) + print (take 3 packed3) diff --git a/testsuite/tests/primops/should_run/T13825-compile.stdout b/testsuite/tests/primops/should_run/T13825-compile.stdout new file mode 100644 index 0000000000..41a5fb1368 --- /dev/null +++ b/testsuite/tests/primops/should_run/T13825-compile.stdout @@ -0,0 +1,3 @@ +[Packed1 0.0# 1.0# 2# 3.0#,Packed1 1.0# 2.0# 3# 4.0#,Packed1 2.0# 3.0# 4# 5.0#] +[Packed2 0.0 1.0 2 3.0,Packed2 1.0 2.0 3 4.0,Packed2 2.0 3.0 4 5.0] +[Packed3 0 1 2 3.0 4 5 6.0 6.0,Packed3 1 2 3 4.0 5 6 7.0 7.0,Packed3 2 3 4 5.0 6 7 8.0 8.0] diff --git a/testsuite/tests/primops/should_run/all.T b/testsuite/tests/primops/should_run/all.T index 68a2d5609f..30e871ac11 100644 --- a/testsuite/tests/primops/should_run/all.T +++ b/testsuite/tests/primops/should_run/all.T @@ -13,3 +13,4 @@ test('T10678', ], compile_and_run, ['-O']) test('T11296', normal, compile_and_run, ['']) +test('T13825-compile', normal, compile_and_run, ['']) |