summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lynagh <igloo@earth.li>2011-11-04 17:03:35 +0000
committerIan Lynagh <igloo@earth.li>2011-11-04 17:03:35 +0000
commit70f631ee065a9b05ea128b02cf3666fd948d77cf (patch)
treecf198a794f431cf37990f3352c0d0254eaaa964a
parent1df198643cc5502ee103f043193d2990c9837e25 (diff)
parent659d5d06f3a3d209415d5c4de3d895e7970bc622 (diff)
downloadhaskell-70f631ee065a9b05ea128b02cf3666fd948d77cf.tar.gz
Merge branch 'master' of http://darcs.haskell.org/ghc
-rw-r--r--compiler/simplCore/Simplify.lhs51
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs
index f72be2cbb4..0a9d388b7f 100644
--- a/compiler/simplCore/Simplify.lhs
+++ b/compiler/simplCore/Simplify.lhs
@@ -1054,6 +1054,10 @@ simplTick env tickish expr cont
; return (env'', wrapFloats env expr'')
}
+ | Just expr' <- want_to_push_tick_inside
+ -- see Note [case-of-scc-of-case]
+ = simplExprF env expr' cont
+
| otherwise
= do { let (inc,outc) = splitCont cont
; (env', expr') <- simplExprF (zapFloats env) expr inc
@@ -1062,6 +1066,21 @@ simplTick env tickish expr cont
; rebuild env'' expr' (TickIt tickish' outc)
}
where
+ want_to_push_tick_inside
+ | not interesting_cont = Nothing
+ | otherwise
+ = case expr of
+ Case scrut bndr ty alts
+ -> Just (Case (mkTick tickish scrut) bndr ty alts')
+ where t_scope = mkNoTick tickish -- drop the tick on the dup'd ones
+ alts' = [ (c,bs, mkTick t_scope e) | (c,bs,e) <- alts]
+ _other -> Nothing
+
+ interesting_cont = case cont of
+ Select _ _ _ _ _ -> True
+ _ -> False
+
+
simplTickish env tickish
| Breakpoint n ids <- tickish
= Breakpoint n (map (getDoneId . substId env) ids)
@@ -1078,6 +1097,38 @@ simplTick env tickish expr cont
getDoneId (DoneId id) = id
getDoneId (DoneEx e) = getIdFromTrivialExpr e -- Note [substTickish] in CoreSubst
getDoneId other = pprPanic "getDoneId" (ppr other)
+
+-- Note [case-of-scc-of-case]
+-- It's pretty important to be able to transform case-of-case when
+-- there's an SCC in the way. For example, the following comes up
+-- in nofib/real/compress/Encode.hs:
+--
+-- case scctick<code_string.r1>
+-- case $wcode_string_r13s wild_XC w1_s137 w2_s138 l_aje
+-- of _ { (# ww1_s13f, ww2_s13g, ww3_s13h #) ->
+-- (ww1_s13f, ww2_s13g, ww3_s13h)
+-- }
+-- of _ { (ww_s12Y, ww1_s12Z, ww2_s130) ->
+-- tick<code_string.f1>
+-- (ww_s12Y,
+-- ww1_s12Z,
+-- PTTrees.PT
+-- @ GHC.Types.Char @ GHC.Types.Int wild2_Xj ww2_s130 r_ajf)
+-- }
+--
+-- We really want this case-of-case to fire, because then the 3-tuple
+-- will go away (indeed, the CPR optimisation is relying on this
+-- happening). But the scctick is in the way - we need to push it
+-- inside to expose the case-of-case. So we perform this
+-- transformation on the inner case:
+--
+-- scctick c (case e of { p1 -> e1; ...; pn -> en })
+-- ==>
+-- case (scctick c e) of { p1 -> scc c e1; ...; pn -> scc c en }
+--
+-- So we've moved a constant amount of work out of the scc to expose
+-- the case. We only do this when the continuation is interesting: in
+-- for now, it has to be another Case (maybe generalise this later).
\end{code}