This is the mail archive of the gcc-patches@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: [PATCH] Tree SRA and atomicity/volatility


On 1/12/07, Richard Guenther <richard.guenther@gmail.com> wrote:
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;


Oh, and of course wrong (?) assembly is created for this:


_ada_q:
.LFB3:
       pushl   %ebp
.LCFI0:
       movl    %esp, %ebp
.LCFI1:
       subl    $16, %esp
.LCFI2:
       movl    $0, -4(%ebp)
       movb    $0, -4(%ebp)
       leave
       ret

Richard.


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