The attached (reverse :-() diff is a bunch of ugly hacks which fix
some severe performance problems in the copy of the Pretty library
distributed with Hugs-Sept99.

The problems show up when making heavy use of hsep (eg printing large
numbers of comma separated lists which tend to run over the end of
line).  The problems manifest themselves as the infamous "control
stack overflow" and seem to be due to the generation of large
Int thunks that look something like this:

  80 - 4 - 1 - 1 - 3 - 1 - ... -1

(There may be a few +'s in there too but -'s predominate.)

I found the problems using the --enable-stack-dumps configure flag,
made a few guesses about what was going wrong and then went berserk
with hacks that would force evaluation of the Ints in any nearby code.
(In other words, you might be able to get away with less hacks and you
can certainly do it in a cleaner way.  You might also want to add more
strictness hacks - the attached patch was enough to let me get back to
work but I suspect there's more gains to be had.)

The problems probably don't show up in Simon PJ's copy of the Pretty
library when compiled using GHC because that version uses Int#'s where
the Hugs copy uses Ints.  In other words, it already has (something
equivalent to) the strictness hacks I added.

--
Alastair Reid



diff -c2 Pretty.lhs /home/css/staff/reid/hugs-Sept99/share/hugs/lib/exts/Pretty.lhs
*** Pretty.lhs  Tue Nov  9 12:50:44 1999
--- /home/css/staff/reid/hugs-Sept99/share/hugs/lib/exts/Pretty.lhs     Tue Nov  9 
13:08:31 1999
***************
*** 547,551 ****
  -- Specfication: aboveNest p g k q = p $g$ (nest k q)
  
- --aboveNest _                   g k q | k == 0 && False = undefined
  aboveNest NoDoc               g k q = NoDoc
  aboveNest (p1 `Union` p2)     g k q = aboveNest p1 g k q `union_` 
--- 550,553 ----
***************
*** 570,574 ****
  --              = text s <> (text "" $g$ nest k q)
  
- --nilAboveNest g k _           | k == 0 && False = undefined
  nilAboveNest g k Empty       = Empty    -- Here's why the "text s <>" is in the spec!
  nilAboveNest g k (Nest k1 q) = nilAboveNest g (k + k1) q
--- 572,575 ----
***************
*** 646,650 ****
  
  sep1 :: Bool -> RDoc -> Int -> [Doc] -> RDoc
- sep1 g _                   k ys | k == 0 && False = undefined
  sep1 g NoDoc               k ys = NoDoc
  sep1 g (p `Union` q)       k ys = sep1 g p k ys
--- 647,650 ----
***************
*** 697,701 ****
  
  fill1 :: Bool -> RDoc -> Int -> [Doc] -> Doc
- fill1 g _                   k ys | k == 0 && False = undefined
  fill1 g NoDoc               k ys = NoDoc
  fill1 g (p `Union` q)       k ys = fill1 g p k ys
--- 697,700 ----
***************
*** 709,713 ****
  fill1 g (TextBeside s sl p) k ys = textBeside_ s sl (fillNB g p (k - sl) ys)
  
- fillNB g _           k ys | k == 0 && False = undefined
  fillNB g (Nest _ p)  k ys  = fillNB g p k ys
  fillNB g Empty k []        = Empty
--- 708,711 ----
***************
*** 751,755 ****
      get :: Int          -- (Remaining) width of line
          -> Doc -> Doc
-     get w _ | w==0 && False = undefined
      get w Empty               = Empty
      get w NoDoc               = NoDoc
--- 749,752 ----
***************
*** 764,768 ****
           -> Doc         -- No unions in here!
  
-     get1 w _ _ | w==0 && False = undefined
      get1 w sl Empty               = Empty
      get1 w sl NoDoc               = NoDoc
--- 761,764 ----
***************
*** 785,789 ****
  fits n Empty               = True
  fits n (NilAbove _)        = True
! fits n (TextBeside _ sl p) = (fits $! (n - sl)) p
  
  minn x y | x < y    = x
--- 781,785 ----
  fits n Empty               = True
  fits n (NilAbove _)        = True
! fits n (TextBeside _ sl p) = fits (n - sl) p
  
  minn x y | x < y    = x
***************

Reply via email to