Volatile operations and PRE
Ricardo FERNANDEZ PASCUAL
ricardo.fernandez@st.com
Tue Nov 7 16:33:00 GMT 2006
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?
FWIW, the folowing function:
void wait2 (void) {
int t;
volatile int *p = &s.w;
loop:
t = *p;
if (t > 0) goto loop;
}
generates the following code, which seems correct to me:
wait2:
pushl %ebp
movl %esp, %ebp
.p2align 4,,7
.L9:
movl s, %eax
testl %eax, %eax
jg .L9
popl %ebp
ret
Thanks in advance for any help.
Best regards,
Ricardo.
More information about the Gcc
mailing list