diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2016-12-09 10:26:34 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-12-09 10:27:34 -0500 |
commit | d3b546b1a6058f26d5659c7f2000a7b25b7ea2ba (patch) | |
tree | 96929e66f77af1c5f9ce451c032a24e988de57b3 /compiler/prelude/PrelRules.hs | |
parent | 61932cd3eb0d5d22cb35d118fb9f87298881cd77 (diff) | |
download | haskell-d3b546b1a6058f26d5659c7f2000a7b25b7ea2ba.tar.gz |
Scrutinee Constant Folding
This patch introduces new rules to perform constant folding through
case-expressions.
E.g.,
```
case t -# 10# of _ { ===> case t of _ {
5# -> e1 15# -> e1
8# -> e2 18# -> e2
DEFAULT -> e DEFAULT -> e
```
The initial motivation is that it allows "Merge Nested Cases"
optimization to kick in and to further simplify the code
(see Trac #12877).
Currently we recognize the following operations for Word# and Int#: Add,
Sub, Xor, Not and Negate (for Int# only).
Test Plan: validate
Reviewers: simonpj, austin, bgamari
Reviewed By: simonpj, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2762
GHC Trac Issues: #12877
Diffstat (limited to 'compiler/prelude/PrelRules.hs')
-rw-r--r-- | compiler/prelude/PrelRules.hs | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/compiler/prelude/PrelRules.hs b/compiler/prelude/PrelRules.hs index 8868047005..e98fd9f6a3 100644 --- a/compiler/prelude/PrelRules.hs +++ b/compiler/prelude/PrelRules.hs @@ -15,7 +15,12 @@ ToDo: {-# LANGUAGE CPP, RankNTypes #-} {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-} -module PrelRules ( primOpRules, builtinRules ) where +module PrelRules + ( primOpRules + , builtinRules + , caseRules + ) +where #include "HsVersions.h" #include "../includes/MachDeps.h" @@ -1385,3 +1390,53 @@ match_smallIntegerTo primOp _ _ _ [App (Var x) y] | idName x == smallIntegerName = Just $ App (Var (mkPrimOpId primOp)) y match_smallIntegerTo _ _ _ _ _ = Nothing + + + +-------------------------------------------------------- +-- Constant folding through case-expressions +-- +-- cf Scrutinee Constant Folding in simplCore/SimplUtils +-------------------------------------------------------- + +-- | Match the scrutinee of a case and potentially return a new scrutinee and a +-- function to apply to each literal alternative. +caseRules :: CoreExpr -> Maybe (CoreExpr, Integer -> Integer) +caseRules scrut = case scrut of + + -- v `op` x# + App (App (Var f) v) (Lit l) + | Just op <- isPrimOpId_maybe f + , Just x <- isLitValue_maybe l -> + case op of + WordAddOp -> Just (v, \y -> y-x ) + IntAddOp -> Just (v, \y -> y-x ) + WordSubOp -> Just (v, \y -> y+x ) + IntSubOp -> Just (v, \y -> y+x ) + XorOp -> Just (v, \y -> y `xor` x) + XorIOp -> Just (v, \y -> y `xor` x) + _ -> Nothing + + -- x# `op` v + App (App (Var f) (Lit l)) v + | Just op <- isPrimOpId_maybe f + , Just x <- isLitValue_maybe l -> + case op of + WordAddOp -> Just (v, \y -> y-x ) + IntAddOp -> Just (v, \y -> y-x ) + WordSubOp -> Just (v, \y -> x-y ) + IntSubOp -> Just (v, \y -> x-y ) + XorOp -> Just (v, \y -> y `xor` x) + XorIOp -> Just (v, \y -> y `xor` x) + _ -> Nothing + + -- op v + App (Var f) v + | Just op <- isPrimOpId_maybe f -> + case op of + NotOp -> Just (v, \y -> complement y) + NotIOp -> Just (v, \y -> complement y) + IntNegOp -> Just (v, \y -> negate y ) + _ -> Nothing + + _ -> Nothing |