[Git][ghc/ghc][master] Core: add absorb rules for binary or/and (#16351)
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Thu Sep 26 08:17:58 UTC 2024
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
383af074 by Sylvain Henry at 2024-09-26T04:16:06-04:00
Core: add absorb rules for binary or/and (#16351)
Rules:
x or (x and y) ==> x
x and (x or y) ==> x
- - - - -
4 changed files:
- compiler/GHC/Core/Opt/ConstantFold.hs
- + testsuite/tests/codeGen/should_compile/T16351.hs
- + testsuite/tests/codeGen/should_compile/T16351.stderr
- testsuite/tests/codeGen/should_compile/all.T
Changes:
=====================================
compiler/GHC/Core/Opt/ConstantFold.hs
=====================================
@@ -3056,6 +3056,11 @@ andFoldingRules' platform arg1 arg2 num_ops = case (arg1, arg2) of
-- (l1 or x) and (l2 or y) ==> (l1 and l2) or (x and l2) or (l1 and y) or (x and y)
-- increase operation numbers
+ -- x and (y or ... or x or ... or z) ==> x
+ (x, is_or_list num_ops -> Just xs)
+ | any (cheapEqExpr x) xs
+ -> Just x
+
_ -> Nothing
where
mkL = Lit . mkNumLiteral platform num_ops
@@ -3079,6 +3084,11 @@ orFoldingRules' platform arg1 arg2 num_ops = case (arg1, arg2) of
-- (l1 and x) or (l2 and y) ==> (l1 and l2) or (x and l2) or (l1 and y) or (x and y)
-- increase operation numbers
+ -- x or (y and ... and x and ... and z) ==> x
+ (x, is_and_list num_ops -> Just xs)
+ | any (cheapEqExpr x) xs
+ -> Just x
+
_ -> Nothing
where
mkL = Lit . mkNumLiteral platform num_ops
@@ -3117,7 +3127,7 @@ is_op op e = case e of
App (OpVal op') x | op == op' -> Just x
_ -> Nothing
-is_add, is_sub, is_mul, is_and, is_or, is_div :: NumOps -> CoreExpr -> Maybe (Arg CoreBndr, Arg CoreBndr)
+is_add, is_sub, is_mul, is_and, is_or, is_div :: NumOps -> CoreExpr -> Maybe (CoreArg, CoreArg)
is_add num_ops e = is_binop (numAdd num_ops) e
is_sub num_ops e = is_binop (numSub num_ops) e
is_mul num_ops e = is_binop (numMul num_ops) e
@@ -3128,6 +3138,25 @@ is_div num_ops e = numDiv num_ops >>= \op -> is_binop op e
is_neg :: NumOps -> CoreExpr -> Maybe (Arg CoreBndr)
is_neg num_ops e = numNeg num_ops >>= \op -> is_op op e
+-- Return a list of operands for a given operation.
+-- E.e. is_and_list (a and ... and z) => [a,...,z] for any nesting of the and
+-- operation
+is_list :: (CoreExpr -> Maybe (CoreArg,CoreArg)) -> CoreExpr -> Maybe [CoreArg]
+is_list f e_org = case f e_org of -- do we have the operator at all?
+ Just (a,b) -> Just (go [a,b])
+ Nothing -> Nothing
+ where
+ go = \case
+ [] -> []
+ (e:es) -> case f e of
+ -- we can't split any more: add to the result list
+ Nothing -> e : go es
+ Just (a,b) -> go (a:b:es)
+
+is_and_list, is_or_list :: NumOps -> CoreExpr -> Maybe [CoreArg]
+is_and_list ops = is_list (is_and ops)
+is_or_list ops = is_list (is_or ops)
+
-- match operation with a literal (handles commutativity)
is_lit_add, is_lit_mul, is_lit_and, is_lit_or :: NumOps -> CoreExpr -> Maybe (Integer, Arg CoreBndr)
is_lit_add num_ops e = is_lit' is_add num_ops e
=====================================
testsuite/tests/codeGen/should_compile/T16351.hs
=====================================
@@ -0,0 +1,23 @@
+module T16351 where
+
+import Data.Bits
+
+x1,x2,x3,x4,x5,x6,x7,x8 :: Int -> Int -> Int
+
+x1 a b = a .&. (a .|. b)
+x2 a b = a .|. (a .&. b)
+x3 a b = a .&. (b .|. a)
+x4 a b = a .|. (b .&. a)
+x5 a b = (a .|. b) .&. a
+x6 a b = (a .&. b) .|. a
+x7 a b = (b .|. a) .&. a
+x8 a b = (b .&. a) .|. a
+
+-- add more nesting
+x10,x11,x12,x13,x14 :: Int -> Int -> Int -> Int
+
+x10 a b c = a .&. ((a .|. b) .|. c)
+x11 a b c = a .&. (c .|. (a .|. b))
+x12 a b c = a .&. (c .|. (b .|. a))
+x13 a b c = a .&. ((b .|. a) .|. c)
+x14 a b c = a .&. ((c .|. (b .|. a)) .|. c)
=====================================
testsuite/tests/codeGen/should_compile/T16351.stderr
=====================================
@@ -0,0 +1,42 @@
+
+==================== Tidy Core ====================
+Result size of Tidy Core
+ = {terms: 63, types: 72, coercions: 0, joins: 0/0}
+
+x14
+ = \ a b c ->
+ case a of wild { I# x# ->
+ case c of { I# x#1 -> case b of { I# x#2 -> wild } }
+ }
+
+x13
+ = \ a b c ->
+ case a of wild { I# x# ->
+ case b of { I# x#1 -> case c of { I# y# -> wild } }
+ }
+
+x12 = x14
+
+x11 = x14
+
+x10 = x13
+
+x8 = \ a b -> case b of { I# x# -> a }
+
+x7 = x8
+
+x6
+ = \ a b -> case a of wild { I# x# -> case b of { I# y# -> wild } }
+
+x5 = x6
+
+x4 = x6
+
+x3 = x6
+
+x2 = x6
+
+x1 = x6
+
+
+
=====================================
testsuite/tests/codeGen/should_compile/all.T
=====================================
@@ -143,3 +143,5 @@ test('T25166', [req_cmm], makefile_test, [])
# dump Core to ensure that d is defined as: d = D 10## RUBBISH(IntRep)
test('T25177', normal, compile, ['-O2 -dno-typeable-binds -ddump-simpl -dsuppress-all -dsuppress-uniques -v0'])
+
+test('T16351', normal, compile, ['-O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/383af0743a46e0961c342261f13a4527ae838873
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/383af0743a46e0961c342261f13a4527ae838873
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240926/573aafc3/attachment-0001.html>
More information about the ghc-commits
mailing list