summaryrefslogtreecommitdiff
path: root/compiler/cmm/PprC.hs
diff options
context:
space:
mode:
authorJoachim Breitner <mail@joachim-breitner.de>2015-03-30 10:20:14 +0200
committerJoachim Breitner <mail@joachim-breitner.de>2015-03-30 10:22:27 +0200
commitde1160be047790afde4ec76de0a81ba3be0c73fa (patch)
tree269bbb98b8451d2cf1ccf1a86dfaae69f2acb50e /compiler/cmm/PprC.hs
parente24f638158f96f80e476000cd7ce8555987d84f2 (diff)
downloadhaskell-de1160be047790afde4ec76de0a81ba3be0c73fa.tar.gz
Refactor the story around switches (#10137)
This re-implements the code generation for case expressions at the Stg → Cmm level, both for data type cases as well as for integral literal cases. (Cases on float are still treated as before). The goal is to allow for fancier strategies in implementing them, for a cleaner separation of the strategy from the gritty details of Cmm, and to run this later than the Common Block Optimization, allowing for one way to attack #10124. The new module CmmSwitch contains a number of notes explaining this changes. For example, it creates larger consecutive jump tables than the previous code, if possible. nofib shows little significant overall improvement of runtime. The rather large wobbling comes from changes in the code block order (see #8082, not much we can do about it). But the decrease in code size alone makes this worthwhile. ``` Program Size Allocs Runtime Elapsed TotalMem Min -1.8% 0.0% -6.1% -6.1% -2.9% Max -0.7% +0.0% +5.6% +5.7% +7.8% Geometric Mean -1.4% -0.0% -0.3% -0.3% +0.0% ``` Compilation time increases slightly: ``` -1 s.d. ----- -2.0% +1 s.d. ----- +2.5% Average ----- +0.3% ``` The test case T783 regresses a lot, but it is the only one exhibiting any regression. The cause is the changed order of branches in an if-then-else tree, which makes the hoople data flow analysis traverse the blocks in a suboptimal order. Reverting that gets rid of this regression, but has a consistent, if only very small (+0.2%), negative effect on runtime. So I conclude that this test is an extreme outlier and no reason to change the code. Differential Revision: https://phabricator.haskell.org/D720
Diffstat (limited to 'compiler/cmm/PprC.hs')
-rw-r--r--compiler/cmm/PprC.hs25
1 files changed, 10 insertions, 15 deletions
diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
index a2c3abf320..92c818242d 100644
--- a/compiler/cmm/PprC.hs
+++ b/compiler/cmm/PprC.hs
@@ -33,6 +33,7 @@ import Cmm hiding (pprBBlock)
import PprCmm ()
import Hoopl
import CmmUtils
+import CmmSwitch
-- Utils
import CPrim
@@ -299,21 +300,12 @@ pprCondBranch expr yes no
--
-- we find the fall-through cases
--
--- N.B. we remove Nothing's from the list of branches, as they are
--- 'undefined'. However, they may be defined one day, so we better
--- document this behaviour.
---
-pprSwitch :: DynFlags -> CmmExpr -> [ Maybe BlockId ] -> SDoc
-pprSwitch dflags e maybe_ids
- = let pairs = [ (ix, ident) | (ix,Just ident) <- zip [0..] maybe_ids ]
- pairs2 = [ (map fst as, snd (head as)) | as <- groupBy sndEq pairs ]
- in
- (hang (ptext (sLit "switch") <+> parens ( pprExpr e ) <+> lbrace)
- 4 (vcat ( map caseify pairs2 )))
- $$ rbrace
-
+pprSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> SDoc
+pprSwitch dflags e ids
+ = (hang (ptext (sLit "switch") <+> parens ( pprExpr e ) <+> lbrace)
+ 4 (vcat ( map caseify pairs ) $$ def)) $$ rbrace
where
- sndEq (_,x) (_,y) = x == y
+ (pairs, mbdef) = switchTargetsFallThrough ids
-- fall through case
caseify (ix:ixs, ident) = vcat (map do_fallthrough ixs) $$ final_branch ix
@@ -326,7 +318,10 @@ pprSwitch dflags e maybe_ids
hsep [ ptext (sLit "case") , pprHexVal ix (wordWidth dflags) <> colon ,
ptext (sLit "goto") , (pprBlockId ident) <> semi ]
- caseify (_ , _ ) = panic "pprSwtich: swtich with no cases!"
+ caseify (_ , _ ) = panic "pprSwitch: switch with no cases!"
+
+ def | Just l <- mbdef = ptext (sLit "default: goto") <+> pprBlockId l <> semi
+ | otherwise = empty
-- ---------------------------------------------------------------------
-- Expressions.