This is the mail archive of the gcc@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: Volatile operations and PRE


Ricardo FERNANDEZ PASCUAL writes:
 > Andrew Haley wrote:
 > 
 > >Ricardo FERNANDEZ PASCUAL writes:
 > > > So, I think the real question is: are COMPONENT_REF nodes allowed
 > > > to be marked as volatile by themselves? I think they should, and
 > > > actually it seems to work (the generated code looks correct).
 > >
 > >volatile is a type qualifier.  The type of a COMPONENT_REF is the type
 > >of the operand to which it refers.  If you want to change the
 > >effective type of a reference, you should generate a suitable
 > >CONVERT_EXPR.  Like this:
 > >
 > >  tree exp_type = TREE_TYPE (exp);
 > >  tree v_type 
 > >    = build_qualified_type (exp_type,
 > >			    TYPE_QUALS (exp_type) | TYPE_QUAL_VOLATILE);
 > >  tree addr = build_fold_addr_expr (exp);
 > >  v_type = build_pointer_type (v_type);
 > >  addr = fold_convert (v_type, addr);
 > >  exp = build_fold_indirect_ref (addr);
 > >  
 > >
 > Thank you. I have tried this and it works for stores, but not for loads 
 > (for loads it behaves as a non volatile load).
 > 
 > I have done some experiments to try to understand what is happening, and 
 > I am a bit confused by the bahavior of GCC. Consider the following C 
 > function:
 > 
 > static struct { int w; } s;
 > 
 > void wait (void) {
 >   int t;
 > loop:
 >   t = *((volatile int *) &s.w);
 >   if (t > 0) goto loop;
 > }
 > 
 > 
 > The code generated by "cc1 -O3" on x86 is:
 > 
 > wait:
 >         movl    s, %eax
 >         pushl   %ebp
 >         movl    %esp, %ebp
 >         testl   %eax, %eax
 >         jg      .L6
 >         popl    %ebp
 >         ret
 > .L3:
 > .L6:
 >         jmp     .L6
 > 
 > 
 > Which does not seem to respect the semantics of volatile. Is this the 
 > expected behavior or is this a bug?

I think it's a bug.  The gimple is:

wait ()
{
  int t;
  void loop = <<< error >>>;

  loop:;
  t = s.w;
  if (t > 0)
    {
      goto loop;
    }
  else
    {
      
    }
}

Whereas for this:

 > FWIW, the folowing function:
 > 
 > void wait2 (void) {
 >   int t;
 >   volatile int *p = &s.w;
 > loop:
 >   t = *p;
 >   if (t > 0) goto loop;
 > }

the gimple is:

wait2 ()
{
  int t;
  volatile int * p;
  void loop = <<< error >>>;

  p = (volatile int *) &s.w;
  loop:;
  t = *p;
  if (t > 0)
    {
      goto loop;
    }
  else
    {
      
    }
}

which looks right.  A temporary shouldn't make any difference here.

At a wild guess, maybe strip_useless_type_conversions() is doing
something Bad.

Andrew.


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