X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fspecialise%2FSpecConstr.lhs;h=ade88d92f9b00872b174c232a68753f4ba525e72;hb=f766da17254420317a6973e0790813650f74a294;hp=36dda5ecda896c9e2133b6f74686d45919e93fcf;hpb=99d1354f70b94951fa8f7401ba82881a317b6a55;p=ghc-hetmet.git diff --git a/compiler/specialise/SpecConstr.lhs b/compiler/specialise/SpecConstr.lhs index 36dda5e..ade88d9 100644 --- a/compiler/specialise/SpecConstr.lhs +++ b/compiler/specialise/SpecConstr.lhs @@ -39,7 +39,6 @@ import Name import DynFlags ( DynFlags(..) ) import StaticFlags ( opt_PprStyle_Debug ) import StaticFlags ( opt_SpecInlineJoinPoints ) -import BasicTypes ( Activation(..) ) import Maybes ( orElse, catMaybes, isJust, isNothing ) import Demand import DmdAnal ( both ) @@ -571,7 +570,7 @@ lookupHowBound :: ScEnv -> Id -> Maybe HowBound lookupHowBound env id = lookupVarEnv (sc_how_bound env) id scSubstId :: ScEnv -> Id -> CoreExpr -scSubstId env v = lookupIdSubst (sc_subst env) v +scSubstId env v = lookupIdSubst (text "scSubstId") (sc_subst env) v scSubstTy :: ScEnv -> Type -> Type scSubstTy env ty = substTy (sc_subst env) ty @@ -1098,20 +1097,24 @@ specialise env force_spec bind_calls (fn, arg_bndrs, body, arg_occs) , notNull arg_bndrs -- Only specialise functions , Just all_calls <- lookupVarEnv bind_calls fn = do { (boring_call, pats) <- callsToPats env specs arg_occs all_calls --- ; pprTrace "specialise" (vcat [ppr fn <+> ppr arg_occs, --- text "calls" <+> ppr all_calls, --- text "good pats" <+> ppr pats]) $ +-- ; pprTrace "specialise" (vcat [ ppr fn <+> text "with" <+> int (length pats) <+> text "good patterns" +-- , text "arg_occs" <+> ppr arg_occs, +-- , text "calls" <+> ppr all_calls, +-- , text "good pats" <+> ppr pats]) $ -- return () -- Bale out if too many specialisations -- Rather a hacky way to do so, but it'll do for now - ; let spec_count' = length pats + spec_count + ; let n_pats = length pats + spec_count' = length pats + spec_count ; case sc_count env of Just max | not force_spec && spec_count' > max - -> WARN( True, msg ) return (nullUsage, spec_info) + -> pprTrace "SpecConstr" msg $ + return (nullUsage, spec_info) where - msg = vcat [ sep [ ptext (sLit "SpecConstr: specialisation of") <+> quotes (ppr fn) - , nest 2 (ptext (sLit "limited by bound of")) <+> int max ] + msg = vcat [ sep [ ptext (sLit "Function") <+> quotes (ppr fn) + , nest 2 (ptext (sLit "has") <+> int n_pats <+> + ptext (sLit "call pattterns, but the limit is") <+> int max) ] , ptext (sLit "Use -fspec-constr-count=n to set the bound") , extra ] extra | not opt_PprStyle_Debug = ptext (sLit "Use -dppr-debug to see specialisations") @@ -1179,18 +1182,19 @@ spec_one env fn arg_bndrs body (call_pat@(qvars, pats), rule_number) -- Usual w/w hack to avoid generating -- a spec_rhs of unlifted type and no args - fn_name = idName fn - fn_loc = nameSrcSpan fn_name - spec_occ = mkSpecOcc (nameOccName fn_name) - rule_name = mkFastString ("SC:" ++ showSDoc (ppr fn <> int rule_number)) - spec_rhs = mkLams spec_lam_args spec_body - spec_str = calcSpecStrictness fn spec_lam_args pats - spec_id = mkUserLocal spec_occ spec_uniq (mkPiTypes spec_lam_args body_ty) fn_loc - `setIdStrictness` spec_str -- See Note [Transfer strictness] - `setIdArity` count isId spec_lam_args - body_ty = exprType spec_body - rule_rhs = mkVarApps (Var spec_id) spec_call_args - rule = mkLocalRule rule_name specConstrActivation fn_name qvars pats rule_rhs + fn_name = idName fn + fn_loc = nameSrcSpan fn_name + spec_occ = mkSpecOcc (nameOccName fn_name) + rule_name = mkFastString ("SC:" ++ showSDoc (ppr fn <> int rule_number)) + spec_rhs = mkLams spec_lam_args spec_body + spec_str = calcSpecStrictness fn spec_lam_args pats + spec_id = mkUserLocal spec_occ spec_uniq (mkPiTypes spec_lam_args body_ty) fn_loc + `setIdStrictness` spec_str -- See Note [Transfer strictness] + `setIdArity` count isId spec_lam_args + body_ty = exprType spec_body + rule_rhs = mkVarApps (Var spec_id) spec_call_args + inline_act = idInlineActivation fn + rule = mkLocalRule rule_name inline_act fn_name qvars pats rule_rhs ; return (spec_usg, OS call_pat rule spec_id spec_rhs) } calcSpecStrictness :: Id -- The original function @@ -1215,18 +1219,23 @@ calcSpecStrictness fn qvars pats | (Var _, args) <- collectArgs e = go env ds args go_one env _ _ = env --- In which phase should the specialise-constructor rules be active? --- Originally I made them always-active, but Manuel found that --- this defeated some clever user-written rules. So Plan B --- is to make them active only in Phase 0; after all, currently, --- the specConstr transformation is only run after the simplifier --- has reached Phase 0. In general one would want it to be --- flag-controllable, but for now I'm leaving it baked in --- [SLPJ Oct 01] -specConstrActivation :: Activation -specConstrActivation = ActiveAfter 0 -- Baked in; see comments above \end{code} +Note [Transfer activation] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +In which phase should the specialise-constructor rules be active? +Originally I made them always-active, but Manuel found that this +defeated some clever user-written rules. Then I made them active only +in Phase 0; after all, currently, the specConstr transformation is +only run after the simplifier has reached Phase 0, but that meant +that specialisations didn't fire inside wrappers; see test +simplCore/should_compile/spec-inline. + +So now I just use the inline-activation of the parent Id, as the +activation for the specialiation RULE, just like the main specialiser; +see Note [Auto-specialisation and RULES] in Specialise. + + Note [Transfer strictness] ~~~~~~~~~~~~~~~~~~~~~~~~~~ We must transfer strictness information from the original function to