Thread-safe profiling

Michael Matz matz@suse.de
Thu Mar 15 14:29:00 GMT 2007


Hi,

On Thu, 15 Mar 2007, Paolo Bonzini wrote:

> > Because the -1LL will be 0xffffffffffffffff in the tree expression.  Now 
> > the expand_expr call above will turn that tree constant into a RTL 
> > constant, namely (const_int -1 [0xffffffff]), that is correct as far as I 
> > can see, as RTL constants are implicitely sign extended.
> 
> This is actually a special case in convert_modes.  The code looks
> like:

Right, I noticed that, but thought it might have a reason to exist ;-) The 
comment above explains some reasons, and on first thought, they seem 
valid.  You basically have the problem, that when you're faced with 
(const_int -1 [0xffffffff]) (let's say coming from an input 0xffffffff), 
and explicitely request it to be converted into DImode, and want it 
unsigned, then you need to have (const_double [0xffffffff] [0] [0] [0]).

Except if the input (const_int -1 [0xffffffff]) resulted from a 
shortening of 0xffffffffffffffffULL, because then you want
(const_double [0xffffffff] [0xffffffff] [0] [0]), or (const_int -1) again 
:-(

Seems to me like a target conflict.

> Without your patch, oldmode is VOIDmode.  It looks to me like the
> correct thing to do would be not to do the truncate and zero extension
> in this case:
> 
>   if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
>       && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
>       && GET_CODE (x) == CONST_INT && INTVAL (x) < 0
> 
>       /* If oldmode is VOIDmode, all we can do is hope that the
>          constant was indeed signed and thus truncated to a
>          CONST_INT.  In other words, we have to assume that X
>          does not need sign- or zero-extension as we do below.  */
>       && oldmode != VOIDmode)
>     {
>       HOST_WIDE_INT val = INTVAL (x);
>       int width = GET_MODE_BITSIZE (oldmode);
> 
>       /* Test if we need to zero extend the low part too.  */
>       if (width < HOST_BITS_PER_WIDE_INT)
>         val &= ((HOST_WIDE_INT) 1 << width) - 1;
> 
>       return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
>     }

This will probably pessimize code.  The condition below that isn't reached 
in our case:

  if ((GET_CODE (x) == CONST_INT
       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
      || (GET_MODE_CLASS (mode) == MODE_INT
          && GET_MODE_CLASS (oldmode) == MODE_INT
        ...

MODE_BITSIZE(mode) in our case is > HOST_BITS_PER_WIDE_INT, and oldmode is 
VOIDmode (hence not MODE_INT class), so we fall through.  It's also no 
VECTOR_MODE_P, so we reach:

  temp = gen_reg_rtx (mode);
  convert_move (temp, x, unsignedp);
  return temp;

which explicitely goes over a register.

Sigh.


Ciao,
Michael.



More information about the Gcc-patches mailing list