Commit 1c9fd3f1 authored by Simon Peyton Jones's avatar Simon Peyton Jones

Case-of-empty-alts is trivial (Trac #11155)

As you'll see from Trac #11155, the code generator was confused
by a binding let x = y in ....   Why did that happen? Because of
a (case y of {}) expression on the RHS.

The right thing is just to expand what a "trivial" expression is.

See Note [Empty case is trivial] in CoreUtils.
parent 5b2b7e33
......@@ -847,15 +847,17 @@ of the scope of a `seq`, or dropped the `seq` altogether.
cpe_ExprIsTrivial :: CoreExpr -> Bool
-- Version that doesn't consider an scc annotation to be trivial.
cpe_ExprIsTrivial (Var _) = True
cpe_ExprIsTrivial (Type _) = True
cpe_ExprIsTrivial (Coercion _) = True
cpe_ExprIsTrivial (Lit _) = True
cpe_ExprIsTrivial (App e arg) = isTypeArg arg && cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Tick t e) = not (tickishIsCode t) && cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Cast e _) = cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Lam b body) | isTyVar b = cpe_ExprIsTrivial body
cpe_ExprIsTrivial _ = False
cpe_ExprIsTrivial (Var _) = True
cpe_ExprIsTrivial (Type _) = True
cpe_ExprIsTrivial (Coercion _) = True
cpe_ExprIsTrivial (Lit _) = True
cpe_ExprIsTrivial (App e arg) = not (isRuntimeArg arg) && cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Lam b e) = not (isRuntimeVar b) && cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Tick t e) = not (tickishIsCode t) && cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Cast e _) = cpe_ExprIsTrivial e
cpe_ExprIsTrivial (Case e _ _ []) = cpe_ExprIsTrivial e
-- See Note [Empty case is trivial] in CoreUtils
cpe_ExprIsTrivial _ = False
{-
-- -----------------------------------------------------------------------------
......
......@@ -733,11 +733,28 @@ saturating them.
Note [Tick trivial]
~~~~~~~~~~~~~~~~~~~
Ticks are only trivial if they are pure annotations. If we treat
"tick<n> x" as trivial, it will be inlined inside lambdas and the
entry count will be skewed, for example. Furthermore "scc<n> x" will
turn into just "x" in mkTick.
Note [Empty case is trivial]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The expression (case (x::Int) Bool of {}) is just a type-changing
case used when we are sure that 'x' will not return. See
Note [Empty case alternatives] in CoreSyn.
If the scrutinee is trivial, then so is the whole expression; and the
CoreToSTG pass in fact drops the case expression leaving only the
scrutinee.
Having more trivial expressions is good. Moreover, if we don't treat
it as trivial we may land up with let-bindings like
let v = case x of {} in ...
and after CoreToSTG that gives
let v = x in ...
and that confuses the code generator (Trac #11155). So best to kill
it off at source.
-}
exprIsTrivial :: CoreExpr -> Bool
......@@ -750,6 +767,7 @@ exprIsTrivial (Tick t e) = not (tickishIsCode t) && exprIsTrivial e
-- See Note [Tick trivial]
exprIsTrivial (Cast e _) = exprIsTrivial e
exprIsTrivial (Lam b body) = not (isRuntimeVar b) && exprIsTrivial body
exprIsTrivial (Case e _ _ []) = exprIsTrivial e -- See Note [Empty case is trivial]
exprIsTrivial _ = False
{-
......
......@@ -6,6 +6,12 @@ T8832:
$(RM) -f T8832.o T8832.hi
'$(TEST_HC)' $(TEST_HC_OPTS) $(T8832_WORDSIZE_OPTS) -O -c -ddump-simpl T8832.hs | grep '^[a-zA-Z0-9]\+ ='
T11155:
$(RM) -f T11155.o T11155.hi
'$(TEST_HC)' $(TEST_HC_OPTS) -c T11155.hs
-nm T11155.o | grep 'stg_ap_0_upd'
# Expecting no output from the grep
T8274:
$(RM) -f T8274.o T8274.hi
'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T8274.hs | grep '#'
......
{-# OPTIONS_GHC -O -fno-full-laziness #-}
module T11155 where
foo :: Bool
{-# NOINLINE foo #-}
foo = error "rk"
bar x = let t :: Char
t = case foo of { True -> 'v'; False -> 'y' }
in [t]
......@@ -224,4 +224,7 @@ test('T10083',
run_command,
['$MAKE -s --no-print-directory T10083'])
test('T10689', normal, compile, [''])
test('T10689a', normal, compile, [''])
test('T11155',
normal,
run_command,
['$MAKE -s --no-print-directory T11155'])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment