On 1/12/07, Eric Botcazou <ebotcazou@adacore.com> wrote:
> [Sorry for the delay, pretty hot week]
>
> > On a second thought this cannot be true. If you have "all the magic
> > to support atomicity" and generate "the full-word access on" your own --
> > why do you expose the individual fields to the middle-end at all??
>
> Well, the type has fields and you can access these fields individually in the
> source so they must be present in the IL to generate debug info for them.
>
> > I claim you _cannot_ generate full-word access this way (unless
> > using memcpy, but even that is nowadays lowered).
>
> Do not underestimate the cleverness of Gigi. :-)
I don't see anything "clever" in
Q ()
{
typedef q__byte q__byte;
typedef struct q__word q__word;
struct q__word T1b = {.first=0, .second=0, .third=0, .fourth=0};
struct q__word tmp;
struct q__word external = VIEW_CONVERT_EXPR<struct q__word>(SAVE_EXPR <T1b>);
tmp = VIEW_CONVERT_EXPR<struct q__word>(external);
tmp.first = 0;
external = VIEW_CONVERT_EXPR<struct q__word>(tmp);
return;
}
for this testcase (t02.original dump, gcc 4.1.2) . Now if I change the
testcase to something I requested (direct write to a component), I get
Q ()
{
typedef q__byte q__byte;
typedef struct q__word q__word;
struct q__word T1b = {.first=0, .second=0, .third=0, .fourth=0};
struct q__word external = VIEW_CONVERT_EXPR<struct q__word>(SAVE_EXPR <T1b>);
VIEW_CONVERT_EXPR<struct q__word>(external).first = 0;
return;
}
and after gimplification we can see all it broken already (that is, you
exposed the component write to the middle-end - no cleverness
prevented this):
Q ()
{
struct q__word T1b.0;
typedef q__byte q__byte;
typedef struct q__word q__word;
struct q__word T1b;
struct q__word external;
T1b.first = 0;
T1b.second = 0;
T1b.third = 0;
T1b.fourth = 0;
T1b.0 = T1b;
external = T1b.0;
external.first = 0;
return;
}
The testcase now looks like:
procedure Q is
type Byte is mod 2**8;
for Byte'Size use 8;
type Word is
record
First, Second, Third, Fourth : Byte;
end record;
External : Word := (others => 0);
pragma Atomic (External);
begin
External.First := 0;
end;