2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[ConFold]{Constant Folder}
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...
11 check boundaries before folding, e.g. we can fold the Float addition
12 (i1 + i2) only if it results in a valid Float.
16 {-# OPTIONS -optc-DNON_POSIX_SOURCE #-}
18 module PrelRules ( primOpRules, builtinRules ) where
20 #include "HsVersions.h"
23 import Id ( mkWildId, idUnfolding )
24 import Literal ( Literal(..), mkMachInt, mkMachWord
26 , word2IntLit, int2WordLit
27 , narrow8IntLit, narrow16IntLit, narrow32IntLit
28 , narrow8WordLit, narrow16WordLit, narrow32WordLit
29 , char2IntLit, int2CharLit
30 , float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit
31 , float2DoubleLit, double2FloatLit, litFitsInChar
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 )
46 import StaticFlags ( opt_SimplExcessPrecision )
47 import Data.Bits as Bits
48 import Data.Word ( Word )
52 Note [Constant folding]
53 ~~~~~~~~~~~~~~~~~~~~~~~
54 primOpRules generates the rewrite rules for each primop
55 These rules do what is often called "constant folding"
56 E.g. the rules for +# might say
58 Well, of course you'd need a lot of rules if you did it
59 like that, so we use a BuiltinRule instead, so that we
60 can match in any two literal values. So the rule is really
62 (Lit 4) +# (Lit y) = Lit (x+#y)
63 where the (+#) on the rhs is done at compile time
65 That is why these rules are built in here. Other rules
66 which don't need to be built in are in GHC.Base. For
72 primOpRules :: PrimOp -> Name -> [CoreRule]
73 primOpRules op op_name = primop_rule op
76 one_lit = oneLit op_name
77 two_lits = twoLits op_name
78 relop cmp = two_lits (cmpOp (\ord -> ord `cmp` EQ))
79 -- Cunning. cmpOp compares the values to give an Ordering.
80 -- It applies its argument to that ordering value to turn
81 -- the ordering into a boolean value. (`cmp` EQ) is just the job.
83 -- ToDo: something for integer-shift ops?
86 primop_rule TagToEnumOp = mkBasicRule op_name 2 tagToEnumRule
87 primop_rule DataToTagOp = mkBasicRule op_name 2 dataToTagRule
90 primop_rule IntAddOp = two_lits (intOp2 (+))
91 primop_rule IntSubOp = two_lits (intOp2 (-))
92 primop_rule IntMulOp = two_lits (intOp2 (*))
93 primop_rule IntQuotOp = two_lits (intOp2Z quot)
94 primop_rule IntRemOp = two_lits (intOp2Z rem)
95 primop_rule IntNegOp = one_lit negOp
96 primop_rule ISllOp = two_lits (intShiftOp2 Bits.shiftL)
97 primop_rule ISraOp = two_lits (intShiftOp2 Bits.shiftR)
98 primop_rule ISrlOp = two_lits (intShiftOp2 shiftRightLogical)
101 primop_rule WordAddOp = two_lits (wordOp2 (+))
102 primop_rule WordSubOp = two_lits (wordOp2 (-))
103 primop_rule WordMulOp = two_lits (wordOp2 (*))
104 primop_rule WordQuotOp = two_lits (wordOp2Z quot)
105 primop_rule WordRemOp = two_lits (wordOp2Z rem)
106 primop_rule AndOp = two_lits (wordBitOp2 (.&.))
107 primop_rule OrOp = two_lits (wordBitOp2 (.|.))
108 primop_rule XorOp = two_lits (wordBitOp2 xor)
109 primop_rule SllOp = two_lits (wordShiftOp2 Bits.shiftL)
110 primop_rule SrlOp = two_lits (wordShiftOp2 shiftRightLogical)
113 primop_rule Word2IntOp = one_lit (litCoerce word2IntLit)
114 primop_rule Int2WordOp = one_lit (litCoerce int2WordLit)
115 primop_rule Narrow8IntOp = one_lit (litCoerce narrow8IntLit)
116 primop_rule Narrow16IntOp = one_lit (litCoerce narrow16IntLit)
117 primop_rule Narrow32IntOp = one_lit (litCoerce narrow32IntLit)
118 primop_rule Narrow8WordOp = one_lit (litCoerce narrow8WordLit)
119 primop_rule Narrow16WordOp = one_lit (litCoerce narrow16WordLit)
120 primop_rule Narrow32WordOp = one_lit (litCoerce narrow32WordLit)
121 primop_rule OrdOp = one_lit (litCoerce char2IntLit)
122 primop_rule ChrOp = one_lit (predLitCoerce litFitsInChar int2CharLit)
123 primop_rule Float2IntOp = one_lit (litCoerce float2IntLit)
124 primop_rule Int2FloatOp = one_lit (litCoerce int2FloatLit)
125 primop_rule Double2IntOp = one_lit (litCoerce double2IntLit)
126 primop_rule Int2DoubleOp = one_lit (litCoerce int2DoubleLit)
127 -- SUP: Not sure what the standard says about precision in the following 2 cases
128 primop_rule Float2DoubleOp = one_lit (litCoerce float2DoubleLit)
129 primop_rule Double2FloatOp = one_lit (litCoerce double2FloatLit)
132 primop_rule FloatAddOp = two_lits (floatOp2 (+))
133 primop_rule FloatSubOp = two_lits (floatOp2 (-))
134 primop_rule FloatMulOp = two_lits (floatOp2 (*))
135 primop_rule FloatDivOp = two_lits (floatOp2Z (/))
136 primop_rule FloatNegOp = one_lit negOp
139 primop_rule DoubleAddOp = two_lits (doubleOp2 (+))
140 primop_rule DoubleSubOp = two_lits (doubleOp2 (-))
141 primop_rule DoubleMulOp = two_lits (doubleOp2 (*))
142 primop_rule DoubleDivOp = two_lits (doubleOp2Z (/))
143 primop_rule DoubleNegOp = one_lit negOp
145 -- Relational operators
146 primop_rule IntEqOp = relop (==) ++ litEq op_name True
147 primop_rule IntNeOp = relop (/=) ++ litEq op_name False
148 primop_rule CharEqOp = relop (==) ++ litEq op_name True
149 primop_rule CharNeOp = relop (/=) ++ litEq op_name False
151 primop_rule IntGtOp = relop (>)
152 primop_rule IntGeOp = relop (>=)
153 primop_rule IntLeOp = relop (<=)
154 primop_rule IntLtOp = relop (<)
156 primop_rule CharGtOp = relop (>)
157 primop_rule CharGeOp = relop (>=)
158 primop_rule CharLeOp = relop (<=)
159 primop_rule CharLtOp = relop (<)
161 primop_rule FloatGtOp = relop (>)
162 primop_rule FloatGeOp = relop (>=)
163 primop_rule FloatLeOp = relop (<=)
164 primop_rule FloatLtOp = relop (<)
165 primop_rule FloatEqOp = relop (==)
166 primop_rule FloatNeOp = relop (/=)
168 primop_rule DoubleGtOp = relop (>)
169 primop_rule DoubleGeOp = relop (>=)
170 primop_rule DoubleLeOp = relop (<=)
171 primop_rule DoubleLtOp = relop (<)
172 primop_rule DoubleEqOp = relop (==)
173 primop_rule DoubleNeOp = relop (/=)
175 primop_rule WordGtOp = relop (>)
176 primop_rule WordGeOp = relop (>=)
177 primop_rule WordLeOp = relop (<=)
178 primop_rule WordLtOp = relop (<)
179 primop_rule WordEqOp = relop (==)
180 primop_rule WordNeOp = relop (/=)
182 primop_rule other = []
187 %************************************************************************
189 \subsection{Doing the business}
191 %************************************************************************
193 ToDo: the reason these all return Nothing is because there used to be
194 the possibility of an argument being a litlit. Litlits are now gone,
195 so this could be cleaned up.
198 --------------------------
199 litCoerce :: (Literal -> Literal) -> Literal -> Maybe CoreExpr
200 litCoerce fn lit = Just (Lit (fn lit))
202 predLitCoerce :: (Literal -> Bool) -> (Literal -> Literal) -> Literal -> Maybe CoreExpr
203 predLitCoerce p fn lit
204 | p lit = Just (Lit (fn lit))
205 | otherwise = Nothing
207 --------------------------
208 cmpOp :: (Ordering -> Bool) -> Literal -> Literal -> Maybe CoreExpr
212 done res | cmp res = Just trueVal
213 | otherwise = Just falseVal
215 -- These compares are at different types
216 go (MachChar i1) (MachChar i2) = done (i1 `compare` i2)
217 go (MachInt i1) (MachInt i2) = done (i1 `compare` i2)
218 go (MachInt64 i1) (MachInt64 i2) = done (i1 `compare` i2)
219 go (MachWord i1) (MachWord i2) = done (i1 `compare` i2)
220 go (MachWord64 i1) (MachWord64 i2) = done (i1 `compare` i2)
221 go (MachFloat i1) (MachFloat i2) = done (i1 `compare` i2)
222 go (MachDouble i1) (MachDouble i2) = done (i1 `compare` i2)
225 --------------------------
227 negOp :: Literal -> Maybe CoreExpr -- Negate
228 negOp (MachFloat 0.0) = Nothing -- can't represent -0.0 as a Rational
229 negOp (MachFloat f) = Just (mkFloatVal (-f))
230 negOp (MachDouble 0.0) = Nothing
231 negOp (MachDouble d) = Just (mkDoubleVal (-d))
232 negOp (MachInt i) = intResult (-i)
235 --------------------------
236 intOp2 :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
237 intOp2 op (MachInt i1) (MachInt i2) = intResult (i1 `op` i2)
238 intOp2 op l1 l2 = Nothing -- Could find LitLit
240 intOp2Z :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
241 -- Like intOp2, but Nothing if i2=0
242 intOp2Z op (MachInt i1) (MachInt i2)
243 | i2 /= 0 = intResult (i1 `op` i2)
244 intOp2Z op l1 l2 = Nothing -- LitLit or zero dividend
246 intShiftOp2 :: (Integer->Int->Integer) -> Literal -> Literal -> Maybe CoreExpr
247 -- Shifts take an Int; hence second arg of op is Int
248 intShiftOp2 op (MachInt i1) (MachInt i2) = intResult (i1 `op` fromInteger i2)
249 intShiftOp2 op l1 l2 = Nothing
251 shiftRightLogical :: Integer -> Int -> Integer
252 -- Shift right, putting zeros in rather than sign-propagating as Bits.shiftR would do
253 -- Do this by converting to Word and back. Obviously this won't work for big
254 -- values, but its ok as we use it here
255 shiftRightLogical x n = fromIntegral (fromInteger x `shiftR` n :: Word)
258 --------------------------
259 wordOp2 :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
260 wordOp2 op (MachWord w1) (MachWord w2)
261 = wordResult (w1 `op` w2)
262 wordOp2 op l1 l2 = Nothing -- Could find LitLit
264 wordOp2Z :: (Integer->Integer->Integer) -> Literal -> Literal -> Maybe CoreExpr
265 wordOp2Z op (MachWord w1) (MachWord w2)
266 | w2 /= 0 = wordResult (w1 `op` w2)
267 wordOp2Z op l1 l2 = Nothing -- LitLit or zero dividend
269 wordBitOp2 op l1@(MachWord w1) l2@(MachWord w2)
270 = wordResult (w1 `op` w2)
271 wordBitOp2 op l1 l2 = Nothing -- Could find LitLit
273 wordShiftOp2 :: (Integer->Int->Integer) -> Literal -> Literal -> Maybe CoreExpr
274 -- Shifts take an Int; hence second arg of op is Int
275 wordShiftOp2 op (MachWord x) (MachInt n)
276 = wordResult (x `op` fromInteger n)
277 -- Do the shift at type Integer
278 wordShiftOp2 op l1 l2 = Nothing
280 --------------------------
281 floatOp2 op (MachFloat f1) (MachFloat f2)
282 = Just (mkFloatVal (f1 `op` f2))
283 floatOp2 op l1 l2 = Nothing
285 floatOp2Z op (MachFloat f1) (MachFloat f2)
286 | f2 /= 0 = Just (mkFloatVal (f1 `op` f2))
287 floatOp2Z op l1 l2 = Nothing
289 --------------------------
290 doubleOp2 op (MachDouble f1) (MachDouble f2)
291 = Just (mkDoubleVal (f1 `op` f2))
292 doubleOp2 op l1 l2 = Nothing
294 doubleOp2Z op (MachDouble f1) (MachDouble f2)
295 | f2 /= 0 = Just (mkDoubleVal (f1 `op` f2))
296 doubleOp2Z op l1 l2 = Nothing
299 --------------------------
307 -- This is a Good Thing, because it allows case-of case things
308 -- to happen, and case-default absorption to happen. For
311 -- if (n ==# 3#) || (n ==# 4#) then e1 else e2
317 -- (modulo the usual precautions to avoid duplicating e1)
320 -> Bool -- True <=> equality, False <=> inequality
323 = [BuiltinRule { ru_name = occNameFS (nameOccName op_name)
324 `appendFS` FSLIT("->case"),
326 ru_nargs = 2, ru_try = rule_fn }]
328 rule_fn [Lit lit, expr] = do_lit_eq lit expr
329 rule_fn [expr, Lit lit] = do_lit_eq lit expr
330 rule_fn other = Nothing
333 = Just (Case expr (mkWildId (literalType lit)) boolTy
334 [(DEFAULT, [], val_if_neq),
335 (LitAlt lit, [], val_if_eq)])
336 val_if_eq | is_eq = trueVal
337 | otherwise = falseVal
338 val_if_neq | is_eq = falseVal
339 | otherwise = trueVal
341 -- Note that we *don't* warn the user about overflow. It's not done at
342 -- runtime either, and compilation of completely harmless things like
343 -- ((124076834 :: Word32) + (2147483647 :: Word32))
344 -- would yield a warning. Instead we simply squash the value into the
345 -- Int range, but not in a way suitable for cross-compiling... :-(
346 intResult :: Integer -> Maybe CoreExpr
348 = Just (mkIntVal (toInteger (fromInteger result :: Int)))
350 wordResult :: Integer -> Maybe CoreExpr
352 = Just (mkWordVal (toInteger (fromInteger result :: Word)))
356 %************************************************************************
358 \subsection{Vaguely generic functions
360 %************************************************************************
363 mkBasicRule :: Name -> Int -> ([CoreExpr] -> Maybe CoreExpr) -> [CoreRule]
364 -- Gives the Rule the same name as the primop itself
365 mkBasicRule op_name n_args rule_fn
366 = [BuiltinRule { ru_name = occNameFS (nameOccName op_name),
368 ru_nargs = n_args, ru_try = rule_fn }]
370 oneLit :: Name -> (Literal -> Maybe CoreExpr)
373 = mkBasicRule op_name 1 rule_fn
375 rule_fn [Lit l1] = test (convFloating l1)
378 twoLits :: Name -> (Literal -> Literal -> Maybe CoreExpr)
381 = mkBasicRule op_name 2 rule_fn
383 rule_fn [Lit l1, Lit l2] = test (convFloating l1) (convFloating l2)
386 -- When excess precision is not requested, cut down the precision of the
387 -- Rational value to that of Float/Double. We confuse host architecture
388 -- and target architecture here, but it's convenient (and wrong :-).
389 convFloating :: Literal -> Literal
390 convFloating (MachFloat f) | not opt_SimplExcessPrecision =
391 MachFloat (toRational ((fromRational f) :: Float ))
392 convFloating (MachDouble d) | not opt_SimplExcessPrecision =
393 MachDouble (toRational ((fromRational d) :: Double))
396 trueVal = Var trueDataConId
397 falseVal = Var falseDataConId
398 mkIntVal i = Lit (mkMachInt i)
399 mkWordVal w = Lit (mkMachWord w)
400 mkFloatVal f = Lit (convFloating (MachFloat f))
401 mkDoubleVal d = Lit (convFloating (MachDouble d))
405 %************************************************************************
407 \subsection{Special rules for seq, tagToEnum, dataToTag}
409 %************************************************************************
412 tagToEnumRule [Type ty, Lit (MachInt i)]
413 = ASSERT( isEnumerationTyCon tycon )
414 case filter correct_tag (tyConDataCons_maybe tycon `orElse` []) of
417 [] -> Nothing -- Abstract type
418 (dc:rest) -> ASSERT( null rest )
419 Just (Var (dataConWorkId dc))
421 correct_tag dc = (dataConTag dc - fIRST_TAG) == tag
423 tycon = tyConAppTyCon ty
425 tagToEnumRule other = Nothing
428 For dataToTag#, we can reduce if either
430 (a) the argument is a constructor
431 (b) the argument is a variable whose unfolding is a known constructor
434 dataToTagRule [Type ty1, Var tag_to_enum `App` Type ty2 `App` tag]
435 | tag_to_enum `hasKey` tagToEnumKey
436 , ty1 `coreEqType` ty2
437 = Just tag -- dataToTag (tagToEnum x) ==> x
439 dataToTagRule [_, val_arg]
440 | Just (dc,_) <- exprIsConApp_maybe val_arg
441 = ASSERT( not (isNewTyCon (dataConTyCon dc)) )
442 Just (mkIntVal (toInteger (dataConTag dc - fIRST_TAG)))
444 dataToTagRule other = Nothing
447 %************************************************************************
449 \subsection{Built in rules}
451 %************************************************************************
453 Note [Scoping for Builtin rules]
454 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
455 When compiling a (base-package) module that defines one of the
456 functions mentioned in the RHS of a built-in rule, there's a danger
459 f = ...(eq String x)....
461 ....and lower down...
465 Then a rewrite would give
467 f = ...(eqString x)...
468 ....and lower down...
471 and lo, eqString is not in scope. This only really matters when we get to code
472 generation. With -O we do a GlomBinds step that does a new SCC analysis on the whole
473 set of bindings, which sorts out the dependency. Without -O we don't do any rule
474 rewriting so again we are fine.
476 (This whole thing doesn't show up for non-built-in rules because their dependencies
481 builtinRules :: [CoreRule]
482 -- Rules for non-primops that can't be expressed using a RULE pragma
484 = [ BuiltinRule { ru_name = FSLIT("AppendLitString"), ru_fn = unpackCStringFoldrName,
485 ru_nargs = 4, ru_try = match_append_lit },
486 BuiltinRule { ru_name = FSLIT("EqString"), ru_fn = eqStringName,
487 ru_nargs = 2, ru_try = match_eq_string },
488 BuiltinRule { ru_name = FSLIT("Inline"), ru_fn = inlineIdName,
489 ru_nargs = 2, ru_try = match_inline }
493 ---------------------------------------------------
495 -- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) = unpackFoldrCString# "foobaz" c n
497 match_append_lit [Type ty1,
500 Var unpk `App` Type ty2
501 `App` Lit (MachStr s2)
505 | unpk `hasKey` unpackCStringFoldrIdKey &&
507 = ASSERT( ty1 `coreEqType` ty2 )
508 Just (Var unpk `App` Type ty1
509 `App` Lit (MachStr (s1 `appendFS` s2))
513 match_append_lit other = Nothing
515 ---------------------------------------------------
517 -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2) = s1==s2
519 match_eq_string [Var unpk1 `App` Lit (MachStr s1),
520 Var unpk2 `App` Lit (MachStr s2)]
521 | unpk1 `hasKey` unpackCStringIdKey,
522 unpk2 `hasKey` unpackCStringIdKey
523 = Just (if s1 == s2 then trueVal else falseVal)
525 match_eq_string other = Nothing
528 ---------------------------------------------------
530 -- inline f_ty (f a b c) = <f's unfolding> a b c
531 -- (if f has an unfolding)
533 -- It's important to allow the argument to 'inline' to have args itself
534 -- (a) because its more forgiving to allow the programmer to write
536 -- or inline (f a b c)
537 -- (b) because a polymorphic f wll get a type argument that the
538 -- programmer can't avoid
540 -- Also, don't forget about 'inline's type argument!
541 match_inline (Type _ : e : _)
542 | (Var f, args1) <- collectArgs e,
543 Just unf <- maybeUnfoldingTemplate (idUnfolding f)
544 = Just (mkApps unf args1)
546 match_inline other = Nothing