Allow RULES for seq, and exploit them
authorsimonpj@microsoft.com <unknown>
Wed, 3 Jun 2009 09:29:56 +0000 (09:29 +0000)
committersimonpj@microsoft.com <unknown>
Wed, 3 Jun 2009 09:29:56 +0000 (09:29 +0000)
commit90ce88a0a9b5611416e592a6ff96781ba884975f
tree81c562a8877efac687034c19e1ac2697b1b609a4
parent1bca92d715d8b358ee83ff5ee0bc085bec063e59
Allow RULES for seq, and exploit them

Roman found situations where he had
      case (f n) of _ -> e
where he knew that f (which was strict in n) would terminate if n did.
Notice that the result of (f n) is discarded. So it makes sense to
transform to
      case n of _ -> e

Rather than attempt some general analysis to support this, I've added
enough support that you can do this using a rewrite rule:

  RULE "f/seq" forall n.  seq (f n) e = seq n e

You write that rule.  When GHC sees a case expression that discards
its result, it mentally transforms it to a call to 'seq' and looks for
a RULE.  (This is done in Simplify.rebuildCase.)  As usual, the
correctness of the rule is up to you.

This patch implements the extra stuff.  I have not documented it explicitly
in the user manual yet... let's see how useful it is first.

The patch looks bigger than it is, because
  a) Comments; see esp MkId Note [seqId magic]

  b) Some refactoring.  Notably, I moved the special desugaring for
     seq from MkCore back into DsUtils where it properly belongs.
     (It's really a desugaring thing, not a CoreSyn invariant.)

  c) Annoyingly, in a RULE left-hand side we need to be careful that
     the magical desugaring done in MkId Note [seqId magic] item (c)
     is *not* done on the LHS of a rule. Or rather, we arrange to
     un-do it, in DsBinds.decomposeRuleLhs.
compiler/basicTypes/MkId.lhs
compiler/coreSyn/MkCore.lhs
compiler/deSugar/DsBinds.lhs
compiler/deSugar/DsExpr.lhs
compiler/deSugar/DsUtils.lhs
compiler/simplCore/Simplify.lhs
compiler/typecheck/Inst.lhs
compiler/vectorise/VectUtils.hs