-GLOBAL_VAR(v_UsageSPInf, False, Bool) -- Off by default
-GLOBAL_VAR(v_Strictness, True, Bool)
-GLOBAL_VAR(v_CPR, True, Bool)
-GLOBAL_VAR(v_CSE, True, Bool)
-
--- these are the static flags you get without -O.
-hsc_minusNoO_flags =
- [
- "-fignore-interface-pragmas",
- "-fomit-interface-pragmas",
- "-fdo-lambda-eta-expansion", -- This one is important for a tiresome reason:
- -- we want to make sure that the bindings for data
- -- constructors are eta-expanded. This is probably
- -- a good thing anyway, but it seems fragile.
- "-flet-no-escape"
- ]
-
--- these are the static flags you get when -O is on.
-hsc_minusO_flags =
- [
- "-fignore-asserts",
- "-ffoldr-build-on",
- "-fdo-eta-reduction",
- "-fdo-lambda-eta-expansion",
- "-fcase-merge",
- "-flet-to-case",
- "-flet-no-escape"
- ]
-
-hsc_minusO2_flags = hsc_minusO_flags -- for now
-
-getStaticOptimisationFlags 0 = hsc_minusNoO_flags
-getStaticOptimisationFlags 1 = hsc_minusO_flags
-getStaticOptimisationFlags n = hsc_minusO2_flags
-
-buildCoreToDo :: IO [CoreToDo]
-buildCoreToDo = do
- opt_level <- readIORef v_OptLevel
- max_iter <- readIORef v_MaxSimplifierIterations
- usageSP <- readIORef v_UsageSPInf
- strictness <- readIORef v_Strictness
- cpr <- readIORef v_CPR
- cse <- readIORef v_CSE
-
- if opt_level == 0 then return
- [
- CoreDoSimplify (isAmongSimpl [
- MaxSimplifierIterations max_iter
- ])
- ]
-
- else {- opt_level >= 1 -} return [
-
- -- initial simplify: mk specialiser happy: minimum effort please
- CoreDoSimplify (isAmongSimpl [
- SimplInlinePhase 0,
- -- Don't inline anything till full laziness has bitten
- -- In particular, inlining wrappers inhibits floating
- -- e.g. ...(case f x of ...)...
- -- ==> ...(case (case x of I# x# -> fw x#) of ...)...
- -- ==> ...(case x of I# x# -> case fw x# of ...)...
- -- and now the redex (f x) isn't floatable any more
- DontApplyRules,
- -- Similarly, don't apply any rules until after full
- -- laziness. Notably, list fusion can prevent floating.
- NoCaseOfCase,
- -- Don't do case-of-case transformations.
- -- This makes full laziness work better
- MaxSimplifierIterations max_iter
- ]),
-
- -- Specialisation is best done before full laziness
- -- so that overloaded functions have all their dictionary lambdas manifest
- CoreDoSpecialising,
-
- CoreDoFloatOutwards False{-not full-},
- CoreDoFloatInwards,
-
- CoreDoSimplify (isAmongSimpl [
- SimplInlinePhase 1,
- -- Want to run with inline phase 1 after the specialiser to give
- -- maximum chance for fusion to work before we inline build/augment
- -- in phase 2. This made a difference in 'ansi' where an
- -- overloaded function wasn't inlined till too late.
- MaxSimplifierIterations max_iter
- ]),
-
- -- infer usage information here in case we need it later.
- -- (add more of these where you need them --KSW 1999-04)
- if usageSP then CoreDoUSPInf else CoreDoNothing,
-
- CoreDoSimplify (isAmongSimpl [
- -- Need inline-phase2 here so that build/augment get
- -- inlined. I found that spectral/hartel/genfft lost some useful
- -- strictness in the function sumcode' if augment is not inlined
- -- before strictness analysis runs
- SimplInlinePhase 2,
- MaxSimplifierIterations max_iter
- ]),
-
- CoreDoSimplify (isAmongSimpl [
- MaxSimplifierIterations 3
- -- No -finline-phase: allow all Ids to be inlined now
- -- This gets foldr inlined before strictness analysis
- --
- -- At least 3 iterations because otherwise we land up with
- -- huge dead expressions because of an infelicity in the
- -- simpifier.
- -- let k = BIG in foldr k z xs
- -- ==> let k = BIG in letrec go = \xs -> ...(k x).... in go xs
- -- ==> let k = BIG in letrec go = \xs -> ...(BIG x).... in go xs
- -- Don't stop now!
- ]),
-
- if cpr then CoreDoCPResult else CoreDoNothing,
- if strictness then CoreDoStrictness else CoreDoNothing,
- CoreDoWorkerWrapper,
- CoreDoGlomBinds,
-
- CoreDoSimplify (isAmongSimpl [
- MaxSimplifierIterations max_iter
- -- No -finline-phase: allow all Ids to be inlined now
- ]),
-
- CoreDoFloatOutwards False{-not full-},
- -- nofib/spectral/hartel/wang doubles in speed if you
- -- do full laziness late in the day. It only happens
- -- after fusion and other stuff, so the early pass doesn't
- -- catch it. For the record, the redex is
- -- f_el22 (f_el21 r_midblock)
-
-
--- Leave out lambda lifting for now
--- "-fsimplify", -- Tidy up results of full laziness
--- "[",
--- "-fmax-simplifier-iterations2",
--- "]",
--- "-ffloat-outwards-full",
-
- -- We want CSE to follow the final full-laziness pass, because it may
- -- succeed in commoning up things floated out by full laziness.
- -- CSE used to rely on the no-shadowing invariant, but it doesn't any more
-
- if cse then CoreCSE else CoreDoNothing,
-
- CoreDoFloatInwards,
-
--- Case-liberation for -O2. This should be after
--- strictness analysis and the simplification which follows it.
-
- if opt_level >= 2 then
- CoreLiberateCase
- else
- CoreDoNothing,
- if opt_level >= 2 then
- CoreDoSpecConstr
- else
- CoreDoNothing,
-
- -- Final clean-up simplification:
- CoreDoSimplify (isAmongSimpl [
- MaxSimplifierIterations max_iter
- -- No -finline-phase: allow all Ids to be inlined now
- ])
- ]