#11731: Simplifier: Inlining trivial let can lose sharing -------------------------------------+------------------------------------- Reporter: nomeata | Owner: Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D2064 Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): For the record, here is the proposed fix (currently on a wip branch): {{{ commit 7ac5610606e8f338cd2eb92eb5d711e054d9d55a Author: Joachim Breitner <mail@joachim-breitner.de> Date: Wed Mar 30 12:55:10 2016 +0200 Used-once variables are not trivial The specification for exprIsTrivial demands that we are unconditionally happy to duplicate the expression. This is not true for variables where we would like to exploit (or already have exploited) that they are used at most once. In order to preserve this property, they must not be duplicated nilly-willy. This fixes #11731 and comes with a test case.
---------------------------------------------------------------
7ac5610606e8f338cd2eb92eb5d711e054d9d55a compiler/coreSyn/CoreUtils.hs | 12 +++++++- testsuite/.gitignore | 1 + testsuite/tests/simplCore/should_run/T11731.hs | 36 ++++++++++++++++++++++ testsuite/tests/simplCore/should_run/T11731.stderr | 1 + testsuite/tests/simplCore/should_run/all.T | 1 + 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/compiler/coreSyn/CoreUtils.hs b/compiler/coreSyn/CoreUtils.hs index 1d9b83b..d02b934 100644 --- a/compiler/coreSyn/CoreUtils.hs +++ b/compiler/coreSyn/CoreUtils.hs @@ -62,6 +62,7 @@ import DataCon import PrimOp import Id import IdInfo +import Demand ( isUsedOnce ) import Type import Coercion import TyCon @@ -755,6 +756,13 @@ Note [exprIsTrivial] Note [Variables are trivial] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Variables are usually trivial. + +Except if 'isUsedOnce (idDemandInfo v) == True': +In this case we have previously determined that a variable is used at +most once, and we likely rely on this information, e.g. during code +generation. In this case, we are not unconditionally happy to duplicate, so we don’t. See #11731. + There used to be a gruesome test for (hasNoBinding v) in the Var case: exprIsTrivial (Var v) | hasNoBinding v = idArity v == 0 @@ -793,7 +801,9 @@ it off at source. -} exprIsTrivial :: CoreExpr -> Bool -exprIsTrivial (Var _) = True -- See Note [Variables are trivial] +exprIsTrivial (Var v) -- See Note [Variables are trivial] + | isUsedOnce (idDemandInfo v) = False + | otherwise = True exprIsTrivial (Type _) = True exprIsTrivial (Coercion _) = True exprIsTrivial (Lit lit) = litIsTrivial lit }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11731#comment:16> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler