This is the mail archive of the gcc-patches@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: [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~


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