[GHC] #13825: Allow multiple constructor fields occupy the same word
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The main goal is to reduce the overhead of things like: {{{#!hs data Bloated = Bloated {-# UNPACK #-} !Word8 {-# UNPACK #-} !Int8 {-# UNPACK #-} !Bool }}} Assuming 64-bit architecture, currently those fields will take 8 bytes each! So for this example we'd need: 8 bytes for header + 3 * 8 bytes for fields = 32 bytes. But we should be able to pack the fields into a single word (a word is 8 bytes and each field really only needs 1 byte) for a total of 16 bytes (8 bytes header + 8 bytes for fields, with the 5 bytes being "overhead" due to heap alignment). My understanding is that we need a few things to make this happen: - Ability to refer to fields that are packed into a single word (currently everything in GHC assumes that each field occupies a single word). Simon Marlow started working on this in https://phabricator.haskell.org/D38 - Introduce primitives like `Word8#`, `Int8#`, ... (currently `WordX` and `IntX` are defined as wrappers of `Word#` and `Int#` respectively) and change `WordX`/`IntX` definitions to use those primitives. - Figure out what to do with `Bool` (should it be just `Word8#`? should we have `Bool#`?) and change its definition (using pattern synonyms for `True`/`False`) Some additional info: - Thread on ghc-devs: https://mail.haskell.org/pipermail/ghc- devs/2017-June/014304.html -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by michalt): * owner: (none) => michalt -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * related: => #605 * milestone: => 8.4.1 Comment: `Bool` isn't special, and shouldn't be. It's just an enumeration type, and should remain one. #605 suggests representing unboxed enumeration types as `Int#`. It seems that to get what you want, you'd want to do something like what `Binary` and `Cereal` do with sum types, using a different number of bits depending on the number of constructors. One big question is whether and how to support sub-byte-sized fields. It is possible, presumably at some performance cost, to pack a `Bool` (for instance) into a single bit. Is the cost enough to worry about? -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * cc: dfeuer (added) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by maoe): * cc: maoe (added) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by michalt): @dfeuer: Thanks for linking #605 - sounds like a much better solution for `Bool` :) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by michalt: @@ -22,3 +22,3 @@ - - Figure out what to do with `Bool` (should it be just `Word8#`? should we - have `Bool#`?) and change its definition (using pattern synonyms for - `True`/`False`) + - ~~Figure out what to do with `Bool` (should it be just `Word8#`? should + we have `Bool#`?) and change its definition (using pattern synonyms for + `True`/`False`)~~ `Bool` should be handled by #605 (see comment:2) New description: The main goal is to reduce the overhead of things like: {{{#!hs data Bloated = Bloated {-# UNPACK #-} !Word8 {-# UNPACK #-} !Int8 {-# UNPACK #-} !Bool }}} Assuming 64-bit architecture, currently those fields will take 8 bytes each! So for this example we'd need: 8 bytes for header + 3 * 8 bytes for fields = 32 bytes. But we should be able to pack the fields into a single word (a word is 8 bytes and each field really only needs 1 byte) for a total of 16 bytes (8 bytes header + 8 bytes for fields, with the 5 bytes being "overhead" due to heap alignment). My understanding is that we need a few things to make this happen: - Ability to refer to fields that are packed into a single word (currently everything in GHC assumes that each field occupies a single word). Simon Marlow started working on this in https://phabricator.haskell.org/D38 - Introduce primitives like `Word8#`, `Int8#`, ... (currently `WordX` and `IntX` are defined as wrappers of `Word#` and `Int#` respectively) and change `WordX`/`IntX` definitions to use those primitives. - ~~Figure out what to do with `Bool` (should it be just `Word8#`? should we have `Bool#`?) and change its definition (using pattern synonyms for `True`/`False`)~~ `Bool` should be handled by #605 (see comment:2) Some additional info: - Thread on ghc-devs: https://mail.haskell.org/pipermail/ghc- devs/2017-June/014304.html -- -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"fe6618b14712b829b8675fc6024dd33e9598d09a/ghc" fe6618b/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="fe6618b14712b829b8675fc6024dd33e9598d09a" ByteCodeGen: use depth instead of offsets in BCEnv This is based on unfinished work in D38 started by Simon Marlow and is the first step for fixing #13825. (next step use byte-indexing for stack) The change boils down to adjusting everything in BCEnv by +1, which simplifies the code a bit. I've also looked into a weird stack adjustement that we did in `getIdValFromApStack` and moved it to `ByteCodeGen` to just keep everything in one place. I've left a comment about this. Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com> Test Plan: ./validate Reviewers: austin, hvr, bgamari, simonmar Reviewed By: bgamari, simonmar Subscribers: simonmar, rwbarton, thomie GHC Trac Issues: #13825 Differential Revision: https://phabricator.haskell.org/D3708 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"5469ac86f9cc9e83b93ed34ca13f0a4f58f4a9a6/ghc" 5469ac86/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="5469ac86f9cc9e83b93ed34ca13f0a4f58f4a9a6" Interpreter.c: use macros to access/modify Sp This is another step in fixing #13825 (based on D38 by Simon Marlow). This commit adds a few macros for accessing and modifying `Sp` (interpreter stack) and will be useful to allow sub-word indexing/pushing. (but that will be a separate change, this commit should introduce no changes in behavior) Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com> Test Plan: ./validate Reviewers: bgamari, simonmar, austin, erikd Reviewed By: bgamari, erikd Subscribers: rwbarton, thomie GHC Trac Issues: #13825 Differential Revision: https://phabricator.haskell.org/D3744 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:8> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"dac4b9d3cdca83c99d5d894d2743cc0bbca450ac/ghc" dac4b9d3/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="dac4b9d3cdca83c99d5d894d2743cc0bbca450ac" ByteCodeGen: use byte indexing for BCenv This is another change needed for #13825 (also based on D38 by Simon Marlow). With the change, we count the stack depth in bytes (instead of words). We also introduce some `newtype`s to help with the change. Note that this only changes how `ByteCodeGen` works and shouldn't affect the generated bytecode. Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com> Test Plan: ./validate Reviewers: bgamari, simonmar, austin, hvr Reviewed By: bgamari, simonmar Subscribers: rwbarton, thomie GHC Trac Issues: #13825 Differential Revision: https://phabricator.haskell.org/D3746 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:9> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"cca2d6b78f97bfb79bef4dc3f75d6c4d15b94680/ghc" cca2d6b7/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="cca2d6b78f97bfb79bef4dc3f75d6c4d15b94680" 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 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:10> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13825: Allow multiple constructor fields occupy the same word -------------------------------------+------------------------------------- Reporter: michalt | Owner: michalt Type: bug | Status: closed Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #605 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => closed * resolution: => fixed -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13825#comment:11> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC