Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Attempt to repair the "text/str" RULE

Idea is to automatically skip the conversion to String where possible -
Pretty can work with the original C-Strings just as well. There is a
rule for that already, but it doesn't fire due to string fusion getting
in the way.

This is an attempt to restore the original behaviour. Unluckily, it comes
with worse performance in corner cases, see comments.
  • Loading branch information...
commit 9afbda2015252c60c14bb9a846bb9889a7dc2459 1 parent 8041d66
Peter Wortmann authored

Showing 2 changed files with 36 additions and 2 deletions. Show diff stats Hide diff stats

  1. +2 0  compiler/utils/Outputable.lhs
  2. +34 2 compiler/utils/Pretty.lhs
2  compiler/utils/Outputable.lhs
@@ -444,6 +444,8 @@ float n = docToSDoc $ Pretty.float n
444 444 double n = docToSDoc $ Pretty.double n
445 445 rational n = docToSDoc $ Pretty.rational n
446 446
  447 +{-# INLINE text #-}
  448 +
447 449 parens, braces, brackets, quotes, quote, doubleQuotes, angleBrackets :: SDoc -> SDoc
448 450
449 451 parens d = SDoc $ Pretty.parens . runSDoc d
36 compiler/utils/Pretty.lhs
@@ -191,8 +191,8 @@ import System.IO
191 191
192 192 #if defined(__GLASGOW_HASKELL__)
193 193 --for a RULES
194   -import GHC.Base ( unpackCString# )
195   -import GHC.Exts ( Int# )
  194 +import GHC.Base ( unpackCString#, unpackFoldrCString# )
  195 +import GHC.Exts ( Int#, build )
196 196 import GHC.Ptr ( Ptr(..) )
197 197 #endif
198 198
@@ -571,6 +571,38 @@ zeroWidthText s = textBeside_ (Str s) (_ILIT(0)) Empty
571 571 {-# RULES
572 572 "text/str" forall a. text (unpackCString# a) = ptext (Ptr a)
573 573 #-}
  574 +
  575 +-- RULES that *actually* do it. The problem here is that string fusion
  576 +-- will turn the string into something like
  577 +--
  578 +-- build (unpackFoldrCString# "...")
  579 +--
  580 +-- the first chance it gets (which is earlier than the above rule
  581 +-- matches, from the looks of it). This eventually gets turned back
  582 +-- into the original string, but again too late for the rule to
  583 +-- fire.
  584 +--
  585 +-- So the following rules try to transform the expression back from
  586 +-- its string-fusion form. Unluckily, this leaves the possibility that
  587 +-- we get a very inefficient representation using "appendChar" and
  588 +-- "empty" if the foldr representation of text *actually* gets fused
  589 +-- at some point.
  590 +--
  591 +-- For example:
  592 +-- text (map toUpper "...")
  593 +-- -> unpackFoldrCString# "..." (appendChar . toUpper) Pretty.Empty
  594 +
  595 +{-# RULES
  596 + "text" [~1] text = foldr appendChar empty;
  597 + "textInv" [1] foldr appendChar empty = text;
  598 + "pprStr" forall a. unpackFoldrCString# a appendChar Pretty.Empty = ptext (Ptr a);
  599 + #-}
  600 +{-# NOINLINE [1] text #-}
  601 +
  602 +appendChar :: Char -> Doc -> Doc
  603 +appendChar c d = char c <> d
  604 +{-# NOINLINE [1] appendChar #-}
  605 +
574 606 #endif
575 607
576 608 nest k p = mkNest (iUnbox k) (reduceDoc p) -- Externally callable version

0 comments on commit 9afbda2

Please sign in to comment.
Something went wrong with that request. Please try again.