Make SpecConstr more informative output when there are too many specialisations
[ghc-hetmet.git] / compiler / specialise / SpecConstr.lhs
index 36dda5e..ade88d9 100644 (file)
@@ -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