summaryrefslogtreecommitdiff
path: root/compiler/GHC/CoreToStg
diff options
context:
space:
mode:
authorSimon Peyton Jones <simon.peytonjones@gmail.com>2023-01-12 22:21:40 +0000
committerSimon Peyton Jones <simon.peytonjones@gmail.com>2023-01-31 08:54:52 +0000
commitae22d1096df1bd83b5ce9ef5d8c2bd8c00e20bad (patch)
treedc345c52cefcb688e3be7447551cb0a0bedfb492 /compiler/GHC/CoreToStg
parentb69461a06166d2b1c600df87b87656d09122fb7c (diff)
downloadhaskell-wip/T22745.tar.gz
Improve exprOkForSpeculation for classopswip/T22745
This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord
Diffstat (limited to 'compiler/GHC/CoreToStg')
-rw-r--r--compiler/GHC/CoreToStg/Prep.hs10
1 files changed, 7 insertions, 3 deletions
diff --git a/compiler/GHC/CoreToStg/Prep.hs b/compiler/GHC/CoreToStg/Prep.hs
index 78ce8e16f1..c0b72cefed 100644
--- a/compiler/GHC/CoreToStg/Prep.hs
+++ b/compiler/GHC/CoreToStg/Prep.hs
@@ -1648,12 +1648,16 @@ long as the callee might evaluate it. And if it is evaluated on
most code paths anyway, we get to turn the unknown eval in the
callee into a known call at the call site.
-However, we must be very careful not to speculate recursive calls!
-Doing so might well change termination behavior.
+Very Nasty Wrinkle
+
+We must be very careful not to speculate recursive calls! Doing so
+might well change termination behavior.
That comes up in practice for DFuns, which are considered ok-for-spec,
because they always immediately return a constructor.
-Not so if you speculate the recursive call, as #20836 shows:
+See Note [NON-BOTTOM-DICTS invariant] in GHC.Core.
+
+But not so if you speculate the recursive call, as #20836 shows:
class Foo m => Foo m where
runFoo :: m a -> m a