From: simonpj@microsoft.com Date: Wed, 29 Nov 2006 21:24:40 +0000 (+0000) Subject: Improve the loop-breaking heuristics X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=1dca158769225e58ec90d95526f968515e325378 Improve the loop-breaking heuristics The loop-breaking heuristics were making it a high priority to avoid choosing a variable as a loop breaker if its *type* was a data type. The reason is that it's very good to be able to "see" constructor applications. But it's only good if the constructor application is *visible*, so that is what I test for now. I found a case (when testing SpecConstr) where I had a Rec like this: rec { lvl = foo Nothing foo = ... RULE foo Nothing = ... } Even if lvl has a data type, it's much better to make lvl the loop breaker, not foo, so that foo's RULE is visible in lvl's RHS. --- diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs index 5bfb4b9..8b3d45e 100644 --- a/compiler/simplCore/OccurAnal.lhs +++ b/compiler/simplCore/OccurAnal.lhs @@ -23,14 +23,13 @@ import CoreUtils ( exprIsTrivial, isDefaultAlt ) import Id ( isDataConWorkId, isOneShotBndr, setOneShotLambda, idOccInfo, setIdOccInfo, isLocalId, isExportedId, idArity, idHasRules, - idType, idUnique, Id + idUnique, Id ) import BasicTypes ( OccInfo(..), isOneOcc, InterestingCxt ) import VarSet import VarEnv -import Type ( isFunTy, dropForAlls ) import Maybes ( orElse ) import Digraph ( stronglyConnCompR, SCC(..) ) import PrelNames ( buildIdKey, foldrIdKey, runSTRepIdKey, augmentIdKey ) @@ -301,7 +300,7 @@ reOrderCycle bndrs (bind : binds) -- where df is the exported dictionary. Then df makes a really -- bad choice for loop breaker - | not_fun_ty (idType bndr) = 3 -- Data types help with cases + | is_con_app rhs = 3 -- 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 @@ -328,7 +327,11 @@ reOrderCycle bndrs (bind : binds) -- we didn't stupidly choose d as the loop breaker. -- But we won't because constructor args are marked "Many". - not_fun_ty ty = not (isFunTy (dropForAlls ty)) + -- Cheap and cheerful; the simplifer moves casts out of the way + is_con_app (Var v) = isDataConWorkId v + is_con_app (App f _) = is_con_app f + is_con_app (Note _ e) = is_con_app e + is_con_app other = False makeLoopBreaker :: VarSet -- Binders of this group -> UsageDetails -- Usage of this rhs (neglecting rules)