summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2018-03-19 13:29:14 -0400
committerBen Gamari <ben@smart-cactus.org>2018-03-19 13:29:23 -0400
commitafad5561d88f04744c398ef0640d846db6262aa0 (patch)
tree1eccb6f5d1daada6f4ef27d8e21596682332362e
parent2d4bda2e4ac68816baba0afab00da6f769ea75a7 (diff)
downloadhaskell-afad5561d88f04744c398ef0640d846db6262aa0.tar.gz
Add -flate-specialise which runs a later specialisation pass
Runs another specialisation pass towards the end of the optimisation pipeline. This can catch specialisation opportunities which arose from the previous specialisation pass or other inlining. You might want to use this if you are you have a type class method which returns a constrained type. For example, a type class where one of the methods implements a traversal. It is not enabled by default or any optimisation level. Only by manually enabling the flag `-flate-specialise`. Reviewers: bgamari Reviewed By: bgamari Subscribers: rwbarton, thomie, carter Differential Revision: https://phabricator.haskell.org/D4457
-rw-r--r--compiler/main/DynFlags.hs3
-rw-r--r--compiler/simplCore/SimplCore.hs5
-rw-r--r--docs/users_guide/using-optimisation.rst14
3 files changed, 22 insertions, 0 deletions
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index f9d2bfb9da..0d018a7ec4 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -450,6 +450,7 @@ data GeneralFlag
| Opt_KillOneShot
| Opt_FullLaziness
| Opt_FloatIn
+ | Opt_LateSpecialise
| Opt_Specialise
| Opt_SpecialiseAggressively
| Opt_CrossModuleSpecialise
@@ -633,6 +634,7 @@ optimisationFlags = EnumSet.fromList
, Opt_KillOneShot
, Opt_FullLaziness
, Opt_FloatIn
+ , Opt_LateSpecialise
, Opt_Specialise
, Opt_SpecialiseAggressively
, Opt_CrossModuleSpecialise
@@ -3937,6 +3939,7 @@ fFlagsDeps = [
flagSpec "kill-absence" Opt_KillAbsence,
flagSpec "kill-one-shot" Opt_KillOneShot,
flagSpec "late-dmd-anal" Opt_LateDmdAnal,
+ flagSpec "late-specialise" Opt_LateSpecialise,
flagSpec "liberate-case" Opt_LiberateCase,
flagSpec "llvm-pass-vectors-in-regs" Opt_LlvmPassVectorsInRegisters,
flagHiddenSpec "llvm-tbaa" Opt_LlvmTBAA,
diff --git a/compiler/simplCore/SimplCore.hs b/compiler/simplCore/SimplCore.hs
index bf69964473..61622aecbd 100644
--- a/compiler/simplCore/SimplCore.hs
+++ b/compiler/simplCore/SimplCore.hs
@@ -131,6 +131,7 @@ getCoreToDo dflags
spec_constr = gopt Opt_SpecConstr dflags
liberate_case = gopt Opt_LiberateCase dflags
late_dmd_anal = gopt Opt_LateDmdAnal dflags
+ late_specialise = gopt Opt_LateSpecialise dflags
static_args = gopt Opt_StaticArgumentTransformation dflags
rules_on = gopt Opt_EnableRewriteRules dflags
eta_expand_on = gopt Opt_DoLambdaEtaExpansion dflags
@@ -347,6 +348,10 @@ getCoreToDo dflags
maybe_rule_check (Phase 0),
+ runWhen late_specialise
+ (CoreDoPasses [ CoreDoSpecialising
+ , simpl_phase 0 ["post-late-spec"] max_iter]),
+
-- Final clean-up simplification:
simpl_phase 0 ["final"] max_iter,
diff --git a/docs/users_guide/using-optimisation.rst b/docs/users_guide/using-optimisation.rst
index 3566462eeb..d6c24de502 100644
--- a/docs/users_guide/using-optimisation.rst
+++ b/docs/users_guide/using-optimisation.rst
@@ -884,6 +884,20 @@ by saying ``-fno-wombat``.
which they are called in this module. Note that specialisation must be
enabled (by ``-fspecialise``) for this to have any effect.
+.. ghc-flag:: -flate-specialise
+ :shortdesc: Run a late specialisation pass
+ :type: dynamic
+ :reverse: -fno-late-specialise
+ :default: off
+
+ Runs another specialisation pass towards the end of the optimisation
+ pipeline. This can catch specialisation opportunities which arose from
+ the previous specialisation pass or other inlining.
+
+ You might want to use this if you are you have a type class method
+ which returns a constrained type. For example, a type class where one
+ of the methods implements a traversal.
+
.. ghc-flag:: -fsolve-constant-dicts
:shortdesc: When solving constraints, try to eagerly solve
super classes using available dictionaries.