Add literal-shift rewrite rules
[ghc-hetmet.git] / compiler / prelude / PrelRules.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[ConFold]{Constant Folder}
5
6 Conceptually, constant folding should be parameterized with the kind
7 of target machine to get identical behaviour during compilation time
8 and runtime. We cheat a little bit here...
9
10 ToDo:
11    check boundaries before folding, e.g. we can fold the Float addition
12    (i1 + i2) only if it results in a valid Float.
13
14 \begin{code}
15
16 {-# OPTIONS -optc-DNON_POSIX_SOURCE #-}
17
18 module PrelRules ( primOpRules, builtinRules ) where
19
20 #include "HsVersions.h"
21
22 import CoreSyn
23 import Id               ( mkWildId, idUnfolding )
24 import Literal          ( Literal(..), mkMachInt, mkMachWord
25                         , literalType
26                         , word2IntLit, int2WordLit
27                         , narrow8IntLit, narrow16IntLit, narrow32IntLit
28                         , narrow8WordLit, narrow16WordLit, narrow32WordLit
29                         , char2IntLit, int2CharLit
30                         , float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit
31                         , float2DoubleLit, double2FloatLit
32                         )
33 import PrimOp           ( PrimOp(..), tagToEnumKey )
34 import TysWiredIn       ( boolTy, trueDataConId, falseDataConId )
35 import TyCon            ( tyConDataCons_maybe, isEnumerationTyCon, isNewTyCon )
36 import DataCon          ( dataConTag, dataConTyCon, dataConWorkId, fIRST_TAG )
37 import CoreUtils        ( cheapEqExpr, exprIsConApp_maybe )
38 import Type             ( tyConAppTyCon, coreEqType )
39 import OccName          ( occNameFS )
40 import PrelNames        ( unpackCStringFoldrName, unpackCStringFoldrIdKey, hasKey,
41                           eqStringName, unpackCStringIdKey, inlineIdName )
42 import Maybes           ( orElse )
43 import Name             ( Name, nameOccName )
44 import Outputable
45 import FastString
46 import StaticFlags      ( opt_SimplExcessPrecision )
47
48 import Data.Bits as Bits        ( Bits(..) )
49 #if __GLASGOW_HASKELL__ >= 500
50 import Data.Word        ( Word )
51 #else
52 import Data.Word        ( Word64 )
53 #endif
54 \end{code}
55
56
57 Note [Constant folding]
58 ~~~~~~~~~~~~~~~~~~~~~~~
59 primOpRules generates the rewrite rules for each primop
60 These rules do what is often called "constant folding"
61 E.g. the rules for +# might say
62              4 +# 5 = 9
63 Well, of course you'd need a lot of rules if you did it 
64 like that, so we use a BuiltinRule instead, so that we
65 can match in any two literal values.  So the rule is really
66 more like
67              (Lit 4) +# (Lit y) = Lit (x+#y)
68 where the (+#) on the rhs is done at compile time
69
70 That is why these rules are built in here.  Other rules
71 which don't need to be built in are in GHC.Base. For 
72 example:
73         x +# 0 = x
74
75
76 \begin{code}
77 primOpRules :: PrimOp -> Name -> [CoreRule]
78 primOpRules op op_name = primop_rule op
79   where
80         -- A useful shorthand
81     one_lit   = oneLit  op_name
82     two_lits  = twoLits op_name
83     relop cmp = two_lits (cmpOp (\ord -> ord `cmp` EQ))
84         -- Cunning.  cmpOp compares the values to give an Ordering.
85         -- It applies its argument to that ordering value to turn
86         -- the ordering into a boolean value.  (`cmp` EQ) is just the job.
87
88     -- ToDo:    something for integer-shift ops?
89     --          NotOp
90
91     primop_rule TagToEnumOp = mkBasicRule op_name 2 tagToEnumRule
92     primop_rule DataToTagOp = mkBasicRule op_name 2 dataToTagRule
93
94         -- Int operations
95     primop_rule IntAddOp    = two_lits (intOp2     (+))
96     primop_rule IntSubOp    = two_lits (intOp2     (-))
97     primop_rule IntMulOp    = two_lits (intOp2     (*))
98     primop_rule IntQuotOp   = two_lits (intOp2Z    quot)
99     primop_rule IntRemOp    = two_lits (intOp2Z    rem)
100     primop_rule IntNegOp    = one_lit  negOp
101     primop_rule ISllOp      = two_lits (intShiftOp2 Bits.shiftL)
102     primop_rule ISraOp      = two_lits (intShiftOp2 Bits.shiftR)
103     primop_rule ISrlOp      = two_lits (intShiftOp2 shiftRightLogical)
104
105         -- Word operations
106 #if __GLASGOW_HASKELL__ >= 500
107     primop_rule WordAddOp   = two_lits (wordOp2    (+))
108     primop_rule WordSubOp   = two_lits (wordOp2    (-))
109     primop_rule WordMulOp   = two_lits (wordOp2    (*))
110 #endif
111     primop_rule WordQuotOp  = two_lits (wordOp2Z   quot)
112     primop_rule WordRemOp   = two_lits (wordOp2Z   rem)
113 #if __GLASGOW_HASKELL__ >= 407
114     primop_rule AndOp       = two_lits (wordBitOp2 (.&.))
115     primop_rule OrOp        = two_lits (wordBitOp2 (.|.))
116     primop_rule XorOp       = two_lits (wordBitOp2 xor)
117 #endif
118     primop_rule SllOp       = two_lits (wordShiftOp2 Bits.shiftL)
119     primop_rule SrlOp       = two_lits (wordShiftOp2 shiftRightLogical)
120
121         -- coercions
122     primop_rule Word2IntOp      = one_lit (litCoerce word2IntLit)
123     primop_rule Int2WordOp      = one_lit (litCoerce int2WordLit)
124     primop_rule Narrow8IntOp    = one_lit (litCoerce narrow8IntLit)
125     primop_rule Narrow16IntOp   = one_lit (litCoerce narrow16IntLit)
126     primop_rule Narrow32IntOp   = one_lit (litCoerce narrow32IntLit)
127     primop_rule Narrow8WordOp   = one_lit (litCoerce narrow8WordLit)
128     primop_rule Narrow16WordOp  = one_lit (litCoerce narrow16WordLit)
129     primop_rule Narrow32WordOp  = one_lit (litCoerce narrow32WordLit)
130     primop_rule OrdOp           = one_lit (litCoerce char2IntLit)
131     primop_rule ChrOp           = one_lit (litCoerce int2CharLit)
132     primop_rule Float2IntOp     = one_lit (litCoerce float2IntLit)
133     primop_rule Int2FloatOp     = one_lit (litCoerce int2FloatLit)
134     primop_rule Double2IntOp    = one_lit (litCoerce double2IntLit)
135     primop_rule Int2DoubleOp    = one_lit (litCoerce int2DoubleLit)
136         -- SUP: Not sure what the standard says about precision in the following 2 cases
137     primop_rule Float2DoubleOp  = one_lit (litCoerce float2DoubleLit)
138     primop_rule Double2FloatOp  = one_lit (litCoerce double2FloatLit)
139
140         -- Float
141     primop_rule FloatAddOp   = two_lits (floatOp2  (+))
142     primop_rule FloatSubOp   = two_lits (floatOp2  (-))
143     primop_rule FloatMulOp   = two_lits (floatOp2  (*))
144     primop_rule FloatDivOp   = two_lits (floatOp2Z (/))
145     primop_rule FloatNegOp   = one_lit  negOp
146
147         -- Double
148     primop_rule DoubleAddOp   = two_lits (doubleOp2  (+))
149     primop_rule DoubleSubOp   = two_lits (doubleOp2  (-))
150     primop_rule DoubleMulOp   = two_lits (doubleOp2  (*))
151     primop_rule DoubleDivOp   = two_lits (doubleOp2Z (/))
152     primop_rule DoubleNegOp   = one_lit  negOp
153
154         -- Relational operators
155     primop_rule IntEqOp  = relop (==) ++ litEq op_name True
156     primop_rule IntNeOp  = relop (/=) ++ litEq op_name False
157     primop_rule CharEqOp = relop (==) ++ litEq op_name True
158     primop_rule CharNeOp = relop (/=) ++ litEq op_name False
159
160     primop_rule IntGtOp         = relop (>)
161     primop_rule IntGeOp         = relop (>=)
162     primop_rule IntLeOp         = relop (<=)
163     primop_rule IntLtOp         = relop (<)
164
165     primop_rule CharGtOp        = relop (>)
166     primop_rule CharGeOp        = relop (>=)
167     primop_rule CharLeOp        = relop (<=)
168     primop_rule CharLtOp        = relop (<)
169
170     primop_rule FloatGtOp       = relop (>)
171     primop_rule FloatGeOp       = relop (>=)
172     primop_rule FloatLeOp       = relop (<=)
173     primop_rule FloatLtOp       = relop (<)
174     primop_rule FloatEqOp       = relop (==)
175     primop_rule FloatNeOp       = relop (/=)
176
177     primop_rule DoubleGtOp      = relop (>)
178     primop_rule DoubleGeOp      = relop (>=)
179     primop_rule DoubleLeOp      = relop (<=)
180     primop_rule DoubleLtOp      = relop (<)
181     primop_rule DoubleEqOp      = relop (==)
182     primop_rule DoubleNeOp      = relop (/=)
183
184     primop_rule WordGtOp        = relop (>)
185     primop_rule WordGeOp        = relop (>=)
186     primop_rule WordLeOp        = relop (<=)
187     primop_rule WordLtOp        = relop (<)
188     primop_rule WordEqOp        = relop (==)
189     primop_rule WordNeOp        = relop (/=)
190
191     primop_rule other           = []
192
193
194 \end{code}
195
196 %************************************************************************
197 %*                                                                      *
198 \subsection{Doing the business}
199 %*                                                                      *
200 %************************************************************************
201
202 ToDo: the reason these all return Nothing is because there used to be
203 the possibility of an argument being a litlit.  Litlits are now gone,
204 so this could be cleaned up.
205
206 \begin{code}
207 --------------------------
208 litCoerce :: (Literal -> Literal) -> Literal -> Maybe CoreExpr
209 litCoerce fn lit = Just (Lit (fn lit))
210
211 --------------------------
212 cmpOp :: (Ordering -> Bool) -> Literal -> Literal -> Maybe CoreExpr
213 cmpOp cmp l1 l2
214   = go l1 l2
215   where
216     done res | cmp res   = Just trueVal
217              | otherwise = Just falseVal
218
219         -- These compares are at different types
220     go (MachChar i1)   (MachChar i2)   = done (i1 `compare` i2)
221     go (MachInt i1)    (MachInt i2)    = done (i1 `compare` i2)
222     go (MachInt64 i1)  (MachInt64 i2)  = done (i1 `compare` i2)
223     go (MachWord i1)   (MachWord i2)   = done (i1 `compare` i2)
224     go (MachWord64 i1) (MachWord64 i2) = done (i1 `compare` i2)
225     go (MachFloat i1)  (MachFloat i2)  = done (i1 `compare` i2)
226     go (MachDouble i1) (MachDouble i2) = done (i1 `compare` i2)
227     go l1              l2              = Nothing
228
229 --------------------------
230
231 negOp :: Literal -> Maybe CoreExpr      -- Negate
232 negOp (MachFloat 0.0)  = Nothing  -- can't represent -0.0 as a Rational
233 negOp (MachFloat f)    = Just (mkFloatVal (-f))
234 negOp (MachDouble 0.0) = Nothing
235 negOp (MachDouble d)   = Just (mkDoubleVal (-d))
236 negOp (MachInt i)      = intResult (-i)
237 negOp l                = Nothing
238
239 --------------------------
240 intOp2 :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
241 intOp2 op (MachInt i1) (MachInt i2) = intResult (i1 `op` i2)
242 intOp2 op l1           l2           = Nothing           -- Could find LitLit
243
244 intOp2Z :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
245 -- Like intOp2, but Nothing if i2=0
246 intOp2Z op (MachInt i1) (MachInt i2)
247   | i2 /= 0 = intResult (i1 `op` i2)
248 intOp2Z op l1 l2 = Nothing              -- LitLit or zero dividend
249
250 intShiftOp2 :: (Integer->Int->Integer) -> Literal -> Literal -> Maybe CoreExpr
251         -- Shifts take an Int; hence second arg of op is Int
252 intShiftOp2 op (MachInt i1) (MachInt i2) = intResult (i1 `op` fromInteger i2)
253 intShiftOp2 op l1           l2           = Nothing 
254
255 shiftRightLogical :: Integer -> Int -> Integer
256 -- Shift right, putting zeros in rather than sign-propagating as Bits.shiftR would do
257 -- Do this by converting to Word and back.  Obviously this won't work for big 
258 -- values, but its ok as we use it here
259 shiftRightLogical x n = fromIntegral (fromInteger x `shiftR` n :: Word)
260
261
262 --------------------------
263 #if __GLASGOW_HASKELL__ >= 500
264 wordOp2 :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
265 wordOp2 op (MachWord w1) (MachWord w2)
266   = wordResult (w1 `op` w2)
267 wordOp2 op l1 l2 = Nothing              -- Could find LitLit
268 #endif
269
270 wordOp2Z :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
271 wordOp2Z op (MachWord w1) (MachWord w2)
272   | w2 /= 0 = wordResult (w1 `op` w2)
273 wordOp2Z op l1 l2 = Nothing     -- LitLit or zero dividend
274
275 #if __GLASGOW_HASKELL__ >= 500
276 wordBitOp2 op l1@(MachWord w1) l2@(MachWord w2)
277   = wordResult (w1 `op` w2)
278 #else
279 -- Integer is not an instance of Bits, so we operate on Word64
280 wordBitOp2 op l1@(MachWord w1) l2@(MachWord w2)
281   = wordResult ((fromIntegral::Word64->Integer) (fromIntegral w1 `op` fromIntegral w2))
282 #endif
283 wordBitOp2 op l1 l2 = Nothing           -- Could find LitLit
284
285 wordShiftOp2 :: (Integer->Int->Integer) -> Literal -> Literal -> Maybe CoreExpr
286         -- Shifts take an Int; hence second arg of op is Int
287 wordShiftOp2 op (MachWord x) (MachInt n) 
288   = wordResult (x `op` fromInteger n)
289         -- Do the shift at type Integer
290 wordShiftOp2 op l1 l2 = Nothing 
291
292 --------------------------
293 floatOp2  op (MachFloat f1) (MachFloat f2)
294   = Just (mkFloatVal (f1 `op` f2))
295 floatOp2  op l1 l2 = Nothing
296
297 floatOp2Z op (MachFloat f1) (MachFloat f2)
298   | f2 /= 0   = Just (mkFloatVal (f1 `op` f2))
299 floatOp2Z op l1 l2 = Nothing
300
301 --------------------------
302 doubleOp2  op (MachDouble f1) (MachDouble f2)
303   = Just (mkDoubleVal (f1 `op` f2))
304 doubleOp2 op l1 l2 = Nothing
305
306 doubleOp2Z op (MachDouble f1) (MachDouble f2)
307   | f2 /= 0   = Just (mkDoubleVal (f1 `op` f2))
308 doubleOp2Z op l1 l2 = Nothing
309
310
311 --------------------------
312         -- This stuff turns
313         --      n ==# 3#
314         -- into
315         --      case n of
316         --        3# -> True
317         --        m  -> False
318         --
319         -- This is a Good Thing, because it allows case-of case things
320         -- to happen, and case-default absorption to happen.  For
321         -- example:
322         --
323         --      if (n ==# 3#) || (n ==# 4#) then e1 else e2
324         -- will transform to
325         --      case n of
326         --        3# -> e1
327         --        4# -> e1
328         --        m  -> e2
329         -- (modulo the usual precautions to avoid duplicating e1)
330
331 litEq :: Name 
332       -> Bool           -- True <=> equality, False <=> inequality
333       -> [CoreRule]
334 litEq op_name is_eq
335   = [BuiltinRule { ru_name = occNameFS (nameOccName op_name) 
336                                 `appendFS` FSLIT("->case"),
337                    ru_fn = op_name, 
338                    ru_nargs = 2, ru_try = rule_fn }]
339   where
340     rule_fn [Lit lit, expr] = do_lit_eq lit expr
341     rule_fn [expr, Lit lit] = do_lit_eq lit expr
342     rule_fn other           = Nothing
343     
344     do_lit_eq lit expr
345       = Just (Case expr (mkWildId (literalType lit)) boolTy
346                     [(DEFAULT,    [], val_if_neq),
347                      (LitAlt lit, [], val_if_eq)])
348     val_if_eq  | is_eq     = trueVal
349                | otherwise = falseVal
350     val_if_neq | is_eq     = falseVal
351                | otherwise = trueVal
352
353 -- Note that we *don't* warn the user about overflow. It's not done at
354 -- runtime either, and compilation of completely harmless things like
355 --    ((124076834 :: Word32) + (2147483647 :: Word32))
356 -- would yield a warning. Instead we simply squash the value into the
357 -- Int range, but not in a way suitable for cross-compiling... :-(
358 intResult :: Integer -> Maybe CoreExpr
359 intResult result
360   = Just (mkIntVal (toInteger (fromInteger result :: Int)))
361
362 #if __GLASGOW_HASKELL__ >= 500
363 wordResult :: Integer -> Maybe CoreExpr
364 wordResult result
365   = Just (mkWordVal (toInteger (fromInteger result :: Word)))
366 #endif
367 \end{code}
368
369
370 %************************************************************************
371 %*                                                                      *
372 \subsection{Vaguely generic functions
373 %*                                                                      *
374 %************************************************************************
375
376 \begin{code}
377 mkBasicRule :: Name -> Int -> ([CoreExpr] -> Maybe CoreExpr) -> [CoreRule]
378 -- Gives the Rule the same name as the primop itself
379 mkBasicRule op_name n_args rule_fn
380   = [BuiltinRule { ru_name = occNameFS (nameOccName op_name),
381                    ru_fn = op_name, 
382                    ru_nargs = n_args, ru_try = rule_fn }]
383
384 oneLit :: Name -> (Literal -> Maybe CoreExpr)
385        -> [CoreRule]
386 oneLit op_name test
387   = mkBasicRule op_name 1 rule_fn
388   where
389     rule_fn [Lit l1] = test (convFloating l1)
390     rule_fn _        = Nothing
391
392 twoLits :: Name -> (Literal -> Literal -> Maybe CoreExpr)
393         -> [CoreRule]
394 twoLits op_name test 
395   = mkBasicRule op_name 2 rule_fn
396   where
397     rule_fn [Lit l1, Lit l2] = test (convFloating l1) (convFloating l2)
398     rule_fn _                = Nothing
399
400 -- When excess precision is not requested, cut down the precision of the
401 -- Rational value to that of Float/Double. We confuse host architecture
402 -- and target architecture here, but it's convenient (and wrong :-).
403 convFloating :: Literal -> Literal
404 convFloating (MachFloat  f) | not opt_SimplExcessPrecision =
405    MachFloat  (toRational ((fromRational f) :: Float ))
406 convFloating (MachDouble d) | not opt_SimplExcessPrecision =
407    MachDouble (toRational ((fromRational d) :: Double))
408 convFloating l = l
409
410 trueVal       = Var trueDataConId
411 falseVal      = Var falseDataConId
412 mkIntVal    i = Lit (mkMachInt  i)
413 mkWordVal   w = Lit (mkMachWord w)
414 mkFloatVal  f = Lit (convFloating (MachFloat  f))
415 mkDoubleVal d = Lit (convFloating (MachDouble d))
416 \end{code}
417
418                                                 
419 %************************************************************************
420 %*                                                                      *
421 \subsection{Special rules for seq, tagToEnum, dataToTag}
422 %*                                                                      *
423 %************************************************************************
424
425 \begin{code}
426 tagToEnumRule [Type ty, Lit (MachInt i)]
427   = ASSERT( isEnumerationTyCon tycon ) 
428     case filter correct_tag (tyConDataCons_maybe tycon `orElse` []) of
429
430
431         []        -> Nothing    -- Abstract type
432         (dc:rest) -> ASSERT( null rest )
433                      Just (Var (dataConWorkId dc))
434   where 
435     correct_tag dc = (dataConTag dc - fIRST_TAG) == tag
436     tag   = fromInteger i
437     tycon = tyConAppTyCon ty
438
439 tagToEnumRule other = Nothing
440 \end{code}
441
442 For dataToTag#, we can reduce if either 
443         
444         (a) the argument is a constructor
445         (b) the argument is a variable whose unfolding is a known constructor
446
447 \begin{code}
448 dataToTagRule [Type ty1, Var tag_to_enum `App` Type ty2 `App` tag]
449   | tag_to_enum `hasKey` tagToEnumKey
450   , ty1 `coreEqType` ty2
451   = Just tag    -- dataToTag (tagToEnum x)   ==>   x
452
453 dataToTagRule [_, val_arg]
454   | Just (dc,_) <- exprIsConApp_maybe val_arg
455   = ASSERT( not (isNewTyCon (dataConTyCon dc)) )
456     Just (mkIntVal (toInteger (dataConTag dc - fIRST_TAG)))
457
458 dataToTagRule other = Nothing
459 \end{code}
460
461 %************************************************************************
462 %*                                                                      *
463 \subsection{Built in rules}
464 %*                                                                      *
465 %************************************************************************
466
467 \begin{code}
468 builtinRules :: [CoreRule]
469 -- Rules for non-primops that can't be expressed using a RULE pragma
470 builtinRules
471   = [ BuiltinRule FSLIT("AppendLitString") unpackCStringFoldrName 4 match_append_lit,
472       BuiltinRule FSLIT("EqString") eqStringName 2 match_eq_string,
473       BuiltinRule FSLIT("Inline") inlineIdName 1 match_inline
474     ]
475
476
477 ---------------------------------------------------
478 -- The rule is this:
479 --      unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n)  =  unpackFoldrCString# "foobaz" c n
480
481 match_append_lit [Type ty1,
482                    Lit (MachStr s1),
483                    c1,
484                    Var unpk `App` Type ty2 
485                             `App` Lit (MachStr s2)
486                             `App` c2
487                             `App` n
488                   ]
489   | unpk `hasKey` unpackCStringFoldrIdKey && 
490     c1 `cheapEqExpr` c2
491   = ASSERT( ty1 `coreEqType` ty2 )
492     Just (Var unpk `App` Type ty1
493                    `App` Lit (MachStr (s1 `appendFS` s2))
494                    `App` c1
495                    `App` n)
496
497 match_append_lit other = Nothing
498
499 ---------------------------------------------------
500 -- The rule is this:
501 --      eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2) = s1==s2
502
503 match_eq_string [Var unpk1 `App` Lit (MachStr s1),
504                  Var unpk2 `App` Lit (MachStr s2)]
505   | unpk1 `hasKey` unpackCStringIdKey,
506     unpk2 `hasKey` unpackCStringIdKey
507   = Just (if s1 == s2 then trueVal else falseVal)
508
509 match_eq_string other = Nothing
510
511
512 ---------------------------------------------------
513 -- The rule is this:
514 --      inline (f a b c) = <f's unfolding> a b c
515 -- (if f has an unfolding)
516 match_inline (e:_)
517   | (Var f, args1) <- collectArgs e,
518     Just unf <- maybeUnfoldingTemplate (idUnfolding f)
519   = Just (mkApps unf args1)
520
521 match_inline other = Nothing
522 \end{code}