PUBLIC
I’ve done some digging into this, and it turns out the DynFlag’s `optLevel` itself is used at some places, most notably when creating the main [CoreToDo]. So turning on all these
flags on their own doesn’t equal setting -On for the right “n”; in fact, currently setting most of these flags does NOTHING on its own unless -On with n>=1 is *also* passed on the command line, and there is no command line flag to *only* turn
on Core optimizations in the abstract, without actually turning any specific ones on.
Is this a documentation bug, an implementation bug (as in, if any of the relevant opts are set, then the CoreToDos should always include the optimization steps selected), or
a design bug (there is no way to support this meaningfully)?
From: Erdi, Gergo
Sent: Monday, October 11, 2021 12:09 PM
To: 'GHC' <ghc-devs@haskell.org>
Cc: Montelatici, Raphael Laurent <Raphael.Montelatici@sc.com>
Subject: -O* does more than what's in optLevelFlags?
PUBLIC
What is set by -O* that is not included in optLevelFlags?
I would have thought that setting all the flags implied by, e.g., -O1, would be the same as setting -O1 itself. But this is not the case! Here are all the flags for O1 from optLevelFlags:
Opt_DoLambdaEtaExpansion
Opt_DoEtaReduction
Opt_LlvmTBAA
Opt_CallArity
Opt_Exitification
Opt_CaseMerge
Opt_CaseFolding
Opt_CmmElimCommonBlocks
Opt_CmmSink
Opt_CmmStaticPred
Opt_CSE
Opt_StgCSE
Opt_EnableRewriteRules
Opt_FloatIn
Opt_FullLaziness
Opt_IgnoreAsserts
Opt_Loopification
Opt_CfgBlocklayout
Opt_Specialise
Opt_CrossModuleSpecialise
Opt_InlineGenerics
Opt_Strictness
Opt_UnboxSmallStrictFields
Opt_CprAnal
Opt_WorkerWrapper
Opt_SolveConstantDicts
Opt_NumConstantFolding
And here are the ones that are set by O0 (the default) but not by O1:
Opt_IgnoreInterfacePragmas
Opt_OmitInterfacePragmas
So I expected that the following two invocations of GHC would be equivalent:
However, just by observing the output of -dshow-passes, I can see that while -O1 applies all these optimizations, the second version does NOT, even though I have turned on each
and every one of them one by one.
Looking at compiler/GHC/Driver/Session.hs, it is not at all clear that -O* should do more than just setting the flags from optLevelFlags. What other flags are implied by -O*?