Compress certain IdInfo fields into a single Word64
Motivation
IdInfos are an absolute massive part of GHC's residency during compilation. Contributing a bit over 15% of residency during it's peak and over 10% over much of the pipeline.
So reducing it's size by 1/3rd would reduce GHC's footprint by 5% at it's peak with no other changes.
I assume they are also a significant contributor to compiler allocations, so compacting these fields would be beneficial there as well. But maybe not as much so as with residency.
Proposal
Currently IdInfo is implemented like this:
data IdInfo
= IdInfo {
arityInfo :: !ArityInfo, -- ^ 'Id' arity
ruleInfo :: RuleInfo, -- ^ Specialisations of the 'Id's function which exist
-- See Note [Specialisations and RULES in IdInfo]
unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding
cafInfo :: CafInfo, -- ^ 'Id' CAF info
oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one
inlinePragInfo :: InlinePragma, -- ^ Any inline pragma atached to the 'Id'
occInfo :: OccInfo, -- ^ How the 'Id' occurs in the program
strictnessInfo :: StrictSig, -- ^ A strictness signature
demandInfo :: Demand, -- ^ ID demand information
callArityInfo :: !ArityInfo, -- ^ How this is called.
-- n <=> all calls have at least n arguments
levityInfo :: LevityInfo -- ^ when applied, will this Id ever have a levity-polymorphic type?
}
Nothing is wrong about that but it's not ideal.
In particular the fields arityInfo, cafInfo, oneShotInfo, callArityInfo and levityInfo could all be compressed into a single Word64 bitmask (if we are content with a max arity of 32k) reducing the size of IdInfo from 12 Words to 8 Words.
So the type would be something like this:
data IdInfo
= IdInfo {
ruleInfo :: RuleInfo, -- ^ Specialisations of the 'Id's function which exist
-- See Note [Specialisations and RULES in IdInfo]
unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding
inlinePragInfo :: InlinePragma, -- ^ Any inline pragma atached to the 'Id'
occInfo :: OccInfo, -- ^ How the 'Id' occurs in the program
strictnessInfo :: StrictSig, -- ^ A strictness signature
demandInfo :: Demand, -- ^ ID demand information
-- n <=> all calls have at least n arguments
bitField :: BitField64 -- ^ Encodes arities, oneShotInfo, cafInfo and levityInfo.
}
newtype BitField64 = BitField64 Word64
-- Functions to extract the values from the bitfield
callArityInfo :: BitField -> !ArityInfo
arityInfo :: ...
...
Problems
-
Not all of these fields are strict. It's likely that making them strict would outweigh in order to shrink IdInfo would still be worthwhile. But there might be issues lurking there I did not account for.
-
Code churn. These fields are used in many places, as such the diff would be fairly substantial. However using pattern synonyms and other tricks I don't think code using the actual values would look much different, if at all.
-
Somebody needs to implement it. I don't plan to in the near future.