diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2017-04-18 17:20:59 -0400 |
---|---|---|
committer | Joachim Breitner <mail@joachim-breitner.de> | 2017-04-18 20:18:03 -0400 |
commit | 21c35bda8e435cfba1998fa8375a52a73fe570f4 (patch) | |
tree | 94902788466c5cee41e911be5c790a144a98e97e /compiler/simplStg | |
parent | fc7601c5dc9fb826db13c5a644b3a64e7594d0b5 (diff) | |
download | haskell-21c35bda8e435cfba1998fa8375a52a73fe570f4.tar.gz |
Simplify StgCases when all alts refer to the case binder
as proposed in #13588.
Differential Revision: https://phabricator.haskell.org/D3467
Diffstat (limited to 'compiler/simplStg')
-rw-r--r-- | compiler/simplStg/StgCse.hs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/compiler/simplStg/StgCse.hs b/compiler/simplStg/StgCse.hs index 1ee6a9a150..ec4b188aae 100644 --- a/compiler/simplStg/StgCse.hs +++ b/compiler/simplStg/StgCse.hs @@ -293,7 +293,7 @@ stgCseExpr env (StgTick tick body) = let body' = stgCseExpr env body in StgTick tick body' stgCseExpr env (StgCase scrut bndr ty alts) - = StgCase scrut' bndr' ty alts' + = mkStgCase scrut' bndr' ty alts' where scrut' = stgCseExpr env scrut (env1, bndr') = substBndr env bndr @@ -381,6 +381,17 @@ stgCseRhs env bndr (StgRhsClosure ccs info occs upd args body) in (Just (substVar env bndr, StgRhsClosure ccs info occs' upd args' body'), env) where occs' = substVars env occs + +mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr +mkStgCase scrut bndr ty alts | all isBndr alts = scrut + | otherwise = StgCase scrut bndr ty alts + + where + -- see Note [All alternatives are the binder] + isBndr (_, _, StgApp f []) = f == bndr + isBndr _ = False + + -- Utilities -- | This function short-cuts let-bindings that are now obsolete @@ -390,6 +401,24 @@ mkStgLet stgLet (Just binds) body = stgLet binds body {- +Note [All alternatives are the binder] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When all alternatives simply refer to the case binder, then we do not have +to bother with the case expression at all (#13588). CoreSTG does this as well, +but sometimes, types get into the way: + + newtype T = MkT Int + f :: (Int, Int) -> (T, Int) + f (x, y) = (MkT x, y) + +Core cannot just turn this into + + f p = p + +as this would not be well-typed. But to STG, where MkT is no longer in the way, +we can. + Note [Trivial case scrutinee] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to be able to handle nested reconstruction of constructors as in |