diff options
author | Simon Peyton Jones <simon.peytonjones@gmail.com> | 2023-01-12 22:21:40 +0000 |
---|---|---|
committer | Simon Peyton Jones <simon.peytonjones@gmail.com> | 2023-01-31 08:54:52 +0000 |
commit | ae22d1096df1bd83b5ce9ef5d8c2bd8c00e20bad (patch) | |
tree | dc345c52cefcb688e3be7447551cb0a0bedfb492 /compiler/GHC/CoreToStg | |
parent | b69461a06166d2b1c600df87b87656d09122fb7c (diff) | |
download | haskell-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.hs | 10 |
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 |