[GHC] #14644: Improve cmm/assembly for pattern matches with two constants.
GHC
ghc-devs at haskell.org
Sun Jan 7 20:04:38 UTC 2018
#14644: Improve cmm/assembly for pattern matches with two constants.
-------------------------------------+-------------------------------------
Reporter: AndreasK | Owner: (none)
Type: task | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.2.2
(CodeGen) |
Keywords: Codegen, CMM, | Operating System: Unknown/Multiple
Patterns, Pattern Matching |
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
For a pattern like:
{{{
f_test :: Int#->Int#
f_test a = case a of
1# -> 33#
7# -> 34#
_ -> -1#
}}}
GHC currently generates code that works best if the default branch is
taken most often.
Pseudo-Code
{{{
if (a >= 8)
return -1;
else {
if (a < 7) {
if(a != 1)
return -1;
else
return 33;
}
else
return 34;
}
}}}
CMM:
{{{
c1cr: // global
if (%MO_S_Ge_W64(R2, 8)) goto c1co; else goto u1cu;
u1cu: // global
if (%MO_S_Lt_W64(R2, 7)) goto u1cv; else goto c1cq;
u1cv: // global
if (R2 != 1) goto c1co; else goto c1cp;
c1co: // global
R1 = (-1);
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
c1cp: // global
R1 = 33;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
c1cq: // global
R1 = 34;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
}}}
Wouldn't the following be better?
{{{
if(a == 1)
return 33
else if(a == 7)
return 34
else
return -1
}}}
I would expect that to
* Improve the cases:
* a = 1
* a < 7
* Be the same for:
* a = 7
* Be worse for
* a > 8
This would be especially nice for the cases where the default branch is
raising a pattern match exception.
Which is a code path I wouldn't expect to be taken often nor be very
performance sensitive.
Even if we keep the current logic there is room for improvement.
GHC currently creates the following assembly:
{{{
_c1cr:
cmpq $8,%r14
jge _c1co
_u1cu:
cmpq $7,%r14
jl _u1cv
_c1cq:
movl $34,%ebx
jmp *(%rbp)
_u1cv:
cmpq $1,%r14
jne _c1co
_c1cp:
movl $33,%ebx
jmp *(%rbp)
_c1co:
movq $-1,%rbx
jmp *(%rbp)
}}}
It would be nice if we could remove one comparison at least.
{{{
_c1cr:
cmpq $7,%r14
jg _c1co
_u1cu:
;No longer neccesary cmpq $7,%r14
jl _u1cv
_c1cq:
movl $34,%ebx
jmp *(%rbp)
_u1cv:
cmpq $1,%r14
jne _c1co
_c1cp:
movl $33,%ebx
jmp *(%rbp)
_c1co:
movq $-1,%rbx
jmp *(%rbp)
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14644>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list