This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Implement switch statements with bit tests
On Fri, Jan 24, 2003 at 09:31:48AM -0700, Roger Sayle wrote:
> That's clever. I hadn't realized that the alpha had a "branch
> if low bit set instruction". It's not universally an improvement
> because with the original formulation the register storing "1<<x"
> can be reused in multiple tests.
Re-using the shift is important for older alphas. Eg. for EV5
which has 4 pipelines, but only one shifter, and has a special
bypass that can dual issue an AND followed by a branch using it.
Indeed, I'd prefer to trust combine (with the help of the backend)
to transform to the branch-if-low-bit-set form.
> A more generic approach might be
>
> if ((int)(CST << x) < 0)
>
> i.e. push the relevant bit into the most significant or sign-bit,
> and then use instructions that test if the word is negative. This
> will benefit targets that have condition code registers that are
> set appropriately by the shift (including x86?).
This _is_ handy for many targets, but falls into the same
category as the above, however, since we don't get to reuse
the shifts.
It also makes the constant more difficult to generate, since
most targets can't load "large" constants in one instruction.
It's possible that rtx_cost is helpful here again.
For sure, if MINVAL is non-zero, you should modify that adjustment
such that CST is as small as possible. E.g.
switch (x)
{
case 100: case 101: case 102:
goto ONE;
case 103: case 104: case 105:
goto TWO;
}
becomes
MINVAL=100
MAXVAL=105
BIAS=MAXVAL - (WORD_SIZE - 1)
t = x - BIAS;
if (t > (WORD_SIZE - 1))
goto DEFAULT;
if ((070 << t) < 0)
goto ONE;
if ((007 << t) < 0)
goto TWO;
goto DEFAULT;
[ Hmm. For this case, do we notice that there are no holes in the
switch constants, such that once we've eliminated all those outside
MIN-MAX, we no longer need to worry about the default? E.g. in
this case we could just do "goto TWO" after the test for ONE. ]
r~