Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
GHC
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gesh
GHC
Commits
7e18dae5
Commit
7e18dae5
authored
27 years ago
by
sof
Browse files
Options
Downloads
Patches
Plain Diff
[project @ 1997-05-18 23:40:29 by sof]
2.04 updates
parent
d6b0f4da
Loading
Loading
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
ghc/compiler/simplCore/SimplCase.lhs
+29
-20
29 additions, 20 deletions
ghc/compiler/simplCore/SimplCase.lhs
ghc/compiler/simplCore/SimplCore.lhs
+64
-18
64 additions, 18 deletions
ghc/compiler/simplCore/SimplCore.lhs
with
93 additions
and
38 deletions
ghc/compiler/simplCore/SimplCase.lhs
+
29
−
20
View file @
7e18dae5
%
`
%
% (c) The AQUA Project, Glasgow University, 1994-1996
%
\section[SimplCase]{Simplification of `case' expression}
...
...
@@ -18,10 +18,11 @@ import CmdLineOpts ( SimplifierSwitch(..) )
import CoreSyn
import CoreUnfold ( Unfolding, SimpleUnfolding )
import CoreUtils ( coreAltsType, nonErrorRHSs, maybeErrorApp,
unTagBindersAlts
unTagBindersAlts
, unTagBinders, coreExprType
)
import Id ( idType, isDataCon, getIdDemandInfo,
SYN_IE(DataCon), GenId{-instance Eq-}
SYN_IE(DataCon), GenId{-instance Eq-},
SYN_IE(Id)
)
import IdInfo ( willBeDemanded, DemandInfo )
import Literal ( isNoRepLit, Literal{-instance Eq-} )
...
...
@@ -34,7 +35,8 @@ import Type ( isPrimType, getAppDataTyConExpandingDicts, mkFunTy, mkFunTys, eqT
import TysPrim ( voidTy )
import Unique ( Unique{-instance Eq-} )
import Usage ( GenUsage{-instance Eq-} )
import Util ( isIn, isSingleton, zipEqual, panic, assertPanic )
import Util ( SYN_IE(Eager), runEager, appEager,
isIn, isSingleton, zipEqual, panic, assertPanic )
\end{code}
Float let out of case.
...
...
@@ -44,7 +46,7 @@ simplCase :: SimplEnv
-> InExpr -- Scrutinee
-> InAlts -- Alternatives
-> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
-> OutType -- Type of result expression
-> OutType
-- Type of result expression
-> SmplM OutExpr
simplCase env (Let bind body) alts rhs_c result_ty
...
...
@@ -109,7 +111,7 @@ simplCase env (Case inner_scrut inner_alts) outer_alts rhs_c result_ty
else
bindLargeAlts env outer_alts rhs_c result_ty `thenSmpl` \ (extra_bindings, outer_alts') ->
let
rhs_c' = \env rhs -> simplExpr env rhs []
rhs_c' = \env rhs -> simplExpr env rhs []
result_ty
in
simplCase env inner_scrut inner_alts
(\env rhs -> simplCase env rhs outer_alts' rhs_c' result_ty)
...
...
@@ -129,10 +131,9 @@ simplCase env scrut alts rhs_c result_ty
| maybeToBool maybe_error_app
= -- Look for an application of an error id
tick CaseOfError `thenSmpl_`
r
hs_c env
retyped_error_app
r
eturnSmpl
retyped_error_app
where
alts_ty = coreAltsType (unTagBindersAlts alts)
maybe_error_app = maybeErrorApp scrut (Just alts_ty)
maybe_error_app = maybeErrorApp scrut (Just result_ty)
Just retyped_error_app = maybe_error_app
\end{code}
...
...
@@ -140,9 +141,18 @@ Finally the default case
\begin{code}
simplCase env other_scrut alts rhs_c result_ty
=
-- Float the let outside the case scrutinee
simplExpr env other_scrut [] `thenSmpl` \ scrut' ->
=
simplTy env scrut_ty `appEager` \ scrut_ty' ->
simplExpr env
'
other_scrut []
scrut_ty
`thenSmpl` \ scrut' ->
completeCase env scrut' alts rhs_c
where
-- When simplifying the scrutinee of a complete case that
-- has no default alternative
env' = case alts of
AlgAlts _ NoDefault -> setCaseScrutinee env
PrimAlts _ NoDefault -> setCaseScrutinee env
other -> env
scrut_ty = coreExprType (unTagBinders other_scrut)
\end{code}
...
...
@@ -355,7 +365,7 @@ completeCase env scrut alts rhs_c
-- the scrutinee. Remember that the rhs is as yet unsimplified.
rhs1_is_scrutinee = case (scrut, rhs1) of
(Var scrut_var, Var rhs_var)
-> case lookupId env rhs_var of
-> case
(runEager $
lookupId env rhs_var
)
of
VarArg rhs_var' -> rhs_var' == scrut_var
other -> False
other -> False
...
...
@@ -440,14 +450,16 @@ bindLargeRhs env args rhs_ty rhs_c
App (Var prim_rhs_fun_id) (VarArg voidId))
| otherwise
= -- Make the new binding Id. NB: it's an OutId
newId rhs_fun_ty `thenSmpl` \ rhs_fun_id ->
-- Generate its rhs
= -- Generate the rhs
cloneIds env used_args `thenSmpl` \ used_args' ->
let
new_env = extendIdEnvWithClones env used_args used_args'
rhs_fun_ty :: OutType
rhs_fun_ty = mkFunTys (map idType used_args') rhs_ty
in
-- Make the new binding Id. NB: it's an OutId
newId rhs_fun_ty `thenSmpl` \ rhs_fun_id ->
rhs_c new_env `thenSmpl` \ rhs' ->
let
final_rhs = mkValLam used_args' rhs'
...
...
@@ -459,8 +471,6 @@ bindLargeRhs env args rhs_ty rhs_c
-- it's processed the OutId won't be found in the environment, so it
-- will be left unmodified.
where
rhs_fun_ty :: OutType
rhs_fun_ty = mkFunTys [simplTy env (idType id) | (id,_) <- used_args] rhs_ty
used_args = [arg | arg@(_,usage) <- args, not (dead usage)]
used_arg_atoms = [VarArg arg_id | (arg_id,_) <- used_args]
...
...
@@ -505,8 +515,7 @@ simplAlts env scrut (AlgAlts alts deflt) rhs_c
new_env = case scrut of
Var v -> extendEnvGivenNewRhs env1 v (Con con args)
where
(_, ty_args, _) = --trace "SimplCase.getAppData..." $
getAppDataTyConExpandingDicts (idType v)
(_, ty_args, _) = getAppDataTyConExpandingDicts (idType v)
args = map TyArg ty_args ++ map VarArg con_args'
other -> env1
...
...
This diff is collapsed.
Click to expand it.
ghc/compiler/simplCore/SimplCore.lhs
+
64
−
18
View file @
7e18dae5
...
...
@@ -27,7 +27,7 @@ import CmdLineOpts ( CoreToDo(..), SimplifierSwitch(..), switchIsOn,
import CoreLint ( lintCoreBindings )
import CoreSyn
import CoreUtils ( coreExprType )
import SimplUtils ( etaCoreExpr )
import SimplUtils ( etaCoreExpr
, typeOkForCase
)
import CoreUnfold
import Literal ( Literal(..), literalType, mkMachInt )
import ErrUtils ( ghcExit )
...
...
@@ -35,19 +35,20 @@ import FiniteMap ( FiniteMap )
import FloatIn ( floatInwards )
import FloatOut ( floatOutwards )
import FoldrBuildWW ( mkFoldrBuildWW )
import Id ( mkSysLocal, setIdVisibility,
import Id ( mkSysLocal, setIdVisibility,
mkIdWithNewName, getIdDemandInfo, idType,
nullIdEnv, addOneToIdEnv, delOneFromIdEnv,
lookupIdEnv, SYN_IE(IdEnv),
GenId{-instance Outputable-}
lookupIdEnv, SYN_IE(IdEnv),
omitIfaceSigForId,
GenId{-instance Outputable-}
, SYN_IE(Id)
)
import Name ( isExported, isLocallyDefined )
import IdInfo ( willBeDemanded, DemandInfo )
import Name ( isExported, isLocallyDefined, SYN_IE(Module), NamedThing(..) )
import TyCon ( TyCon )
import PrimOp ( PrimOp(..) )
import PrelVals ( unpackCStringId, unpackCString2Id,
integerZeroId, integerPlusOneId,
integerPlusTwoId, integerMinusOneId
)
import Type ( maybeAppDataTyCon,
getAppDataTyConExpandingDicts, maybeAppSpecDataTyConExpandingDicts
)
import Type ( maybeAppDataTyCon,
isPrimType, SYN_IE(Type)
)
import TysWiredIn ( stringTy )
import LiberateCase ( liberateCase )
import MagicUFs ( MagicUnfoldingFun )
...
...
@@ -55,7 +56,7 @@ import Outputable ( Outputable(..){-instance * (,) -} )
import PprCore
import PprStyle ( PprStyle(..) )
import PprType ( GenType{-instance Outputable-}, GenTyVar{-ditto-} )
import Pretty (
ppShow, ppAboves, ppAbove, ppCat
)
import Pretty (
Doc, vcat, ($$), hsep
)
import SAT ( doStaticArgs )
import SimplMonad ( zeroSimplCount, showSimplCount, SimplCount )
import SimplPgm ( simplifyPgm )
...
...
@@ -64,7 +65,8 @@ import SpecUtils ( pprSpecErrs )
import StrictAnal ( saWwTopBinds )
import TyVar ( nullTyVarEnv, GenTyVar{-instance Eq-} )
import Unique ( integerTyConKey, ratioTyConKey, Unique{-instance Eq-} )
import UniqSupply ( splitUniqSupply, getUnique )
import UniqFM ( Uniquable(..) )
import UniqSupply ( splitUniqSupply, getUnique, UniqSupply )
import Util ( mapAccumL, assertPanic, panic{-ToDo:rm-}, pprTrace, pprPanic )
import SrcLoc ( noSrcLoc )
import Constants ( tARGET_MIN_INT, tARGET_MAX_INT )
...
...
@@ -207,7 +209,7 @@ core2core core_todos module_name ppr_style us local_tycons tycon_specs binds
-- if we got errors, we die straight away
(if not spec_noerrs ||
(opt_ShowImportSpecs && not (isEmptyBag spec_warn)) then
hPutStr stderr (
ppShow 1000 {-pprCols-}
hPutStr stderr (
show
(pprSpecErrs module_name spec_errs spec_warn spec_tyerrs))
>> hPutStr stderr "\n"
else
...
...
@@ -250,8 +252,8 @@ core2core core_todos module_name ppr_style us local_tycons tycon_specs binds
then
hPutStr stderr ("\n*** "++what++":\n")
>>
hPutStr stderr (
ppShow 1000
(
ppAboves
(map (pprCoreBinding ppr_style) binds2)))
hPutStr stderr (
show
(
vcat
(map (pprCoreBinding ppr_style) binds2)))
>>
hPutStr stderr "\n"
else
...
...
@@ -324,6 +326,9 @@ Several tasks are done by @tidyCorePgm@
nuke them if possible. (In general the simplifier does eta expansion not
eta reduction, up to this point.)
8. Do let-to-case. See notes in Simplify.lhs for why we defer let-to-case
for multi-constructor types.
Eliminate indirections
~~~~~~~~~~~~~~~~~~~~~~
...
...
@@ -383,15 +388,48 @@ tidyCorePgm mod us binds_in
(indirection_env, reduced_binds) = mapAccumL try_bind nullIdEnv binds_in
try_bind :: IdEnv Id -> CoreBinding -> (IdEnv Id, Maybe CoreBinding)
try_bind env_so_far
(NonRec exported_binder (Var local_id))
try_bind env_so_far (NonRec exported_binder rhs)
| isExported exported_binder && -- Only if this is exported
isLocallyDefined local_id && -- Only if this one is defined in this
not (isExported local_id) && -- module, so that we *can* change its
maybeToBool maybe_rhs_id && -- and the RHS is a simple Id
isLocallyDefined rhs_id && -- Only if this one is defined in this
-- module, so that we *can* change its
-- binding to be the exported thing!
not (maybeToBool (lookupIdEnv env_so_far local_id))
not (isExported rhs_id) && -- Only if this one is not itself exported,
-- since the transformation will nuke it
not (omitIfaceSigForId rhs_id) && -- Don't do the transformation if rhs_id is
-- something like a constructor, whose
-- definition is implicitly exported and
-- which must not vanish.
-- To illustrate the preceding check consider
-- data T = MkT Int
-- mkT = MkT
-- f x = MkT (x+1)
-- Here, we'll make a local, non-exported, defn for MkT, and without the
-- above condition we'll transform it to:
-- mkT = \x. MkT [x]
-- f = \y. mkT (y+1)
-- This is bad because mkT will get the IdDetails of MkT, and won't
-- be exported. Also the code generator won't make a definition for
-- the MkT constructor.
-- Slightly gruesome, this.
not (maybeToBool (lookupIdEnv env_so_far rhs_id))
-- Only if not already substituted for
= (addOneToIdEnv env_so_far local_id exported_binder, Nothing)
= (addOneToIdEnv env_so_far rhs_id new_rhs_id, Nothing)
where
maybe_rhs_id = case etaCoreExpr rhs of
Var rhs_id -> Just rhs_id
other -> Nothing
Just rhs_id = maybe_rhs_id
new_rhs_id = mkIdWithNewName rhs_id (getName exported_binder)
-- NB: we keep the Pragmas and IdInfo for the old rhs_id!
-- This is important; it might be marked "no-inline" by
-- the occurrence analyser (because it's recursive), and
-- we must not lose that information.
try_bind env_so_far bind
= (env_so_far, Just bind)
...
...
@@ -469,6 +507,14 @@ tidyCoreExpr (Lam bndr body)
= tidyCoreExpr body `thenTM` \ body' ->
returnTM (Lam bndr body')
-- Try for let-to-case (see notes in Simplify.lhs for why
-- some let-to-case stuff is deferred to now).
tidyCoreExpr (Let (NonRec bndr rhs) body)
| willBeDemanded (getIdDemandInfo bndr) &&
typeOkForCase (idType bndr)
= ASSERT( not (isPrimType (idType bndr)) )
tidyCoreExpr (Case rhs (AlgAlts [] (BindDefault bndr body)))
tidyCoreExpr (Let bind body)
= tidyCoreBinding bind `thenTM` \ bind' ->
tidyCoreExprEta body `thenTM` \ body' ->
...
...
@@ -491,7 +537,7 @@ tidyCoreExpr (Case scrut@(Prim op args) (PrimAlts _ (BindDefault binder rhs)))
-- Eliminate polymorphic case, for which we can't generate code just yet
tidyCoreExpr (Case scrut (AlgAlts [] (BindDefault deflt_bndr rhs)))
| not (
maybeToBool (maybeAppSpecDataTyConExpandingDicts (coreExprType scrut)
))
| not (
typeOkForCase (idType deflt_bndr
))
= pprTrace "Warning: discarding polymorphic case:" (ppr PprDebug scrut) $
case scrut of
Var v -> extendEnvTM deflt_bndr v (tidyCoreExpr rhs)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment