Comments and white space only
[ghc-hetmet.git] / compiler / coreSyn / CoreUnfold.lhs
index d467e89..f83521c 100644 (file)
@@ -93,11 +93,12 @@ mkUnfolding top_lvl expr
        -- Sometimes during simplification, there's a large let-bound thing     
        -- which has been substituted, and so is now dead; so 'expr' contains
        -- two copies of the thing while the occurrence-analysed expression doesn't
-       -- Nevertheless, we don't occ-analyse before computing the size because the
+       -- Nevertheless, we *don't* occ-analyse before computing the size because the
        -- size computation bales out after a while, whereas occurrence analysis does not.
        --
        -- This can occasionally mean that the guidance is very pessimistic;
-       -- it gets fixed up next round
+       -- it gets fixed up next round.  And it should be rare, because large
+       -- let-bound things that are dead are usually caught by preInlineUnconditionally
 
 mkCoreUnfolding :: Bool -> CoreExpr -> Arity -> UnfoldingGuidance -> Unfolding
 -- Occurrence-analyses the expression before capturing it
@@ -121,7 +122,8 @@ mkWwInlineRule id expr arity
 
 mkCompulsoryUnfolding :: CoreExpr -> Unfolding
 mkCompulsoryUnfolding expr        -- Used for things that absolutely must be unfolded
-  = mkCoreUnfolding True expr 0    -- Arity of unfolding doesn't matter
+  = mkCoreUnfolding True expr 
+                    0    -- Arity of unfolding doesn't matter
                     (InlineRule { ir_info = InlAlways, ir_sat = InlUnSat })    
 
 mkInlineRule :: InlSatFlag -> CoreExpr -> Arity -> Unfolding
@@ -190,6 +192,7 @@ Examples
   --------------
     0    42#
     0    x
+    0     True
     2    f x
     1    Just x
     4    f (g x)
@@ -389,7 +392,7 @@ funSize top_args fun n_val_args
 
 conSize :: DataCon -> Int -> ExprSize
 conSize dc n_val_args
-  | n_val_args == 0      = SizeIs (_ILIT(0)) emptyBag (_ILIT(1))
+  | n_val_args == 0      = SizeIs (_ILIT(0)) emptyBag (_ILIT(1))       -- Like variables
   | isUnboxedTupleCon dc = SizeIs (_ILIT(0)) emptyBag (iUnbox n_val_args +# _ILIT(1))
   | otherwise           = SizeIs (_ILIT(1)) emptyBag (iUnbox n_val_args +# _ILIT(1))
        -- Treat a constructors application as size 1, regardless of how
@@ -604,11 +607,13 @@ instance Outputable ArgSummary where
 
 data CallCtxt = BoringCtxt
 
-             | ArgCtxt Bool    -- We're somewhere in the RHS of function with rules
-                               --      => be keener to inline
-                       Int     -- We *are* the argument of a function with this arg discount
-                               --      => be keener to inline
-               -- INVARIANT: ArgCtxt False 0 ==> BoringCtxt
+             | ArgCtxt         -- We are somewhere in the argument of a function
+                        Bool   -- True  <=> we're somewhere in the RHS of function with rules
+                               -- False <=> we *are* the argument of a function with non-zero
+                               --           arg discount
+                                --        OR 
+                                --           we *are* the RHS of a let  Note [RHS of lets]
+                                -- In both cases, be a little keener to inline
 
              | ValAppCtxt      -- We're applied to at least one value arg
                                -- This arises when we have ((f x |> co) y)
@@ -618,10 +623,10 @@ data CallCtxt = BoringCtxt
                                -- that decomposes its scrutinee
 
 instance Outputable CallCtxt where
-  ppr BoringCtxt    = ptext (sLit "BoringCtxt")
-  ppr (ArgCtxt rules disc) = ptext (sLit "ArgCtxt") <> ppr (rules,disc)
-  ppr CaseCtxt             = ptext (sLit "CaseCtxt")
-  ppr ValAppCtxt    = ptext (sLit "ValAppCtxt")
+  ppr BoringCtxt      = ptext (sLit "BoringCtxt")
+  ppr (ArgCtxt rules) = ptext (sLit "ArgCtxt") <+> ppr rules
+  ppr CaseCtxt               = ptext (sLit "CaseCtxt")
+  ppr ValAppCtxt      = ptext (sLit "ValAppCtxt")
 
 callSiteInline dflags active_inline id lone_variable arg_infos cont_info
   = let
@@ -707,6 +712,15 @@ callSiteInline dflags active_inline id lone_variable arg_infos cont_info
     }
 \end{code}
 
+Note [RHS of lets]
+~~~~~~~~~~~~~~~~~~
+Be a tiny bit keener to inline in the RHS of a let, because that might
+lead to good thing later
+     f y = (y,y,y)
+     g y = let x = f y in ...(case x of (a,b,c) -> ...) ...
+We'd inline 'f' if the call was in a case context, and it kind-of-is,
+only we can't see it.  So we treat the RHS of a let as not-totally-boring.
+    
 Note [Unsaturated applications]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 When a call is not saturated, we *still* inline if one of the
@@ -806,6 +820,11 @@ At one stage I replaced this condition by 'True' (leading to the above
 slow-down).  The motivation was test eyeball/inline1.hs; but that seems
 to work ok now.
 
+NOTE: arguably, we should inline in ArgCtxt only if the result of the
+call is at least CONLIKE.  At least for the cases where we use ArgCtxt
+for the RHS of a 'let', we only profit from the inlining if we get a 
+CONLIKE thing (modulo lets).
+
 Note [Lone variables]
 ~~~~~~~~~~~~~~~~~~~~~
 The "lone-variable" case is important.  I spent ages messing about