| ... |
... |
@@ -786,15 +786,45 @@ setInteractivePrint f d = d { interactivePrint = Just f} |
|
786
|
786
|
-----------------------------------------------------------------------------
|
|
787
|
787
|
-- Setting the optimisation level
|
|
788
|
788
|
|
|
|
789
|
+{- Note [Simplifier iterations and the optimisation level]
|
|
|
790
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
791
|
+At -O0 the only Core-to-Core pass that runs is the final simplifier pass (see
|
|
|
792
|
+'GHC.Core.Opt.Pipeline.getCoreToDo'); every optimisation-specific pass is gated
|
|
|
793
|
+off. We therefore want as few simplifier iterations as possible at -O0, since
|
|
|
794
|
+the later iterations only chase optimisation opportunities the user opted out of
|
|
|
795
|
+by choosing -O0.
|
|
|
796
|
+
|
|
|
797
|
+We cannot drop to a *single* iteration, though. The final simplifier pass is
|
|
|
798
|
+still load-bearing for correctness: a single iteration can leave a recursive
|
|
|
799
|
+superclass dictionary with an unreduced superclass selector applied to it, which
|
|
|
800
|
+then builds an infinite dictionary tower and diverges (<<loop>> at -O, OOM at
|
|
|
801
|
+-O0). See #21973 and test T21973b. The fix needs (at least) two iterations: the
|
|
|
802
|
+first inlines the dictionary functions to expose a constructor, and the second
|
|
|
803
|
+reduces the superclass selector against it, making the recursive dictionary
|
|
|
804
|
+dead. Empirically two iterations suffice across the known reproducers; the
|
|
|
805
|
+simplifier offers no proof of a fixed bound, so we keep a small margin rather
|
|
|
806
|
+than the bare minimum.
|
|
|
807
|
+
|
|
|
808
|
+So we tie 'maxSimplIterations' to the optimisation level: 2 iterations at -O0
|
|
|
809
|
+and 4 at -O1/-O2. This is a noticeable win for unoptimised compilation, and most
|
|
|
810
|
+noticeable for the byte-code interpreter (GHCi), which defaults to -O0 and codegen
|
|
|
811
|
+does less work compared to other backends.
|
|
|
812
|
+
|
|
|
813
|
+An explicit -fmax-simplifier-iterations=⟨n⟩ still overrides this, as long as it
|
|
|
814
|
+appears after the -O flag on the command line (the usual flag-ordering rule for
|
|
|
815
|
+options that -O adjusts).
|
|
|
816
|
+-}
|
|
|
817
|
+
|
|
789
|
818
|
updOptLevelChanged :: Int -> DynFlags -> (DynFlags, Bool)
|
|
790
|
819
|
-- ^ Sets the 'DynFlags' to be appropriate to the optimisation level and signals if any changes took place
|
|
791
|
820
|
updOptLevelChanged n dfs
|
|
792
|
|
- = (dfs3, changed1 || changed2 || changed3)
|
|
|
821
|
+ = (dfs4, changed1 || changed2 || changed3 || changed4)
|
|
793
|
822
|
where
|
|
794
|
823
|
final_n = max 0 (min 2 n) -- Clamp to 0 <= n <= 2
|
|
795
|
824
|
(dfs1, changed1) = foldr unset (dfs , False) remove_gopts
|
|
796
|
825
|
(dfs2, changed2) = foldr set (dfs1, False) extra_gopts
|
|
797
|
826
|
(dfs3, changed3) = setLlvmOptLevel dfs2
|
|
|
827
|
+ (dfs4, changed4) = setSimplIterations dfs3
|
|
798
|
828
|
|
|
799
|
829
|
extra_gopts = [ f | (ns,f) <- optLevelFlags, final_n `elem` ns ]
|
|
800
|
830
|
remove_gopts = [ f | (ns,f) <- optLevelFlags, final_n `notElem` ns ]
|
| ... |
... |
@@ -814,6 +844,14 @@ updOptLevelChanged n dfs |
|
814
|
844
|
| llvmOptLevel dfs /= llvm_n = (dfs{ llvmOptLevel = llvm_n }, True)
|
|
815
|
845
|
| otherwise = (dfs, False)
|
|
816
|
846
|
|
|
|
847
|
+ -- See Note [Simplifier iterations and the optimisation level]
|
|
|
848
|
+ simpl_iters = if final_n == 0 then 2 else 4
|
|
|
849
|
+
|
|
|
850
|
+ setSimplIterations dfs
|
|
|
851
|
+ | maxSimplIterations dfs /= simpl_iters =
|
|
|
852
|
+ (dfs{ maxSimplIterations = simpl_iters }, True)
|
|
|
853
|
+ | otherwise = (dfs, False)
|
|
|
854
|
+
|
|
817
|
855
|
updOptLevel :: Int -> DynFlags -> DynFlags
|
|
818
|
856
|
-- ^ Sets the 'DynFlags' to be appropriate to the optimisation level
|
|
819
|
857
|
updOptLevel n = fst . updOptLevelChanged n
|