summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2012-10-02 09:20:53 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2012-10-02 09:20:53 +0100
commit902a8632c627304bc553557c21263c591ae63428 (patch)
tree555b3203d7bc9ae7f14dd2955db15d69b4c51ef2 /compiler
parent522a1552d0546458bb1c0ff7052175606ac36d99 (diff)
downloadhaskell-902a8632c627304bc553557c21263c591ae63428.tar.gz
Improve (and simplify) the short-circuiting of Refl coercions
The constraint solver sometimes goes to a lot of effort that turns out to be Refl in the end, and avoiding zonking those proofs is a useful optimisation. (Trac #5030)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/typecheck/TcHsSyn.lhs45
1 files changed, 17 insertions, 28 deletions
diff --git a/compiler/typecheck/TcHsSyn.lhs b/compiler/typecheck/TcHsSyn.lhs
index 86cff0f474..ab784eca67 100644
--- a/compiler/typecheck/TcHsSyn.lhs
+++ b/compiler/typecheck/TcHsSyn.lhs
@@ -1156,29 +1156,17 @@ zonkEvBinds env binds
zonkEvBind :: ZonkEnv -> EvBind -> TcM EvBind
zonkEvBind env (EvBind var term)
- = case term of
- -- Special-case fast paths for small coercions
- -- NB: could be optimized further! (e.g. SymCo cv)
- -- See Note [Optimized Evidence Binding Zonking]
- EvCoercion co
- | Just ty <- isTcReflCo_maybe co
- -> do { zty <- zonkTcTypeToType env ty
- ; let var' = setVarType var (mkEqPred zty zty)
- -- Here we save the task of zonking var's type,
- -- because we know just what it is!
- ; return (EvBind var' (EvCoercion (mkTcReflCo zty))) }
-
- | Just cv <- getTcCoVar_maybe co
- -> do { let cv' = zonkIdOcc env cv -- Just lazily look up
- term' = EvCoercion (TcCoVarCo cv')
- var' = setVarType var (varType cv')
- ; return (EvBind var' term') }
-
- -- The default path
- _ -> do { var' <- {-# SCC "zonkEvBndr" #-} zonkEvBndr env var
- ; term' <- zonkEvTerm env term
- ; return (EvBind var' term')
- }
+ = do { var' <- {-# SCC "zonkEvBndr" #-} zonkEvBndr env var
+
+ -- Optimise the common case of Refl coercions
+ -- See Note [Optimise coercion zonking]
+ -- This has a very big effect on some programs (eg Trac #5030)
+ ; let ty' = idType var'
+ ; case getEqPredTys_maybe ty' of
+ Just (ty1, ty2) | ty1 `eqType` ty2
+ -> return (EvBind var' (EvCoercion (mkTcReflCo ty1)))
+ _other -> do { term' <- zonkEvTerm env term
+ ; return (EvBind var' term') } }
\end{code}
%************************************************************************
@@ -1233,8 +1221,8 @@ The type of Phantom is (forall (k : BOX). forall (a : k). Int). Both `a` and
we have a type or a kind variable; for kind variables we just return AnyK (and
not the ill-kinded Any BOX).
-Note [Optimized Evidence Binding Zonking]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Optimise coercion zonkind]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When optimising evidence binds we may come across situations where
a coercion looks like
cv = ReflCo ty
@@ -1242,10 +1230,11 @@ or cv1 = cv2
where the type 'ty' is big. In such cases it is a waste of time to zonk both
* The variable on the LHS
* The coercion on the RHS
-Rather, we can zonk the coercion, take its type and use that for
-the variable. For big coercions this might be a lose, though, so we
-just have a fast case for a couple of special cases.
+Rather, we can zonk the variable, and if its type is (ty ~ ty), we can just
+use Refl on the right, ignoring the actual coercion on the RHS.
+This can have a very big effect, because the constraint solver sometimes does go
+to a lot of effort to prove Refl! (Eg when solving 10+3 = 10+3; cf Trac #5030)
\begin{code}
zonkTyVarOcc :: ZonkEnv -> TyVar -> TcM TcType