summaryrefslogtreecommitdiff
path: root/compiler/GHC/Data
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2022-05-19 18:37:38 +0200
committerSebastian Graf <sebastian.graf@kit.edu>2022-06-20 09:43:29 +0200
commitb570da84b7aad5ca3f90f2d1c1a690c927e99fe9 (patch)
tree9210e2e9c3f37477db705df57dbf359da9e95baa /compiler/GHC/Data
parent94f2e92a2510a3338c5201a4dcc69666fa9575f8 (diff)
downloadhaskell-b570da84b7aad5ca3f90f2d1c1a690c927e99fe9.tar.gz
CorePrep: Don't speculatively evaluate recursive calls (#20836)
In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836.
Diffstat (limited to 'compiler/GHC/Data')
-rw-r--r--compiler/GHC/Data/Graph/UnVar.hs8
1 files changed, 7 insertions, 1 deletions
diff --git a/compiler/GHC/Data/Graph/UnVar.hs b/compiler/GHC/Data/Graph/UnVar.hs
index 5bfc23eef6..f5a9e1e54a 100644
--- a/compiler/GHC/Data/Graph/UnVar.hs
+++ b/compiler/GHC/Data/Graph/UnVar.hs
@@ -17,7 +17,7 @@ equal to g, but twice as expensive and large.
module GHC.Data.Graph.UnVar
( UnVarSet
, emptyUnVarSet, mkUnVarSet, varEnvDom, unionUnVarSet, unionUnVarSets
- , extendUnVarSet, delUnVarSet
+ , extendUnVarSet, extendUnVarSetList, delUnVarSet, delUnVarSetList
, elemUnVarSet, isEmptyUnVarSet
, UnVarGraph
, emptyUnVarGraph
@@ -63,6 +63,9 @@ isEmptyUnVarSet (UnVarSet s) = S.null s
delUnVarSet :: UnVarSet -> Var -> UnVarSet
delUnVarSet (UnVarSet s) v = UnVarSet $ k v `S.delete` s
+delUnVarSetList :: UnVarSet -> [Var] -> UnVarSet
+delUnVarSetList s vs = s `minusUnVarSet` mkUnVarSet vs
+
minusUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet
minusUnVarSet (UnVarSet s) (UnVarSet s') = UnVarSet $ s `S.difference` s'
@@ -78,6 +81,9 @@ varEnvDom ae = UnVarSet $ ufmToSet_Directly ae
extendUnVarSet :: Var -> UnVarSet -> UnVarSet
extendUnVarSet v (UnVarSet s) = UnVarSet $ S.insert (k v) s
+extendUnVarSetList :: [Var] -> UnVarSet -> UnVarSet
+extendUnVarSetList vs s = s `unionUnVarSet` mkUnVarSet vs
+
unionUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet
unionUnVarSet (UnVarSet set1) (UnVarSet set2) = UnVarSet (set1 `S.union` set2)