[GHC] #11195: New pattern-match check can be non-performant

GHC ghc-devs at haskell.org
Fri Dec 11 11:06:38 UTC 2015


#11195: New pattern-match check can be non-performant
-------------------------------------+-------------------------------------
        Reporter:  goldfire          |                Owner:  goldfire
            Type:  bug               |               Status:  new
        Priority:  highest           |            Milestone:  8.0.1
       Component:  Compiler          |              Version:  7.11
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash                              |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by gkaracha):

 Replying to [comment:1 bgamari]:
 > Looking at the code I'd suspect the problem is either `opt_trans_rule`
 or `opt_co4` as these both have a substantial number of patterns each with
 many guards. I'll try distilling a testcase from one of these.

 Yes, I think so too. For example, concerning this part:

 {{{#!hs
 -- Push transitivity inside forall
 opt_trans_rule is co1 co2
   | ForAllCo tv1 eta1 r1 <- co1
   , Just (tv2,eta2,r2) <- etaForAllCo_maybe co2 = undefined

   | ForAllCo tv2 eta2 r2 <- co2
   , Just (tv1,eta1,r1) <- etaForAllCo_maybe co1 = undefined
 }}}
 Considering only the guards `ForAllCo tv1 eta1 r1 <- co1` and `ForAllCo
 tv2 eta2 r2 <- co2`
 will generate as missing cases the following:
 {{{
 TcRefl         _ _ ~ co1
 TcTyConAppCo _ _ _ ~ co1
 TcAppCo        _ _ ~ co1
 TcCoVarCo        _ ~ co1
          ...
 TcCoercion       _ ~ co1

 ForAllCo tv1 eta1 r1 ~ co1, TcRefl         _ _ ~ co2
 ForAllCo tv1 eta1 r1 ~ co1, TcTyConAppCo _ _ _ ~ co2
 ForAllCo tv1 eta1 r1 ~ co1, TcAppCo        _ _ ~ co2
 ForAllCo tv1 eta1 r1 ~ co1, TcCoVarCo        _ ~ co2
                          ...
 ForAllCo tv1 eta1 r1 ~ co1, TcCoercion       _ ~ co2
 }}}
 This will be passed to the next clause and each one will be checked
 individually so the numbers
 will be multiplied and the sets will **really** grow exponentially. Guards
 are expensive by
 definition so I cannot think of a nice way out of this. Some options I can
 think of though are:
   1. Restructure the code to use less guards (or use them differently)
   2. See if I can make the check to eagerly solve some constraints to
 decrease the size of the
      sets it generates (I am not sure if it will be enough though, since,
 the above sets are all
      consistent for example so pruning eagerly wouldn't decrease the size
 of the above uncovered
      set)
   3. Oversimplify the check to drop all the guards

 I hate to admit it but after all these performance failures (#11160,
 #11161, ... and now this), I
 am really tempted to drop the guards. The new checker will still be
 accurate when it comes to GADTs
 but will have almost the same performance as the old checker, by not
 reasoning about guards at all,
 like it used to do. I am not sure about the price we are willing to pay
 for the additional
 reasoning (I feel that we are paying a lot) so I would like some input on
 this. What do you think?

 In any case I will investigate it more and see if this really has anything
 to do with the type=kind
 change or if it is inherent to the check. I assume the latter but if I am
 mistaken I am sure we can
 sort it out with Richard.

 George

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11195#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list