This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]