summaryrefslogtreecommitdiff
path: root/compiler/iface/TcIface.hs
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2018-01-05 15:20:05 +0000
committerBartosz Nitka <niteria@gmail.com>2018-01-10 13:50:56 +0000
commitdbdf77d92c9cd0bbb269137de0bf8754573cdc1e (patch)
tree17bbe7fb388308615ba009e4f887c719c9e58107 /compiler/iface/TcIface.hs
parent1577908f2a9db0fcf6f749d40dd75481015f5497 (diff)
downloadhaskell-dbdf77d92c9cd0bbb269137de0bf8754573cdc1e.tar.gz
Lift constructor tag allocation out of a loop
Before this change, for each constructor that we want to allocate a tag for we would traverse a list of all the constructors in a datatype to determine which tag a constructor should get. This is obviously quadratic and for datatypes with 10k constructors it actually makes a big difference. This change implements the plan outlined by @simonpj in https://mail.haskell.org/pipermail/ghc-devs/2017-October/014974.html which is basically about using a map and constructing it outside the loop. One place where things got a bit awkward was TysWiredIn.hs, it would have been possible to just assign the tags by hand, but that seemed error-prone to me, so I decided to go through a map there as well. Test Plan: ./validate On a file with 10k constructors Before: 8,130,522,344 bytes allocated in the heap Total time 3.682s ( 3.920s elapsed) After: 4,133,478,744 bytes allocated in the heap Total time 2.509s ( 2.750s elapsed) Reviewers: simonpj, bgamari Reviewed By: simonpj Subscribers: goldfire, rwbarton, thomie, simonmar, carter, simonpj GHC Trac Issues: #14657 Differential Revision: https://phabricator.haskell.org/D4289
Diffstat (limited to 'compiler/iface/TcIface.hs')
-rw-r--r--compiler/iface/TcIface.hs5
1 files changed, 4 insertions, 1 deletions
diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs
index 6fad8da87c..70438f6337 100644
--- a/compiler/iface/TcIface.hs
+++ b/compiler/iface/TcIface.hs
@@ -897,6 +897,9 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons
univ_tvs :: [TyVar]
univ_tvs = binderVars (tyConTyVarBinders tc_tybinders)
+ tag_map :: NameEnv ConTag
+ tag_map = mkTyConTagMap tycon
+
tc_con_decl (IfCon { ifConInfix = is_infix,
ifConExTvs = ex_bndrs,
ifConUserTvBinders = user_bndrs,
@@ -960,7 +963,7 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons
lbl_names
univ_tvs ex_tvs user_tv_bndrs
eq_spec theta
- arg_tys orig_res_ty tycon
+ arg_tys orig_res_ty tycon tag_map
; traceIf (text "Done interface-file tc_con_decl" <+> ppr dc_name)
; return con }
mk_doc con_name = text "Constructor" <+> ppr con_name