-
-
Save k-bx/9b4a3d95f2de9c86b50dca1c615c63e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compiler/basicTypes/VarEnv.hs b/compiler/basicTypes/VarEnv.hs | |
index e22c207858..59304002a9 100644 | |
--- a/compiler/basicTypes/VarEnv.hs | |
+++ b/compiler/basicTypes/VarEnv.hs | |
@@ -34,7 +34,7 @@ module VarEnv ( | |
extendDVarEnvList, | |
lookupDVarEnv, elemDVarEnv, | |
isEmptyDVarEnv, foldDVarEnv, | |
- mapDVarEnv, | |
+ mapDVarEnv, filterDVarEnv, | |
modifyDVarEnv, | |
alterDVarEnv, | |
plusDVarEnv, plusDVarEnv_C, | |
@@ -555,6 +555,9 @@ foldDVarEnv = foldUDFM | |
mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b | |
mapDVarEnv = mapUDFM | |
+filterDVarEnv :: (a -> Bool) -> DVarEnv a -> DVarEnv a | |
+filterDVarEnv = filterUDFM | |
+ | |
alterDVarEnv :: (Maybe a -> Maybe a) -> DVarEnv a -> Var -> DVarEnv a | |
alterDVarEnv = alterUDFM | |
diff --git a/compiler/typecheck/TcEvidence.hs b/compiler/typecheck/TcEvidence.hs | |
index bf62152606..759147a820 100644 | |
--- a/compiler/typecheck/TcEvidence.hs | |
+++ b/compiler/typecheck/TcEvidence.hs | |
@@ -13,7 +13,8 @@ module TcEvidence ( | |
-- Evidence bindings | |
TcEvBinds(..), EvBindsVar(..), | |
EvBindMap(..), emptyEvBindMap, extendEvBinds, | |
- lookupEvBind, evBindMapBinds, foldEvBindMap, isEmptyEvBindMap, | |
+ lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap, | |
+ isEmptyEvBindMap, | |
EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, | |
sccEvBinds, evBindVar, | |
EvTerm(..), mkEvCast, evVarsOfTerm, mkEvScSelectors, | |
@@ -436,6 +437,10 @@ evBindMapBinds = foldEvBindMap consBag emptyBag | |
foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a | |
foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) | |
+filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap | |
+filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) | |
+ = EvBindMap { ev_bind_varenv = filterDVarEnv k env } | |
+ | |
instance Outputable EvBindMap where | |
ppr (EvBindMap m) = ppr m | |
diff --git a/compiler/typecheck/TcInstDcls.hs b/compiler/typecheck/TcInstDcls.hs | |
index 8917fee0b8..a12165ccaa 100644 | |
--- a/compiler/typecheck/TcInstDcls.hs | |
+++ b/compiler/typecheck/TcInstDcls.hs | |
@@ -818,16 +818,14 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) | |
, sc_implics `unionBags` meth_implics ) } | |
; env <- getLclEnv | |
- ; emitImplication $ Implic { ic_tclvl = tclvl | |
- , ic_skols = inst_tyvars | |
- , ic_no_eqs = False | |
- , ic_given = dfun_ev_vars | |
- , ic_wanted = mkImplicWC sc_meth_implics | |
- , ic_status = IC_Unsolved | |
- , ic_binds = dfun_ev_binds_var | |
- , ic_needed = emptyVarSet | |
- , ic_env = env | |
- , ic_info = InstSkol } | |
+ ; emitImplication $ | |
+ newImplication { ic_tclvl = tclvl | |
+ , ic_skols = inst_tyvars | |
+ , ic_given = dfun_ev_vars | |
+ , ic_wanted = mkImplicWC sc_meth_implics | |
+ , ic_binds = dfun_ev_binds_var | |
+ , ic_env = env | |
+ , ic_info = InstSkol } | |
-- Create the result bindings | |
; self_dict <- newDict clas inst_tys | |
@@ -1035,16 +1033,11 @@ checkInstConstraints thing_inside | |
; ev_binds_var <- newTcEvBinds | |
; env <- getLclEnv | |
- ; let implic = Implic { ic_tclvl = tclvl | |
- , ic_skols = [] | |
- , ic_no_eqs = False | |
- , ic_given = [] | |
- , ic_wanted = wanted | |
- , ic_status = IC_Unsolved | |
- , ic_binds = ev_binds_var | |
- , ic_needed = emptyVarSet | |
- , ic_env = env | |
- , ic_info = InstSkol } | |
+ ; let implic = newImplication { ic_tclvl = tclvl | |
+ , ic_wanted = wanted | |
+ , ic_binds = ev_binds_var | |
+ , ic_env = env | |
+ , ic_info = InstSkol } | |
; return (implic, ev_binds_var, result) } | |
diff --git a/compiler/typecheck/TcRnMonad.hs b/compiler/typecheck/TcRnMonad.hs | |
index 6cf807512f..6eb2227d08 100644 | |
--- a/compiler/typecheck/TcRnMonad.hs | |
+++ b/compiler/typecheck/TcRnMonad.hs | |
@@ -89,7 +89,7 @@ module TcRnMonad( | |
-- * Type constraints | |
newTcEvBinds, | |
addTcEvBind, | |
- getTcEvTyCoVars, getTcEvBindsMap, | |
+ getTcEvTyCoVars, getTcEvBindsMap, setTcEvBindsMap, | |
chooseUniqueOccTc, | |
getConstraintVar, setConstraintVar, | |
emitConstraints, emitStaticConstraints, emitSimple, emitSimples, | |
@@ -1369,6 +1369,10 @@ getTcEvBindsMap :: EvBindsVar -> TcM EvBindMap | |
getTcEvBindsMap (EvBindsVar { ebv_binds = ev_ref }) | |
= readTcRef ev_ref | |
+setTcEvBindsMap :: EvBindsVar -> EvBindMap -> TcM () | |
+setTcEvBindsMap (EvBindsVar { ebv_binds = ev_ref }) binds | |
+ = writeTcRef ev_ref binds | |
+ | |
addTcEvBind :: EvBindsVar -> EvBind -> TcM () | |
-- Add a binding to the TcEvBinds by side effect | |
addTcEvBind (EvBindsVar { ebv_binds = ev_ref, ebv_uniq = u }) ev_bind | |
diff --git a/compiler/typecheck/TcRnTypes.hs b/compiler/typecheck/TcRnTypes.hs | |
index f38d255ebb..2c25590264 100644 | |
--- a/compiler/typecheck/TcRnTypes.hs | |
+++ b/compiler/typecheck/TcRnTypes.hs | |
@@ -89,7 +89,8 @@ module TcRnTypes( | |
isDroppableDerivedLoc, insolubleImplic, | |
arisesFromGivens, | |
- Implication(..), ImplicStatus(..), isInsolubleStatus, isSolvedStatus, | |
+ Implication(..), newImplication, | |
+ ImplicStatus(..), isInsolubleStatus, isSolvedStatus, | |
SubGoalDepth, initialSubGoalDepth, maxSubGoalDepth, | |
bumpSubGoalDepth, subGoalDepthExceeded, | |
CtLoc(..), ctLocSpan, ctLocEnv, ctLocLevel, ctLocOrigin, | |
@@ -2319,17 +2320,38 @@ data Implication | |
ic_binds :: EvBindsVar, -- Points to the place to fill in the | |
-- abstraction and bindings. | |
- ic_needed :: VarSet, -- Union of the ics_need fields of any /discarded/ | |
- -- solved implications in ic_wanted | |
+ -- The ic_need fields keep track of which Given evidence | |
+ -- is used by this implication or its children | |
+ -- NB: including stuff used by nested implications that have since | |
+ -- been discarded | |
+ ic_need_inner :: VarSet, -- Includes all used Given evidence | |
+ ic_need_outer :: VarSet, -- Includes only the free Given evidence | |
+ -- i.e. ic_need_inner after deleting | |
+ -- (a) givens (b) binders of ic_binds | |
ic_status :: ImplicStatus | |
} | |
+newImplication :: Implication | |
+newImplication | |
+ = Implic { -- These fields must be initialisad | |
+ ic_tclvl = panic "newImplic:tclvl" | |
+ , ic_binds = panic "newImplic:binds" | |
+ , ic_info = panic "newImplic:info" | |
+ , ic_env = panic "newImplic:env" | |
+ | |
+ -- The rest have sensible default values | |
+ , ic_skols = [] | |
+ , ic_given = [] | |
+ , ic_wanted = emptyWC | |
+ , ic_no_eqs = False | |
+ , ic_status = IC_Unsolved | |
+ , ic_need_inner = emptyVarSet | |
+ , ic_need_outer = emptyVarSet } | |
+ | |
data ImplicStatus | |
= IC_Solved -- All wanteds in the tree are solved, all the way down | |
- { ics_need :: VarSet -- Evidence variables bound further out, | |
- -- but needed by this solved implication | |
- , ics_dead :: [EvVar] } -- Subset of ic_given that are not needed | |
+ { ics_dead :: [EvVar] } -- Subset of ic_given that are not needed | |
-- See Note [Tracking redundant constraints] in TcSimplify | |
| IC_Insoluble -- At least one insoluble constraint in the tree | |
@@ -2340,7 +2362,8 @@ instance Outputable Implication where | |
ppr (Implic { ic_tclvl = tclvl, ic_skols = skols | |
, ic_given = given, ic_no_eqs = no_eqs | |
, ic_wanted = wanted, ic_status = status | |
- , ic_binds = binds, ic_needed = needed , ic_info = info }) | |
+ , ic_binds = binds, ic_need_inner = need_in | |
+ , ic_need_outer = need_out, ic_info = info }) | |
= hang (text "Implic" <+> lbrace) | |
2 (sep [ text "TcLevel =" <+> ppr tclvl | |
, text "Skolems =" <+> pprTyVars skols | |
@@ -2349,16 +2372,15 @@ instance Outputable Implication where | |
, hang (text "Given =") 2 (pprEvVars given) | |
, hang (text "Wanted =") 2 (ppr wanted) | |
, text "Binds =" <+> ppr binds | |
- , text "Needed =" <+> ppr needed | |
+ , text "Needed inner =" <+> ppr need_in | |
+ , text "Needed outer =" <+> ppr need_out | |
, pprSkolInfo info ] <+> rbrace) | |
instance Outputable ImplicStatus where | |
ppr IC_Insoluble = text "Insoluble" | |
ppr IC_Unsolved = text "Unsolved" | |
- ppr (IC_Solved { ics_need = vs, ics_dead = dead }) | |
- = text "Solved" | |
- <+> (braces $ vcat [ text "Dead givens =" <+> ppr dead | |
- , text "Needed =" <+> ppr vs ]) | |
+ ppr (IC_Solved { ics_dead = dead }) | |
+ = text "Solved" <+> (braces (text "Dead givens =" <+> ppr dead)) | |
{- | |
Note [Needed evidence variables] | |
diff --git a/compiler/typecheck/TcSMonad.hs b/compiler/typecheck/TcSMonad.hs | |
index feff170a58..8cc2c186e6 100644 | |
--- a/compiler/typecheck/TcSMonad.hs | |
+++ b/compiler/typecheck/TcSMonad.hs | |
@@ -42,9 +42,8 @@ module TcSMonad ( | |
getInstEnvs, getFamInstEnvs, -- Getting the environments | |
getTopEnv, getGblEnv, getLclEnv, | |
getTcEvBindsVar, getTcLevel, | |
- getTcEvBindsAndTCVs, getTcEvBindsMap, | |
- tcLookupClass, | |
- tcLookupId, | |
+ getTcEvTyCoVars, getTcEvBindsMap, setTcEvBindsMap, | |
+ tcLookupClass, tcLookupId, | |
-- Inerts | |
InertSet(..), InertCans(..), | |
@@ -2531,16 +2530,13 @@ buildImplication skol_info skol_tvs givens (TcS thing_inside) | |
WC { wc_simple = listToCts eqs | |
, wc_impl = emptyBag | |
, wc_insol = emptyCts } | |
- imp = Implic { ic_tclvl = new_tclvl | |
- , ic_skols = skol_tvs | |
- , ic_no_eqs = True | |
- , ic_given = givens | |
- , ic_wanted = wc | |
- , ic_status = IC_Unsolved | |
- , ic_binds = ev_binds_var | |
- , ic_env = env | |
- , ic_needed = emptyVarSet | |
- , ic_info = skol_info } | |
+ imp = newImplication { ic_tclvl = new_tclvl | |
+ , ic_skols = skol_tvs | |
+ , ic_given = givens | |
+ , ic_wanted = wc | |
+ , ic_binds = ev_binds_var | |
+ , ic_env = env | |
+ , ic_info = skol_info } | |
; return (unitBag imp, TcEvBinds ev_binds_var, res) } } | |
{- | |
@@ -2627,17 +2623,19 @@ getTcEvBindsVar = TcS (return . tcs_ev_binds) | |
getTcLevel :: TcS TcLevel | |
getTcLevel = wrapTcS TcM.getTcLevel | |
-getTcEvBindsAndTCVs :: EvBindsVar -> TcS (EvBindMap, TyCoVarSet) | |
-getTcEvBindsAndTCVs ev_binds_var | |
- = wrapTcS $ do { bnds <- TcM.getTcEvBindsMap ev_binds_var | |
- ; tcvs <- TcM.getTcEvTyCoVars ev_binds_var | |
- ; return (bnds, tcvs) } | |
+getTcEvTyCoVars :: EvBindsVar -> TcS TyCoVarSet | |
+getTcEvTyCoVars ev_binds_var | |
+ = wrapTcS $ TcM.getTcEvTyCoVars ev_binds_var | |
getTcEvBindsMap :: TcS EvBindMap | |
getTcEvBindsMap | |
= do { ev_binds_var <- getTcEvBindsVar | |
; wrapTcS $ TcM.getTcEvBindsMap ev_binds_var } | |
+setTcEvBindsMap :: EvBindsVar -> EvBindMap -> TcS () | |
+setTcEvBindsMap ev_binds_var binds | |
+ = wrapTcS $ TcM.setTcEvBindsMap ev_binds_var binds | |
+ | |
unifyTyVar :: TcTyVar -> TcType -> TcS () | |
-- Unify a meta-tyvar with a type | |
-- We keep track of how many unifications have happened in tcs_unified, | |
diff --git a/compiler/typecheck/TcSimplify.hs b/compiler/typecheck/TcSimplify.hs | |
index dc9c85829a..c63712438f 100644 | |
--- a/compiler/typecheck/TcSimplify.hs | |
+++ b/compiler/typecheck/TcSimplify.hs | |
@@ -25,7 +25,6 @@ import DynFlags ( WarningFlag ( Opt_WarnMonomorphism ) | |
import Id ( idType ) | |
import Inst | |
import ListSetOps | |
-import Maybes | |
import Name | |
import Outputable | |
import PrelInfo | |
@@ -682,16 +681,13 @@ emitResidualImplication rhs_tclvl tc_lcl_env ev_binds_var | |
= do { traceTc "emitResidualImplication" (ppr implic) | |
; emitImplication implic } | |
where | |
- implic = Implic { ic_tclvl = rhs_tclvl | |
- , ic_skols = qtvs | |
- , ic_no_eqs = False | |
- , ic_given = full_theta_vars | |
- , ic_wanted = wanteds | |
- , ic_status = IC_Unsolved | |
- , ic_binds = ev_binds_var | |
- , ic_info = skol_info | |
- , ic_needed = emptyVarSet | |
- , ic_env = tc_lcl_env } | |
+ implic = newImplication { ic_tclvl = rhs_tclvl | |
+ , ic_skols = qtvs | |
+ , ic_given = full_theta_vars | |
+ , ic_wanted = wanteds | |
+ , ic_binds = ev_binds_var | |
+ , ic_info = skol_info | |
+ , ic_env = tc_lcl_env } | |
full_theta = map idType full_theta_vars | |
skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) | |
@@ -1416,7 +1412,8 @@ solveImplication imp@(Implic { ic_tclvl = tclvl | |
; res_implic <- setImplicationStatus (imp { ic_no_eqs = no_given_eqs | |
, ic_wanted = final_wanted }) | |
- ; (evbinds, tcvs) <- TcS.getTcEvBindsAndTCVs ev_binds_var | |
+ ; evbinds <- TcS.getTcEvBindsMap | |
+ ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var | |
; traceTcS "solveImplication end }" $ vcat | |
[ text "no_given_eqs =" <+> ppr no_given_eqs | |
, text "floated_eqs =" <+> ppr floated_eqs | |
@@ -1433,99 +1430,90 @@ setImplicationStatus :: Implication -> TcS (Maybe Implication) | |
-- * Trim the ic_wanted field to remove Derived constraints | |
-- Precondition: the ic_status field is not already IC_Solved | |
-- Return Nothing if we can discard the implication altogether | |
-setImplicationStatus implic@(Implic { ic_binds = ev_binds_var | |
- , ic_status = status | |
+setImplicationStatus implic@(Implic { ic_status = status | |
, ic_info = info | |
, ic_wanted = wc | |
- , ic_needed = old_discarded_needs | |
, ic_given = givens }) | |
| ASSERT2( not (isSolvedStatus status ), ppr info ) | |
-- Precondition: we only set the status if it is not already solved | |
- some_insoluble | |
- = return $ Just $ | |
- implic { ic_status = IC_Insoluble | |
- , ic_needed = new_discarded_needs | |
- , ic_wanted = pruned_wc } | |
- | |
- | some_unsolved | |
- = do { traceTcS "setImplicationStatus" $ | |
- vcat [ppr givens $$ ppr simples $$ ppr insols $$ ppr mb_implic_needs] | |
- ; return $ Just $ | |
- implic { ic_status = IC_Unsolved | |
- , ic_needed = new_discarded_needs | |
- , ic_wanted = pruned_wc } | |
- } | |
- | |
- | otherwise -- Everything is solved; look at the implications | |
+ -- some_insoluble | |
+ -- = return $ Just $ | |
+ -- implic { ic_status = IC_Insoluble | |
+ -- , ic_needed = new_discarded_needs | |
+ -- , ic_wanted = pruned_wc } | |
+ | |
+ -- | some_unsolved | |
+ -- = do { traceTcS "setImplicationStatus" $ | |
+ -- vcat [ppr givens $$ ppr simples $$ ppr insols $$ ppr mb_implic_needs] | |
+ -- ; return $ Just $ | |
+ -- implic { ic_status = IC_Unsolved | |
+ -- , ic_needed = new_discarded_needs | |
+ -- , ic_wanted = pruned_wc } | |
+ -- } | |
+ | |
+ -- | otherwise -- Everything is solved; look at the implications | |
+ not all_solved | |
+ = do { traceTcS "setImplicationStatus(not-all-solved) {" (ppr implic) | |
+ | |
+ ; implic <- neededEvVars implic | |
+ | |
+ ; let new_status | insolubleWC pruned_wc = IC_Insoluble | |
+ | otherwise = IC_Unsolved | |
+ new_implic = implic { ic_status = new_status | |
+ , ic_wanted = pruned_wc } | |
+ | |
+ ; traceTcS "setImplicationStatus(not-all-solved) }" (ppr new_implic) | |
+ | |
+ ; return $ Just new_implic } | |
+ | |
+ | otherwise -- Everything is solved | |
+ -- Set status to IC_Solved, | |
+ -- and compute the dead givens and outer needs | |
-- See Note [Tracking redundant constraints] | |
- = do { ev_binds <- TcS.getTcEvBindsAndTCVs ev_binds_var | |
- ; let all_needs = neededEvVars ev_binds $ | |
- solved_implic_needs `unionVarSet` new_discarded_needs | |
- | |
- dead_givens | warnRedundantGivens info | |
- = filterOut (`elemVarSet` all_needs) givens | |
+ = do { traceTcS "setImplicationStatus(all-solved) {" (ppr implic) | |
+ ; implic <- neededEvVars implic | |
+ ; let dead_givens | warnRedundantGivens info | |
+ = filterOut (`elemVarSet` ic_need_inner implic) givens | |
| otherwise = [] -- None to report | |
- | |
- final_needs = all_needs `delVarSetList` givens | |
- | |
discard_entire_implication -- Can we discard the entire implication? | |
= null dead_givens -- No warning from this implication | |
&& isEmptyBag pruned_implics -- No live children | |
- && isEmptyVarSet final_needs -- No needed vars to pass up to parent | |
+ && isEmptyVarSet (ic_need_outer implic) -- No needed vars to pass up to parent | |
- final_status = IC_Solved { ics_need = final_needs | |
- , ics_dead = dead_givens } | |
+ final_status = IC_Solved { ics_dead = dead_givens } | |
final_implic = implic { ic_status = final_status | |
- , ic_needed = emptyVarSet -- Irrelevant for IC_Solved | |
, ic_wanted = pruned_wc } | |
- -- Check that there are no term-level evidence bindings | |
- -- in the cases where we have no place to put them | |
- ; MASSERT2( termEvidenceAllowed info || isEmptyEvBindMap (fst ev_binds) | |
- , ppr info $$ ppr ev_binds ) | |
+ ; traceTcS "setImplicationStatus(all-solved) }" $ | |
+ vcat [ text "discard:" <+> ppr discard_entire_implication | |
+ , text "new_implic:" <+> ppr final_implic ] | |
- ; traceTcS "setImplicationStatus 2" $ | |
- vcat [ppr givens $$ ppr ev_binds $$ ppr all_needs] | |
; return $ if discard_entire_implication | |
then Nothing | |
else Just final_implic } | |
where | |
WC { wc_simple = simples, wc_impl = implics, wc_insol = insols } = wc | |
- some_insoluble = insolubleWC wc | |
- some_unsolved = not (isEmptyBag simples && isEmptyBag insols) | |
- || isNothing mb_implic_needs | |
- | |
pruned_simples = dropDerivedSimples simples | |
pruned_insols = dropDerivedInsols insols | |
- (pruned_implics, discarded_needs) = partitionBagWith discard_me implics | |
- pruned_wc = wc { wc_simple = pruned_simples | |
+ pruned_implics = filterBag keep_me implics | |
+ pruned_wc = WC { wc_simple = pruned_simples | |
, wc_insol = pruned_insols | |
, wc_impl = pruned_implics } | |
- new_discarded_needs = foldrBag unionVarSet old_discarded_needs discarded_needs | |
- | |
- mb_implic_needs :: Maybe VarSet | |
- -- Just vs => all implics are IC_Solved, with 'vs' needed | |
- -- Nothing => at least one implic is not IC_Solved | |
- mb_implic_needs = foldrBag add_implic (Just emptyVarSet) pruned_implics | |
- Just solved_implic_needs = mb_implic_needs | |
- | |
- add_implic implic acc | |
- | Just vs_acc <- acc | |
- , IC_Solved { ics_need = vs } <- ic_status implic | |
- = Just (vs `unionVarSet` vs_acc) | |
- | otherwise = Nothing | |
- | |
- discard_me :: Implication -> Either Implication VarSet | |
- discard_me ic | |
- | IC_Solved { ics_dead = dead_givens, ics_need = needed } <- ic_status ic | |
+ | |
+ all_solved = isEmptyBag pruned_simples | |
+ && allBag (isSolvedStatus . ic_status) pruned_implics | |
+ | |
+ keep_me :: Implication -> Bool | |
+ keep_me ic | |
+ | IC_Solved { ics_dead = dead_givens } <- ic_status ic | |
-- Fully solved | |
, null dead_givens -- No redundant givens to report | |
, isEmptyBag (wc_impl (ic_wanted ic)) | |
-- And no children that might have things to report | |
- = Right needed | |
+ = False -- Tnen we don't need to keep it | |
| otherwise | |
- = Left ic | |
+ = True -- Otherwise, keep it | |
warnRedundantGivens :: SkolemInfo -> Bool | |
warnRedundantGivens (SigSkol ctxt _ _) | |
@@ -1539,38 +1527,82 @@ warnRedundantGivens (SigSkol ctxt _ _) | |
warnRedundantGivens (InstSkol {}) = True | |
warnRedundantGivens _ = False | |
-neededEvVars :: (EvBindMap, TcTyVarSet) -> VarSet -> VarSet | |
+neededEvVars :: Implication -> TcS Implication | |
-- Find all the evidence variables that are "needed", | |
--- and then delete all those bound by the evidence bindings | |
--- See Note [Tracking redundant constraints] | |
+-- and delete dead evidence bindings | |
+-- See Note [Tracking redundant constraints] | |
+-- See Note [Delete dead Given evidence bindings] | |
-- | |
-- - Start from initial_seeds (from nested implications) | |
+-- | |
-- - Add free vars of RHS of all Wanted evidence bindings | |
-- and coercion variables accumulated in tcvs (all Wanted) | |
--- - Do transitive closure through Given bindings | |
--- e.g. Neede {a,b} | |
+-- | |
+-- - Generate 'needed', the needed set of EvVars, by doing transitive | |
+-- closure through Given bindings | |
+-- e.g. Needed {a,b} | |
-- Given a = sc_sel a2 | |
-- Then a2 is needed too | |
--- - Finally delete all the binders of the evidence bindings | |
-- | |
-neededEvVars (ev_binds, tcvs) initial_seeds | |
- = needed `minusVarSet` bndrs | |
+-- - Prune out all Given bindings that are not needed | |
+-- | |
+-- - From the 'needed' set, delete ev_bndrs, the binders of the | |
+-- evidence bindings, to give the final needed variables | |
+-- | |
+neededEvVars implic@(Implic { ic_info = info | |
+ , ic_given = givens | |
+ , ic_binds = ev_binds_var | |
+ , ic_wanted = WC { wc_impl = implics } | |
+ , ic_need_inner = old_needs }) | |
+ = do { ev_binds <- TcS.getTcEvBindsMap | |
+ ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var | |
+ | |
+ -- Check that there are no term-level evidence bindings | |
+ -- in the cases where we have no place to put them | |
+ ; MASSERT2( termEvidenceAllowed info || isEmptyEvBindMap ev_binds | |
+ , ppr info $$ ppr ev_binds ) | |
+ | |
+ ; let seeds1 = foldrBag add_implic_seeds old_needs implics | |
+ seeds2 = foldEvBindMap add_wanted seeds1 ev_binds | |
+ seeds3 = seeds2 `unionVarSet` tcvs | |
+ need_inner = transCloVarSet (also_needs ev_binds) seeds3 | |
+ live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds | |
+ need_outer = foldEvBindMap del_ev_bndr need_inner live_ev_binds | |
+ `delVarSetList` givens | |
+ | |
+ ; TcS.setTcEvBindsMap ev_binds_var live_ev_binds | |
+ -- See Note [Delete dead Given evidence bindings] | |
+ | |
+ ; traceTcS "neededEvVars" $ | |
+ vcat [ text "old_needs:" <+> ppr old_needs | |
+ , text "seeds3:" <+> ppr seeds3 | |
+ , text "ev_binds:" <+> ppr ev_binds | |
+ , text "live_ev_binds:" <+> ppr live_ev_binds ] | |
+ | |
+ ; return (implic { ic_need_inner = need_inner | |
+ , ic_need_outer = need_outer }) } | |
where | |
- needed = transCloVarSet also_needs seeds | |
- seeds = foldEvBindMap add_wanted initial_seeds ev_binds | |
- `unionVarSet` tcvs | |
- bndrs = foldEvBindMap add_bndr emptyVarSet ev_binds | |
+ add_implic_seeds (Implic { ic_need_outer = needs, ic_given = givens }) acc | |
+ = (needs `delVarSetList` givens) `unionVarSet` acc | |
+ | |
+ needed_ev_bind needed (EvBind { eb_lhs = ev_var | |
+ , eb_is_given = is_given }) | |
+ | is_given = ev_var `elemVarSet` needed | |
+ | otherwise = True -- Keep all wanted bindings | |
+ | |
+ del_ev_bndr :: EvBind -> VarSet -> VarSet | |
+ del_ev_bndr (EvBind { eb_lhs = v }) needs = delVarSet needs v | |
add_wanted :: EvBind -> VarSet -> VarSet | |
add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | |
| is_given = needs -- Add the rhs vars of the Wanted bindings only | |
| otherwise = evVarsOfTerm rhs `unionVarSet` needs | |
- also_needs :: VarSet -> VarSet | |
- also_needs needs | |
+ also_needs :: EvBindMap -> VarSet -> VarSet | |
+ also_needs ev_binds needs | |
= nonDetFoldUniqSet add emptyVarSet needs | |
- -- It's OK to use nonDetFoldUFM here because we immediately forget | |
- -- about the ordering by creating a set | |
+ -- It's OK to use nonDetFoldUFM here because we immediately | |
+ -- forget about the ordering by creating a set | |
where | |
add v needs | |
| Just ev_bind <- lookupEvBind ev_binds v | |
@@ -1580,11 +1612,43 @@ neededEvVars (ev_binds, tcvs) initial_seeds | |
| otherwise | |
= needs | |
- add_bndr :: EvBind -> VarSet -> VarSet | |
- add_bndr (EvBind { eb_lhs = v }) vs = extendVarSet vs v | |
- | |
+{- Note [Delete dead Given evidence bindings] | |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
+As a result of superclass expansion, we speculatively | |
+generate evidence bindings for Givens. E.g. | |
+ f :: (a ~ b) => a -> b -> Bool | |
+ f x y = ... | |
+We'll have | |
+ [G] d1 :: (a~b) | |
+and we'll specuatively generate the evidence binding | |
+ [G] d2 :: (a ~# b) = sc_sel d | |
+ | |
+Now d2 is available for solving. But it may not be needed! Usually | |
+such dead superclass selections will eventually be dropped as dead | |
+code, but: | |
+ | |
+ * It won't always be dropped (Trac #13032). In the case of an | |
+ unlifted-equality superclass like d2 above, we generate | |
+ case heq_sc d1 of d2 -> ... | |
+ and we can't (in general) drop that case exrpession in case | |
+ d1 is bottom. So it's technically unsound to have added it | |
+ in the first place. | |
+ | |
+ * Simply generating all those extra superclasses can generate lots of | |
+ code that has to be zonked, only to be discarded later. Better not | |
+ to generate it in the first place. | |
+ | |
+ Moreover, if we simplify this implication more than once | |
+ (e.g. because we can't solve it completely on the first iteration | |
+ of simpl_looop), we'll generate all the same bindings AGAIN! | |
+ | |
+Easy solution: take advantage of the work we are doing to track dead | |
+(unused) Givens, and use it to prune the Given bindings too. This is | |
+all done by neededEvVars. | |
+ | |
+This led to a remarkable 25% overall compiler allocation decrease in | |
+test T12227. | |
-{- | |
Note [Tracking redundant constraints] | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
With Opt_WarnRedundantConstraints, GHC can report which | |
@@ -1621,18 +1685,16 @@ works: | |
----- How tracking works | |
+* The ic_need fields of an Implic records in-scope (given) evidence | |
+ variables bound by the context, that were needed to solve this | |
+ implication (so far). See the declaration of Implication. | |
+ | |
* When the constraint solver finishes solving all the wanteds in | |
an implication, it sets its status to IC_Solved | |
- The ics_dead field, of IC_Solved, records the subset of this | |
implication's ic_given that are redundant (not needed). | |
- - The ics_need field of IC_Solved then records all the | |
- in-scope (given) evidence variables bound by the context, that | |
- were needed to solve this implication, including all its nested | |
- implications. (We remove the ic_given of this implication from | |
- the set, of course.) | |
- | |
* We compute which evidence variables are needed by an implication | |
in setImplicationStatus. A variable is needed if | |
a) it is free in the RHS of a Wanted EvBind, | |
diff --git a/compiler/typecheck/TcUnify.hs b/compiler/typecheck/TcUnify.hs | |
index 6d3916950d..8ff9b27c52 100644 | |
--- a/compiler/typecheck/TcUnify.hs | |
+++ b/compiler/typecheck/TcUnify.hs | |
@@ -1133,16 +1133,13 @@ buildImplicationFor tclvl skol_info skol_tvs given wanted | |
= ASSERT2( all isSkolemTyVar skol_tvs, ppr skol_tvs ) | |
do { ev_binds_var <- newTcEvBinds | |
; env <- getLclEnv | |
- ; let implic = Implic { ic_tclvl = tclvl | |
- , ic_skols = skol_tvs | |
- , ic_no_eqs = False | |
- , ic_given = given | |
- , ic_wanted = wanted | |
- , ic_status = IC_Unsolved | |
- , ic_binds = ev_binds_var | |
- , ic_env = env | |
- , ic_needed = emptyVarSet | |
- , ic_info = skol_info } | |
+ ; let implic = newImplication { ic_tclvl = tclvl | |
+ , ic_skols = skol_tvs | |
+ , ic_given = given | |
+ , ic_wanted = wanted | |
+ , ic_binds = ev_binds_var | |
+ , ic_env = env | |
+ , ic_info = skol_info } | |
; return (unitBag implic, TcEvBinds ev_binds_var) } | |
diff --git a/testsuite/tests/indexed-types/should_compile/T7837.stderr b/testsuite/tests/indexed-types/should_compile/T7837.stderr | |
index eb682613b9..7bca960e00 100644 | |
--- a/testsuite/tests/indexed-types/should_compile/T7837.stderr | |
+++ b/testsuite/tests/indexed-types/should_compile/T7837.stderr | |
@@ -2,4 +2,3 @@ Rule fired: Class op signum (BUILTIN) | |
Rule fired: Class op abs (BUILTIN) | |
Rule fired: Class op HEq_sc (BUILTIN) | |
Rule fired: normalize/Double (T7837) | |
-Rule fired: Class op HEq_sc (BUILTIN) | |
diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T | |
index 6fbde0d009..e088c6fbc2 100644 | |
--- a/testsuite/tests/perf/compiler/all.T | |
+++ b/testsuite/tests/perf/compiler/all.T | |
@@ -994,12 +994,13 @@ test('T10547', | |
test('T12227', | |
[ only_ways(['normal']), | |
compiler_stats_num_field('bytes allocated', | |
- [(wordsize(64), 1060158624, 5), | |
+ [(wordsize(64), 812869424, 5), | |
# 2016-07-11 5650186880 (Windows) before fix for #12227 | |
# 2016-07-11 1822822016 (Windows) after fix for #12227 | |
# 2016-12-20 1715827784 after d250d493 (INLINE in Traversable dms) | |
# (or thereabouts in the commit history) | |
# 2017-02-14 1060158624 Early inlining: 35% improvement | |
+ # 2018-01-04 812869424 Drop unused givens (#13032): 23% better | |
]), | |
], | |
compile, | |
diff --git a/testsuite/tests/simplCore/should_compile/T4398.stderr b/testsuite/tests/simplCore/should_compile/T4398.stderr | |
index e1fa710a43..c9b89ca6b4 100644 | |
--- a/testsuite/tests/simplCore/should_compile/T4398.stderr | |
+++ b/testsuite/tests/simplCore/should_compile/T4398.stderr | |
@@ -2,21 +2,5 @@ | |
T4398.hs:6:11: warning: | |
Forall'd constraint ‘Ord a’ is not bound in RULE lhs | |
Orig bndrs: [a, $dOrd, x, y] | |
- Orig lhs: let { | |
- $dEq :: Eq a | |
- [LclId] | |
- $dEq = GHC.Classes.$p1Ord @ a $dOrd } in | |
- f @ a | |
- ((\ ($dOrd :: Ord a) -> | |
- let { | |
- $dEq :: Eq a | |
- [LclId] | |
- $dEq = GHC.Classes.$p1Ord @ a $dOrd } in | |
- let { | |
- $dEq :: Eq a | |
- [LclId] | |
- $dEq = GHC.Classes.$p1Ord @ a $dOrd } in | |
- x) | |
- $dOrd) | |
- y | |
+ Orig lhs: f @ a ((\ ($dOrd :: Ord a) -> x) $dOrd) y | |
optimised lhs: f @ a x y | |
diff --git a/testsuite/tests/typecheck/should_compile/T13032.hs b/testsuite/tests/typecheck/should_compile/T13032.hs | |
new file mode 100644 | |
index 0000000000..065656e20c | |
--- /dev/null | |
+++ b/testsuite/tests/typecheck/should_compile/T13032.hs | |
@@ -0,0 +1,12 @@ | |
+{-# OPTIONS_GHC -ddump-ds -dsuppress-uniques #-} | |
+{-# LANGUAGE GADTs #-} | |
+ | |
+module T13032 where | |
+ | |
+f :: (a ~ b) => a -> b -> Bool | |
+f x y = True | |
+ | |
+-- The point of the test is to check that we don't | |
+-- get a redundant superclass selection to fetch an | |
+-- equality constraint out of the (a~b) dictionary | |
+-- Hence -ddump-ds | |
diff --git a/testsuite/tests/typecheck/should_compile/T13032.stderr b/testsuite/tests/typecheck/should_compile/T13032.stderr | |
new file mode 100644 | |
index 0000000000..f26e13e7b3 | |
--- /dev/null | |
+++ b/testsuite/tests/typecheck/should_compile/T13032.stderr | |
@@ -0,0 +1,19 @@ | |
+ | |
+==================== Desugar (after optimization) ==================== | |
+Result size of Desugar (after optimization) | |
+ = {terms: 13, types: 24, coercions: 0, joins: 0/0} | |
+ | |
+-- RHS size: {terms: 6, types: 11, coercions: 0, joins: 0/0} | |
+f :: forall a b. ((a :: *) ~ (b :: *)) => a -> b -> Bool | |
+[LclIdX] | |
+f = \ (@ a) (@ b) _ [Occ=Dead] _ [Occ=Dead] _ [Occ=Dead] -> | |
+ GHC.Types.True | |
+ | |
+-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} | |
+T13032.$trModule :: GHC.Types.Module | |
+[LclIdX] | |
+T13032.$trModule | |
+ = GHC.Types.Module | |
+ (GHC.Types.TrNameS "main"#) (GHC.Types.TrNameS "T13032"#) | |
+ | |
+ | |
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T | |
index 6d646c2e04..75d8f27b4d 100644 | |
--- a/testsuite/tests/typecheck/should_compile/all.T | |
+++ b/testsuite/tests/typecheck/should_compile/all.T | |
@@ -565,3 +565,4 @@ test('T14128', normal, multimod_compile, ['T14128Main', '-v0']) | |
test('T14154', normal, compile, ['']) | |
test('T14158', normal, compile, ['']) | |
test('T13943', normal, compile, ['-fsolve-constant-dicts']) | |
+test('T13032', normal, compile, ['']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
===--- building phase 0 | |
make --no-print-directory -f ghc.mk phase=0 phase_0_builds | |
make[1]: Nothing to be done for 'phase_0_builds'. | |
===--- building phase 1 | |
make --no-print-directory -f ghc.mk phase=1 phase_1_builds | |
make[1]: Nothing to be done for 'phase_1_builds'. | |
===--- building final phase | |
make --no-print-directory -f ghc.mk phase=final all | |
"inplace/bin/ghc-stage1" -hisuf hi -osuf o -hcsuf hc -static -O0 -H64m -Wall -this-unit-id ghc-prim-0.5.1.1 -hide-all-packages -i -ilibraries/ghc-prim/. -ilibraries/ghc-prim/dist-install/build -Ilibraries/ghc-prim/dist-install/build -ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/. -optP-include -optPlibraries/ghc-prim/dist-install/build/./autogen/cabal_macros.h -package-id rts -this-unit-id ghc-prim -XHaskell2010 -O -no-user-package-db -rtsopts -Wno-trustworthy-safe -Wno-deprecated-flags -Wnoncanonical-monad-instances -odir libraries/ghc-prim/dist-install/build -hidir libraries/ghc-prim/dist-install/build -stubdir libraries/ghc-prim/dist-install/build -dynamic-too -c libraries/ghc-prim/./GHC/Classes.hs -o libraries/ghc-prim/dist-install/build/GHC/Classes.o -dyno libraries/ghc-prim/dist-install/build/GHC/Classes.dyn_o | |
compilation IS NOT required | |
"rm" -f libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a.contents | |
"inplace/bin/ghc-stage1" -hisuf hi -osuf o -hcsuf hc -static -O0 -H64m -Wall -this-unit-id integer-gmp-1.0.1.0 -hide-all-packages -i -ilibraries/integer-gmp/src/ -ilibraries/integer-gmp/dist-install/build -Ilibraries/integer-gmp/dist-install/build -ilibraries/integer-gmp/dist-install/build/./autogen -Ilibraries/integer-gmp/dist-install/build/./autogen -Ilibraries/integer-gmp/include -optP-include -optPlibraries/integer-gmp/dist-install/build/./autogen/cabal_macros.h -package-id ghc-prim-0.5.1.1 -this-unit-id integer-gmp -Wall -XHaskell2010 -O -no-user-package-db -rtsopts -Wno-deprecated-flags -Wnoncanonical-monad-instances -odir libraries/integer-gmp/dist-install/build -hidir libraries/integer-gmp/dist-install/build -stubdir libraries/integer-gmp/dist-install/build -dynamic-too -c libraries/integer-gmp/src//GHC/Integer/Type.hs -o libraries/integer-gmp/dist-install/build/GHC/Integer/Type.o -dyno libraries/integer-gmp/dist-install/build/GHC/Integer/Type.dyn_o | |
echo libraries/ghc-prim/dist-install/build/GHC/CString.o libraries/ghc-prim/dist-install/build/GHC/Classes.o libraries/ghc-prim/dist-install/build/GHC/Debug.o libraries/ghc-prim/dist-install/build/GHC/IntWord64.o libraries/ghc-prim/dist-install/build/GHC/Magic.o libraries/ghc-prim/dist-install/build/GHC/PrimopWrappers.o libraries/ghc-prim/dist-install/build/GHC/Tuple.o libraries/ghc-prim/dist-install/build/GHC/Types.o libraries/ghc-prim/dist-install/build/cbits/atomic.o libraries/ghc-prim/dist-install/build/cbits/bswap.o libraries/ghc-prim/dist-install/build/cbits/clz.o libraries/ghc-prim/dist-install/build/cbits/ctz.o libraries/ghc-prim/dist-install/build/cbits/debug.o libraries/ghc-prim/dist-install/build/cbits/longlong.o libraries/ghc-prim/dist-install/build/cbits/popcnt.o libraries/ghc-prim/dist-install/build/cbits/word2float.o >> libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a.contents | |
"inplace/bin/ghc-stage1" -hisuf dyn_hi -osuf dyn_o -hcsuf dyn_hc -fPIC -dynamic -O0 -H64m -Wall -this-unit-id ghc-prim-0.5.1.1 -hide-all-packages -i -ilibraries/ghc-prim/. -ilibraries/ghc-prim/dist-install/build -Ilibraries/ghc-prim/dist-install/build -ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/. -optP-include -optPlibraries/ghc-prim/dist-install/build/./autogen/cabal_macros.h -package-id rts -this-unit-id ghc-prim -XHaskell2010 -O -no-user-package-db -rtsopts -Wno-trustworthy-safe -Wno-deprecated-flags -Wnoncanonical-monad-instances -odir libraries/ghc-prim/dist-install/build -hidir libraries/ghc-prim/dist-install/build -stubdir libraries/ghc-prim/dist-install/build -fPIC -dynamic -O0 -H64m -Wall -this-unit-id ghc-prim-0.5.1.1 -hide-all-packages -i -ilibraries/ghc-prim/. -ilibraries/ghc-prim/dist-install/build -Ilibraries/ghc-prim/dist-install/build -ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/dist-install/build/./autogen -Ilibraries/ghc-prim/. -optP-include -optPlibraries/ghc-prim/dist-install/build/./autogen/cabal_macros.h -package-id rts -this-unit-id ghc-prim -XHaskell2010 -O -no-user-package-db -rtsopts -Wno-trustworthy-safe -Wno-deprecated-flags -Wnoncanonical-monad-instances -fno-use-rpaths -optl-Wl,-rpath -optl-Wl,'$ORIGIN/../rts' -optl-Wl,-zorigin libraries/ghc-prim/dist-install/build/GHC/CString.dyn_o libraries/ghc-prim/dist-install/build/GHC/Classes.dyn_o libraries/ghc-prim/dist-install/build/GHC/Debug.dyn_o libraries/ghc-prim/dist-install/build/GHC/IntWord64.dyn_o libraries/ghc-prim/dist-install/build/GHC/Magic.dyn_o libraries/ghc-prim/dist-install/build/GHC/PrimopWrappers.dyn_o libraries/ghc-prim/dist-install/build/GHC/Tuple.dyn_o libraries/ghc-prim/dist-install/build/GHC/Types.dyn_o libraries/ghc-prim/dist-install/build/cbits/atomic.dyn_o libraries/ghc-prim/dist-install/build/cbits/bswap.dyn_o libraries/ghc-prim/dist-install/build/cbits/clz.dyn_o libraries/ghc-prim/dist-install/build/cbits/ctz.dyn_o libraries/ghc-prim/dist-install/build/cbits/debug.dyn_o libraries/ghc-prim/dist-install/build/cbits/longlong.dyn_o libraries/ghc-prim/dist-install/build/cbits/popcnt.dyn_o libraries/ghc-prim/dist-install/build/cbits/word2float.dyn_o -shared -dynamic -dynload deploy -no-auto-link-packages -o libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1-ghc8.2.2.so | |
"/usr/bin/ar" q libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a @libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a.contents | |
/usr/bin/ar: creating libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a | |
Warning: -rtsopts and -with-rtsopts have no effect with -shared. | |
Call hs_init_ghc() from your main() function to set these options. | |
"rm" -f libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.1.1.a.contents | |
/home/kb/workspace/ghc/libraries/ghc-prim/dist-install/build/GHC/Classes.hi | |
Declaration for $fEqOrdering_$c/= | |
Unfolding of $fEqOrdering_$c/=: | |
Iface id out of scope: $dEq | |
ghc-stage1: panic! (the 'impossible' happened) | |
(GHC version 8.2.2 for x86_64-unknown-linux): | |
StgCmmEnv: variable not found | |
$dOrd_a3a7 | |
local binds for: | |
negateInteger | |
eqInteger# | |
neqInteger# | |
absInteger | |
signumInteger | |
leInteger# | |
gtInteger# | |
ltInteger# | |
geInteger# | |
compareInteger | |
floatFromInteger | |
doubleFromInteger | |
encodeFloatInteger | |
encodeDoubleInteger | |
wordToInteger | |
bitInteger | |
sqrInteger1 | |
$WMBN# | |
intToSBigNat#1 | |
intToSBigNat#2 | |
intToSBigNat#3 | |
importIntegerFromAddr2 | |
importIntegerFromAddr1 | |
importBigNatFromAddr1 | |
xorBigNat_xor' | |
$wxorBigNat | |
$wtimesBigNatWord | |
$wtestBitNegBigNat | |
$wtimesBigNat | |
$wsqrBigNat | |
$wsignumInteger | |
$wshiftRNegBigNat | |
$wshiftRBigNat | |
$wshiftLBigNat | |
$wrecipModSBigNat | |
$wrecipModBigNat | |
$wpowModSBigNat | |
$wpowModBigNatWord | |
$wunsafeShrinkFreezeBigNat# | |
$wpowModBigNat | |
orBigNat_ior' | |
$worBigNat | |
$wneqBigNat# | |
$wminusBigNatWord | |
$wminusBigNat | |
gcdBigNat_gcd' | |
$wgcdBigNat | |
$weqBigNat# | |
$wcompareBigNat | |
$WS# | |
$wandnBigNat | |
$wunsafeRenormFreezeBigNat# | |
$wandBigNat | |
$trModule4 | |
$trModule2 | |
$trModule1 | |
$trModule3 | |
$tcSBigNat2 | |
$tcSBigNat1 | |
$tcSBigNat | |
$tcMutBigNat2 | |
$tcMutBigNat1 | |
$tcMutBigNat | |
$tcInteger2 | |
$tcInteger1 | |
$tcInteger | |
$tcBigNat2 | |
$tcBigNat1 | |
$tcBigNat | |
$tc'S#3 | |
$tc'S#1 | |
$tc'S#2 | |
$tc'S# | |
$tc'PosBN2 | |
$tc'PosBN1 | |
$tc'PosBN | |
$tc'NegBN3 | |
$tc'NegBN1 | |
$tc'NegBN2 | |
$tc'NegBN | |
$tc'MBN#3 | |
$tc'MBN#1 | |
$tc'MBN#2 | |
$tc'MBN# | |
$tc'Jp#2 | |
$tc'Jp#1 | |
$tc'Jp# | |
$tc'Jn#3 | |
$tc'Jn#1 | |
$tc'Jn#2 | |
$tc'Jn# | |
$tc'BN#3 | |
$tc'BN#1 | |
$tc'BN#2 | |
$trModule | |
$tc'BN# | |
$fEqInteger | |
zeroBigNat | |
xorBigNat | |
wordToNegInteger | |
wordToBigNat2 | |
wordToBigNat | |
unsafeShrinkFreezeBigNat# | |
unsafeRenormFreezeBigNat# | |
unsafePromote | |
timesInt2Integer | |
timesBigNatWord | |
timesBigNat | |
testBitWord# | |
testBitNegBigNat | |
testBitInteger | |
testBitBigNat | |
sqrInteger | |
sqrBigNat | |
signumInteger# | |
shiftRNegBigNat | |
shiftRBigNat | |
shiftLBigNat | |
sgnI# | |
remBigNatWord | |
recipModWord | |
recipModSBigNat | |
recipModBigNat | |
powModWord | |
powModSBigNatWord | |
powModSBigNat | |
powModBigNatWord | |
powModBigNat | |
popCountInteger | |
popCountBigNat | |
popCntI# | |
orBigNat | |
oneBigNat | |
nullBigNat | |
nextPrime# | |
neqInteger | |
neqBigNat# | |
minusBigNatWord | |
minusBigNat | |
minI# | |
ltInteger | |
leInteger | |
integer_gmp_powm1# | |
integer_gmp_powm# | |
integer_gmp_invert# | |
integer_gmp_gcdext# | |
integerToSBigNat | |
int_encodeDouble# | |
intToSBigNat# | |
importIntegerFromAddr | |
importBigNatFromByteArray# | |
importBigNatFromByteArray | |
importBigNatFromAddr# | |
importBigNatFromAddr | |
gtInteger | |
geInteger | |
gcdWord# | |
gcdWord | |
gcdInt | |
gcdBigNatWord | |
gcdBigNat | |
eqInteger | |
eqBigNat# | |
eqBigNat | |
czeroBigNat | |
compareBigNatWord | |
compareBigNat | |
cmpW# | |
cmpI# | |
c_scan_nzbyte_bytearray | |
c_scan_nzbyte_addr | |
c_rscan_nzbyte_bytearray | |
c_rscan_nzbyte_addr | |
c_mpn_xor_n | |
c_mpn_tdiv_r | |
c_mpn_tdiv_qr | |
c_mpn_tdiv_q | |
c_mpn_sub_1 | |
c_mpn_sub | |
c_mpn_rshift_2c | |
c_mpn_rshift | |
c_mpn_popcount | |
c_mpn_mul_1 | |
c_mpn_mul | |
c_mpn_mod_1 | |
c_mpn_lshift | |
c_mpn_ior_n | |
c_mpn_import_bytearray | |
c_mpn_import_addr | |
c_mpn_get_d | |
c_mpn_gcd_1# | |
c_mpn_gcd# | |
c_mpn_divrem_1 | |
c_mpn_cmp | |
c_mpn_andn_n | |
c_mpn_and_n | |
c_mpn_add_1 | |
c_mpn_add | |
byteArrayToBigNat# | |
bitWord# | |
bitBigNat | |
andnBigNat | |
andBigNat | |
absSBigNat | |
absI# | |
$WJp# | |
$WJn# | |
$WNegBN | |
$WPosBN | |
nextPrime#1_rcbS | |
c_mpn_import_bytearray1_rcbT | |
c_rscan_nzbyte_bytearray1_rcbU | |
c_scan_nzbyte_bytearray1_rcbV | |
c_mpn_import_addr1_rcbW | |
c_rscan_nzbyte_addr1_rcbX | |
c_scan_nzbyte_addr1_rcbY | |
c_mpn_xor_n1_rcbZ | |
c_mpn_ior_n1_rcc0 | |
c_mpn_andn_n1_rcc1 | |
c_mpn_and_n1_rcc2 | |
c_mpn_lshift1_rcc3 | |
c_mpn_rshift_2c1_rcc4 | |
c_mpn_rshift1_rcc5 | |
c_mpn_divrem_2_rcc6 | |
c_mpn_tdiv_r1_rcc7 | |
c_mpn_tdiv_q1_rcc8 | |
c_mpn_tdiv_qr1_rcc9 | |
c_mpn_mul1_rcca | |
c_mpn_sub1_rccb | |
c_mpn_add1_rccc | |
c_mpn_mul_2_rccd | |
c_mpn_sub_2_rcce | |
c_mpn_add_2_rccf | |
integer_gmp_gcdext#1_rccg | |
c_mpn_gcd#1_rcch | |
integer_gmp_invert#1_rcci | |
integer_gmp_powm#1_rccj | |
$krep_rcck | |
$krep1_rccl | |
$krep2_rccm | |
$krep3_rccn | |
$krep4_rcco | |
$krep5_rccp | |
$krep6_rccq | |
$krep7_rccr | |
$krep8_rccs | |
lvl_rcct | |
lvl1_rccu | |
lvl2_rccv | |
lvl3_rccw | |
lvl4_rccx | |
lvl5_rccy | |
lvl6_rccz | |
lvl7_rccA | |
lvl8_rccB | |
ww_scQU | |
ww1_scQV | |
wild_scQX | |
wild1_scQZ | |
wild3_scR2 | |
wild4_scR4 | |
sat_scR6 | |
sat_scR7 | |
sat_scRp | |
sat_scRt | |
Call stack: | |
CallStack (from HasCallStack): | |
prettyCurrentCallStack, called at compiler/utils/Outputable.hs:1133:58 in ghc:Outputable | |
callStackDoc, called at compiler/utils/Outputable.hs:1137:37 in ghc:Outputable | |
pprPanic, called at compiler/codeGen/StgCmmEnv.hs:147:9 in ghc:StgCmmEnv | |
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug | |
libraries/integer-gmp/ghc.mk:4: recipe for target 'libraries/integer-gmp/dist-install/build/GHC/Integer/Type.o' failed | |
make[1]: *** [libraries/integer-gmp/dist-install/build/GHC/Integer/Type.o] Error 1 | |
Makefile:122: recipe for target 'all' failed | |
make: *** [all] Error 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment