common branch conditions - could optimize better
Geoff Keating
geoffk@envy.cygnus.com
Thu Dec 16 12:47:00 GMT 1999
Jeffrey A Law <law@cygnus.com> writes:
> In message <19991216113512.A31064@horac.ta.jcu.cz>you write:
> > On Thu, Dec 16, 1999 at 02:11:45AM -0700, Jeffrey A Law wrote:
> > > In message <Pine.LNX.4.10.9910160739260.1293-100000@first>you write:
> > > > Hello GCC people
> > > >
> > > > Consider the following code:
> > > >
> > > > void f1(void), f2(void), f3(void);
> > > > void foo (int x, int y)
> > > > {
> > > > if (x*x*x<y*y)
> > > > f1();
> > > > else
> > > > f2();
> > > > if (x*x*x<y*y)
> > > > f3();
> > > > }
> > > >
> > > > Here the condition x*x*x<y*y could be tested only once.
> > > > GCC 2.95.1 does not optimize this - see below the asm,
> > > > produced with gcc -O2 -S on i586-linux.
> > > > Even x*x*x and y*y are computed twice... what is that gcse thing then
> > ?
> > > It's got to be something goofy about the ia32 target, they're removed jus
> > t
> > > fine on my PA target.
> >
> > It is because of gcse is unable to handle parallels used by x86 to model
> > flags. I've made some progress in this path (for cprop only for now),
> > but first part (to propagate from parallels) got refused (it is not issue
> > for x86 after my mov patterns cleanups anyway) and second part (to propagat
> > e
> > to parallels) wasn't reviewed yet.
> No. That is not the cause. Go back to gcc-2.95 and try it like the report
> mentions. Remember gcc-2.95 did not have the new ia32 backend.
On ppc, this is very interesting.
Under 2.95.2, no folding is done. We get six multiplies emitted at -O2.
Under 19991215, we get four (count em!) multiplies. The extra
multiply is of x*temp, where temp was previously computed from x*x.
The RTL that is generated for the multiplies of 'x' is:
(insn 4 53 6 (set (reg/v:SI 82)
(reg:SI 3 r3)) 426 {movsi+1} (nil)
(nil))
..
(insn 13 7 58 (set (reg:SI 84)
(mult:SI (reg/v:SI 82)
(reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
(nil))
// reg 92 is never mentioned other than here. It is created by GCSE.
(insn 58 13 15 (set (reg:SI 92)
(reg:SI 84)) -1 (nil)
(nil))
(insn 15 58 17 (set (reg:SI 85)
(mult:SI (reg:SI 84)
(reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
(nil))
and then in a basic block far away,
// changed by GCSE from
// (set (reg:SI 88 (mult:SI (reg/v: SI 82) (reg/v: SI 82))))
(insn 30 48 32 (set (reg:SI 88)
(reg:SI 84)) 426 {movsi+1} (nil)
(nil))
(insn 32 30 34 (set (reg:SI 89)
(mult:SI (reg:SI 88)
(reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
(nil))
GCSE is seeing these multiplies as different simply because they use
different registers. Probably what we need to do is train GCSE to do a
little no-op set elimination.
--
- Geoffrey Keating <geoffk@cygnus.com>
More information about the Gcc
mailing list