[GHC] #10124: Simple case analyses generate too many branches
GHC
ghc-devs at haskell.org
Mon Mar 2 16:22:33 UTC 2015
#10124: Simple case analyses generate too many branches
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.4
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Runtime | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: #6135, #9661 | Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by nomeata):
> I'd agree that it seems better to avoid breaking up the case expression
to begin with.
Not sure if that helps, after all, we want to have good code even when the
user writes a case statement to begin with:
{{{
myIsSpace ' ' = True
myIsSpace '\n' = True
myIsSpace '\t' = True
myIsSpace _ = False
}}}
I would expect the compiler to (try to) create optimal code from this
specification, whether it’s a linear list of condition, an if-then-else-
tree or a jump table.
I looked at the CG, which even has a pass to unify the common branches,
but we need CMM first, so we have to generate some assembly. We currently
unconditionally generate an if-then-else tree there, so it is hard to
rewrite that into something smarter.
Maybe the way forward would be to implement this todo from 11 years ago:
{{{
emitCmmLitSwitch :: CmmExpr -- Tag to switch on
-> [(Literal, CmmAGraphScoped)] -- Tagged branches
-> CmmAGraphScoped -- Default branch (always)
-> FCode () -- Emit the code
-- Used for general literals, whose size might not be a word,
-- where there is always a default case, and where we don't know
-- the range of values for certain. For simplicity we always generate a
tree.
--
-- ToDo: for integers we could do better here, perhaps by generalising
-- mk_switch and using that. --SDM 15/09/2004
}}}
For `emitCmmSwitch` there is already a case that generates a `CmmSwitch`
statement, used when compiling to C. So we might want to try to create a
`switch` statement also in `emitCmmLitSwitch` when compiling via LLVM, to
leave it to the compiler.
If we emit a switch statement in `emitCmmLitSwitch` unconditionally, then
we can run the common block transformation first, and later, in a separate
step replace the `CmmSwitch` by a tree of if-then-else statements, or by
some branchless code, or whatever looks best by then. For LLVM, we might
simply leave it as a switch statement.
In order to do so, the type of `CmmSwitch` would have to support sparse
switch statements better – it currently takes a `[Maybe Label]`.
(Disclaimer: I don’t know much about code generation. If I’m not helpful
here, just tell me :-))
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10124#comment:10>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list