This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Autoincrement ideas
- To: "Michael P. Hayes" <michaelh at ongaonga dot chch dot cri dot nz>
- Subject: Re: Autoincrement ideas
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Wed, 28 Jan 1998 20:51:01 -0700
- cc: egcs at cygnus dot com
- Reply-To: law at cygnus dot com
In message <199801190301.QAA05626@ongaonga.chch.cri.nz>you write:
> I've been hacking flow.c to improve generation of autoincrement
> addressing modes, in particular for targets that can increment
> an address by the contents of another register (eg, RS6000, ARC,
> C3x/C4x).
Interestingly enough the HPPA can do something quite similar.
The difference is the base register update happens *after* the
memory reference. So we'd want to do something like this:
insn 1: (set (reg A) (mem (reg B)))
insn 2: (set (reg B) (plus (reg B) (reg C)))
into
(parallel [(set (reg A) (mem (reg B)))
(set (reg B) (plus (reg B) (reg C))])
To make matters more complicated, you can also replace reg C with
(ashift (reg C) (const_int X)) for X = 1,2,3 depending on the
size of the memory reference. C could also be a constant that
doesn't necessarily relate to the size of a memory reference.
> Currrently these targets have move_update patterns
> but they don't get exercised very often since the combine pass
> only looks for insns where a source operand is set by a preceeding
> insn.
Yup.
> I thus modified flow.c to combine the following two insns
>
[ ... ]
> which works fine but is still very limited.
Yup.
> A better approach would be handle this sort of side effect like we
> handle POST_INC so that other instructions can utilise these
> addressing modes without having to define myriads of other patterns.
>
> I envisage either of two approaches:
>
> 1) (set (reg A) (mem (post_inc2 (reg B) (reg C))))
>
> 2) (set (reg A) (mem (post_inc (plus (reg B) (reg C)))))
>
There was a contribution *years* ago which introduced PRE_MODIFY
and POST_MODIFY to do basically the same thing. I don't know why
they never went into the tree.
I did manage to save a copy of the submission as well as some of
RMS's comments.
(post_modify:M x y)
Represents the side effect of incrementing X by Y and represents
X before X is incremented. Here incremented is either
incrementing or decrementing depending on the value of Y.
X must be a `reg' or `mem', but most machines allow only a
`reg'. M must be the machine mode for pointers on the machine in
use. Y can be a register or a constant or a memory reference.
(pre_modify:M x y)
Similar except sideffects happen before the use.
If you want the old code I can forward it to you. It might be
possible to beat it into shape.
jeff