From 26caf834b8eba8eea0f68ab96d47997159a5ed7e Mon Sep 17 00:00:00 2001
From: simonpj <unknown>
Date: Mon, 28 Jun 1999 16:27:30 +0000
Subject: [PATCH] [project @ 1999-06-28 16:27:27 by simonpj] Improve common
 sub-expression stuff 	- better hash function 	- add Const.isBoxedDataCon,
 and use it in CSE 	- don't CSE for nullary constructors

---
 ghc/compiler/basicTypes/Const.lhs  |  9 +++++--
 ghc/compiler/coreSyn/CoreUtils.lhs | 38 ++++++++++++++++++++----------
 ghc/compiler/simplCore/CSE.lhs     | 19 ++++++++-------
 3 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/ghc/compiler/basicTypes/Const.lhs b/ghc/compiler/basicTypes/Const.lhs
index 2c2fbb4ee45f..dd0bda49589a 100644
--- a/ghc/compiler/basicTypes/Const.lhs
+++ b/ghc/compiler/basicTypes/Const.lhs
@@ -7,7 +7,7 @@
 module Const (
 	Con(..),
 	conType, conPrimRep,
-	conOkForApp, conOkForAlt, isWHNFCon, isDataCon,
+	conOkForApp, conOkForAlt, isWHNFCon, isDataCon, isBoxedDataCon,
 	conIsTrivial, conIsCheap, conIsDupable, conStrictness, 
 	conOkForSpeculation, hashCon,
 
@@ -31,7 +31,9 @@ import Name		( hashName )
 import PrimOp		( PrimOp, primOpType, primOpIsDupable, primOpTag,
 			  primOpIsCheap, primOpStrictness, primOpOkForSpeculation )
 import PrimRep		( PrimRep(..) )
-import DataCon		( DataCon, dataConName, dataConType, dataConTyCon, isNullaryDataCon, dataConRepStrictness )
+import DataCon		( DataCon, dataConName, dataConType, dataConTyCon, 
+			  isNullaryDataCon, dataConRepStrictness, isUnboxedTupleCon
+			)
 import TyCon		( isNewTyCon )
 import Type		( Type, typePrimRep )
 import PprType		( pprParendType )
@@ -113,6 +115,9 @@ isWHNFCon (PrimOp _)   = False
 isDataCon (DataCon dc) = True
 isDataCon other	       = False
 
+isBoxedDataCon (DataCon dc) = not (isUnboxedTupleCon dc)
+isBoxedDataCon other	    = False
+
 -- conIsTrivial is true for constants we are unconditionally happy to duplicate
 -- cf CoreUtils.exprIsTrivial
 conIsTrivial (Literal lit) = not (isNoRepLit lit)
diff --git a/ghc/compiler/coreSyn/CoreUtils.lhs b/ghc/compiler/coreSyn/CoreUtils.lhs
index ea91fe4a31f4..bc6b37611be5 100644
--- a/ghc/compiler/coreSyn/CoreUtils.lhs
+++ b/ghc/compiler/coreSyn/CoreUtils.lhs
@@ -18,6 +18,8 @@ module CoreUtils (
 
 import {-# SOURCE #-} CoreUnfold	( isEvaldUnfolding )
 
+import GlaExts		-- For `xori` 
+
 import CoreSyn
 import PprCore		( pprCoreExpr )
 import Var		( IdOrTyVar, isId, isTyVar )
@@ -400,19 +402,29 @@ eqExpr e1 e2
 
 \begin{code}
 hashExpr :: CoreExpr -> Int
-hashExpr (Note _ e)   		 = hashExpr e
-hashExpr (Let (NonRec b r) e)    = hashId b
-hashExpr (Let (Rec ((b,r):_)) e) = hashId b
-hashExpr (Case _ b _)		 = hashId b
-hashExpr (App f e)   		 = hashExpr f
-hashExpr (Var v)     		 = hashId v
-hashExpr (Con con args)   	 = hashArgs args (hashCon con)
-hashExpr (Lam b _)	         = hashId b
-hashExpr (Type t)	         = trace "hashExpr: type" 0		-- Shouldn't happen
-
-hashArgs []		 con = con
-hashArgs (Type t : args) con = hashArgs args con
-hashArgs (arg    : args) con = hashExpr arg
+hashExpr e = abs (hash_expr e)
+	-- Negative numbers kill UniqFM
+
+hash_expr (Note _ e)   		  = hash_expr e
+hash_expr (Let (NonRec b r) e)    = hashId b
+hash_expr (Let (Rec ((b,r):_)) e) = hashId b
+hash_expr (Case _ b _)		  = hashId b
+hash_expr (App f e)   		  = hash_expr f + fast_hash_expr e
+hash_expr (Var v)     		  = hashId v
+hash_expr (Con con args)   	  = foldr ((+) . fast_hash_expr) (hashCon con) args
+hash_expr (Lam b _)	          = hashId b
+hash_expr (Type t)	          = trace "hash_expr: type" 0		-- Shouldn't happen
+
+fast_hash_expr (Var v)     	= hashId v
+fast_hash_expr (Con con args) 	= fast_hash_args args con
+fast_hash_expr (App f (Type _)) = fast_hash_expr f
+fast_hash_expr (App f a)        = fast_hash_expr a
+fast_hash_expr (Lam b _)        = hashId b
+fast_hash_expr other	        = 0
+
+fast_hash_args []	       con = hashCon con
+fast_hash_args (Type t : args) con = fast_hash_args args con
+fast_hash_args (arg    : args) con = fast_hash_expr arg
 
 hashId :: Id -> Int
 hashId id = hashName (idName id)
diff --git a/ghc/compiler/simplCore/CSE.lhs b/ghc/compiler/simplCore/CSE.lhs
index 188cb48fec3f..ee12ab927ce9 100644
--- a/ghc/compiler/simplCore/CSE.lhs
+++ b/ghc/compiler/simplCore/CSE.lhs
@@ -13,8 +13,7 @@ module CSE (
 import CmdLineOpts	( opt_D_dump_cse, opt_D_verbose_core2core )
 import Id		( Id, idType )
 import CoreUtils	( hashExpr, cheapEqExpr, exprIsBig )
-import Const		( Con(..) )
-import DataCon		( isUnboxedTupleCon )
+import Const		( isBoxedDataCon )
 import Type		( splitTyConApp_maybe )
 import CoreSyn
 import VarEnv	
@@ -131,13 +130,15 @@ cseAlts env bndr alts
 		other		  -> pprPanic "cseAlts" (ppr bndr)
 
     cse_alt (con, args, rhs)
-	| ok_for_cse con = (con, args, cseExpr (extendCSEnv env bndr (Con con (arg_tys ++ (map varToCoreExpr args)))) rhs)
-	| otherwise      = (con, args, cseExpr env rhs)
-
-    ok_for_cse DEFAULT      = False
-    ok_for_cse (Literal l)  = True
-    ok_for_cse (DataCon dc) = not (isUnboxedTupleCon dc)
-	-- Unboxed tuples aren't shared
+	| null args || not (isBoxedDataCon con) = (con, args, cseExpr env rhs)
+		-- Don't try CSE if there are no args; it just increases the number
+		-- of live vars.  E.g.
+		--	case x of { True -> ....True.... }
+		-- Don't replace True by x!  
+		-- Hence the 'null args', which also deal with literals and DEFAULT
+		-- And we can't CSE on unboxed tuples
+	| otherwise
+	= (con, args, cseExpr (extendCSEnv env bndr (Con con (arg_tys ++ (map varToCoreExpr args)))) rhs)
 \end{code}
 
 
-- 
GitLab