This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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.