This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Inefficient uses of JUMP_P
Hi Richard,
I apologize in advance if I appear to be too pushy on this speed-up,
but this isn't kind of improvement where I save a couple of CPU cycles
here and there.
I did a quick hack and saw some improvement. Specifically, I replaced
all uses of jump predicates with inline wrapper functions with prefix
"inefficient_" like so
static inline int
inefficient_tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
{
if (!JUMP_P (insn))
return 0;
return tablejump_p (insn, labelp, tablep);
}
and removed JUMP_P check from each of the predicates. Then I went
through all *.c and the i386 backend to remove the prefix
"inefficient_" wherever appropriate. Here is a timing in seconds for
five runs of several semi-large testcases.
original patched diff %
c-common.c 20.894 20.254 -3.159
combine.c 20.090 19.174 -4.777
dwarf2out.c 19.457 19.247 -1.091
fold-const.c 43.580 42.898 -1.589
> > I am thinking about making these checks the callers' responsibility so
> > that we will only have to do a single JUMP_P check for each "if"
> > statement containing several jump predicates.
>
> I think that will result in more source code bloat and missed
> checks than anything else.
Missed checks are certainly a concern. Putting into jump predicates a
check like
#ifdef ENABLE_CHECKING
gcc_assert (JUMP_P (insn));
#endif
may alleviate the concern, but not completely. If we enabled the
gcc_assert in a production compiler (with checks disabled and asserts
enabled), we wouldn't get speed-up anyway.
I am not so worried about code bloat because I only have 65 uses of
those inline functions with "inefficient_" prefix (out of 200 some
uses of jump predicates).
> I think the thing to take away from this is that if we're often
> seeing two or more predicates used together, then we have
> incorrectly factored code. Better would be a new predicate
> that performs the composite operation.
One problem is that there are so many combinations that are actually
in use. Plus "if (JUMP_P (insn))" often dominates a lot of code under
it, in which case a composite predicate won't help.
One compromise would be to make these jump predicates pure functions
and provide wrapper inline functions for each predicate like so:
static inline int
tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
{
if (!JUMP_P (insn))
return 0;
return tablejump_p_1 (insn, labelp, tablep);
}
Then GCC itself should be able to remove redundant JUMP_P by itself,
and we wouldn't have to worry as much about missed checks. Of course,
if there are (non-pure/const) function calls or write access to memory
between a JUMP_P and a use of a jump predicate, GCC may not be able to
remove the second occurrence of JUMP_P.
Kazu Hirata