Method selectors aren't floated out of loops
Here is a small example:
foo :: Num a => [a] -> [a]
foo as = filter (/=0) (map (\x -> x-x) as)
Here is the code that the current HEAD generates for the loop:
go_smy =
\ (ds_akN :: [a_aiw]) ->
case ds_akN of _ {
[] -> GHC.Types.[] @ a_aiw;
: y_akS ys_akT ->
let {
x_smA :: a_aiw
x_smA = GHC.Num.- @ a_aiw $dNum_ajk y_akS y_akS } in
case GHC.Classes./= @ a_aiw lvl_smu x_smA lit_smw of _ {
GHC.Bool.False -> go_smy ys_akT;
GHC.Bool.True -> GHC.Types.: @ a_aiw x_smA (go_smy ys_akT)
}
Note that the Eq
dictionary is inspected by (/=)
in every loop iteration. Floating out GHC.Classes./= @ a_aiw lvl_smu
(and, perhaps, GHC.Num.- @ a_aiw $dNum_ajk
) should solve this. In fact, I wonder why that isn't happening already. Do method selectors have a wrong arity?
FWIW, in GHC 6.10 LiberateCase
moves the method selection out of the loop (not ideal, but it gets the job done) so !NoSlow shows this as a slight performance regression.
Trac metadata
Trac field | Value |
---|---|
Version | 6.13 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |