X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FsimplCore%2FOccurAnal.lhs;h=4492bd7b9f031d084a08a7cb24c2de5671fb3783;hb=19b0b165a24606dbdb1f4dd7728da7346845a5a0;hp=ae2b7b902399af3fc851682739d8b24a2dee768a;hpb=262c142b90c94ca1aa577c950a6ceae1f255e2d6;p=ghc-hetmet.git diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs index ae2b7b9..4492bd7 100644 --- a/compiler/simplCore/OccurAnal.lhs +++ b/compiler/simplCore/OccurAnal.lhs @@ -135,7 +135,7 @@ It isn't easy to do a perfect job in one blow. Consider \begin{code} occAnalBind env (Rec pairs) body_usage - = foldr (_scc_ "occAnalBind.dofinal" do_final_bind) (body_usage, []) sccs + = foldr ({-# SCC "occAnalBind.dofinal" #-} do_final_bind) (body_usage, []) sccs where analysed_pairs :: [Details] analysed_pairs = [ (bndr, rhs_usage, rhs') @@ -144,12 +144,12 @@ occAnalBind env (Rec pairs) body_usage ] sccs :: [SCC (Node Details)] - sccs = _scc_ "occAnalBind.scc" stronglyConnCompR edges + sccs = {-# SCC "occAnalBind.scc" #-} stronglyConnCompR edges ---- stuff for dependency analysis of binds ------------------------------- edges :: [Node Details] - edges = _scc_ "occAnalBind.assoc" + edges = {-# SCC "occAnalBind.assoc" #-} [ (details, idUnique id, edges_from id rhs_usage) | details@(id, rhs_usage, rhs) <- analysed_pairs ] @@ -164,7 +164,7 @@ occAnalBind env (Rec pairs) body_usage -- which has n**2 cost, and this meant that edges_from alone -- consumed 10% of total runtime! edges_from :: Id -> UsageDetails -> [Unique] - edges_from bndr rhs_usage = _scc_ "occAnalBind.edges_from" + edges_from bndr rhs_usage = {-# SCC "occAnalBind.edges_from" #-} keysUFM (addRuleUsage rhs_usage bndr) ---- Stuff to "re-constitute" bindings from dependency-analysis info ------ @@ -308,12 +308,10 @@ reOrderCycle bndrs (bind : binds) -- Also vital to avoid risk of divergence: -- Note [Recursive rules] - | is_con_app rhs = 2 -- Data types help with cases - -- This used to have a lower score than inlineCandidate, but - -- it's *really* helpful if dictionaries get inlined fast, - -- so I'm experimenting with giving higher priority to data-typed things + | inlineCandidate bndr rhs = 2 -- Likely to be inlined + -- Note [Inline candidates] - | inlineCandidate bndr rhs = 1 -- Likely to be inlined + | is_con_app rhs = 1 -- Data types help with cases | otherwise = 0 @@ -356,6 +354,25 @@ makeLoopBreaker bndrs rhs_usg bndr rules_only = bndrs `intersectsUFM` rhs_usg \end{code} +Note [Inline candidates] +~~~~~~~~~~~~~~~~~~~~~~~~ +At one point I gave is_con_app a higher score than inline-candidate, +on the grounds that "it's *really* helpful if dictionaries get inlined fast". +However a nofib run revealed no change if they were swapped so that +inline-candidate has the higher score. And it's important that it does, +else you can get a bad worker-wrapper split thus: + rec { + $wfoo x = ....foo x.... + + {-loop brk-} foo x = ...$wfoo x... + } +But we *want* the wrapper to be inlined! If it isn't, the interface +file sees the unfolding for $wfoo, and sees that foo is strict (and +hence it gets an auto-generated wrapper. Result: an infinite inlining +in the importing scope. So be a bit careful if you change this. A +good example is Tree.repTree in nofib/spectral/minimax. If is_con_app +has the higher score, then compiling Game.hs goes into an infinite loop. + Note [Recursive rules] ~~~~~~~~~~~~~~~~~~~~~~ Consider this group, which is typical of what SpecConstr builds: