comp.lang.ada
 help / color / mirror / Atom feed
* Access to fixed memory location
@ 2007-11-30 19:32 Tomas Cernaj
  2007-11-30 21:42 ` Samuel Tardieu
  0 siblings, 1 reply; 5+ messages in thread
From: Tomas Cernaj @ 2007-11-30 19:32 UTC (permalink / raw)


Hello everyone,

is there any way to tell the Ada compiler that an Address attribute 
should be constant? I want to use it for accessing fixed memory 
locations, and without the Address attribute being constant the compiler 
won't optimize away an indirect access.

I couldn't find anything in the RM or GNAT documentation... The point is 
that I want to use the 'Address construct on the AVR target, which is an 
8-bit processor, so the indirect access is quite expensive.

I suppose that was a bit unclear, so here's an example: :)
I have the following declarations in a package spec file:

    type T_Type is array (0 .. 7) of Boolean;
    pragma Pack (T_Type);
    for T_Type'Size use 8;
    
    package TA is new System.Address_To_Access_Conversions (T_Type);
    X : constant access T_Type
        := TA.To_Pointer (System.Storage_Elements.To_Address (50));
    
    Y : T_Type;
    for Y'Address use System.Storage_Elements.To_Address (51);
    pragma Import (Ada, Y);

Note that X is something like a "T_Type * const X" in C.
Compiling the following code

        X (4) := True;
        Y (5) := True;

with GNAT (gcc-4.2 -O -S) yields this assembler output (x86-64):

        orb     $16, 50			; X (4) := True
        movq    testpkg__y(%rip), %rdx	; Y (5) := True
        movzbl  (%rdx), %eax
        orl     $32, %eax
        movb    %al, (%rdx)

That's because the compiler can not assume that Y'Address will not be 
changed.

Thank you for your help,
Tomas



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Access to fixed memory location
  2007-11-30 19:32 Access to fixed memory location Tomas Cernaj
@ 2007-11-30 21:42 ` Samuel Tardieu
  2007-11-30 22:22   ` Samuel Tardieu
  2007-12-02 22:00   ` Tomas Cernaj
  0 siblings, 2 replies; 5+ messages in thread
From: Samuel Tardieu @ 2007-11-30 21:42 UTC (permalink / raw)


>>>>> "Tomas" == Tomas Cernaj <tcernaj.WITHOUTTHIS@gmx.de> writes:

Tomas> That's because the compiler can not assume that Y'Address will
Tomas> not be changed.

Well, no, that's not the reason (Y'Address is obviously static and
constant). This is due to an unfortunate combination of three things:

 a) because of RM13.3(19), no optimization can be done on Y based on
    assumptions of no aliases

 b) to implement this clause, GCC marks the implicitly defined pointer
    type as volatile

 c) when this implicitly defined pointer type is marked as volatile,
    GCC generates code which does read+modify+write here at 3 separate
    operations rather than using an atomic one

I think GNAT is overconservative concerning (b) as I do not think a
volatile behaviour is mandated here, and that (c) could generate a
better code but this is a separate issue from (b).

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Access to fixed memory location
  2007-11-30 21:42 ` Samuel Tardieu
@ 2007-11-30 22:22   ` Samuel Tardieu
  2007-12-02 22:00   ` Tomas Cernaj
  1 sibling, 0 replies; 5+ messages in thread
From: Samuel Tardieu @ 2007-11-30 22:22 UTC (permalink / raw)


>>>>> "Sam" == Samuel Tardieu <sam@rfc1149.net> writes:
>>>>> "Tomas" == Tomas Cernaj <tcernaj.WITHOUTTHIS@gmx.de> writes:

Tomas> That's because the compiler can not assume that Y'Address will
Tomas> not be changed.

Sam> Well, no, that's not the reason (Y'Address is obviously static
Sam> and constant). This is due to an unfortunate combination of three
Sam> things:

Sam>  a) because of RM13.3(19), no optimization can be done on Y based
Sam> on assumptions of no aliases

Sam>  b) to implement this clause, GCC marks the implicitly defined
Sam> pointer type as volatile

Sam>  c) when this implicitly defined pointer type is marked as
Sam> volatile, GCC generates code which does read+modify+write here at
Sam> 3 separate operations rather than using an atomic one

Sam> I think GNAT is overconservative concerning (b) as I do not think
Sam> a volatile behaviour is mandated here, and that (c) could
Sam> generate a better code but this is a separate issue from (b).

I found a discussion about (b) dating from last September which
explains that a lot of Ada code assumes that pragma Volatile is
implicit and cannot be easily changed. So I asked about (c) on the GCC
developers mailing-list, as it may be a missed optimization.

 Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Access to fixed memory location
  2007-11-30 21:42 ` Samuel Tardieu
  2007-11-30 22:22   ` Samuel Tardieu
@ 2007-12-02 22:00   ` Tomas Cernaj
  2007-12-02 23:13     ` Samuel Tardieu
  1 sibling, 1 reply; 5+ messages in thread
From: Tomas Cernaj @ 2007-12-02 22:00 UTC (permalink / raw)


Thank you for your quick response. You've helped me a lot to sort things 
out.

Actually I think there's two problems at hand:

 1) the read/modify/write access

 2) the indirect access

ad 1): As explained by Richard Kenner, the C construct "y |= 32" is by 
definition equivalent to "y = y | 32", so R/M/W is perfectly OK. However, 
writing "Y (5) := True" IMO means that we only want to set the 
corresponding bit, no matter what the rest of the byte/word etc. looks 
like.
I've tried this using a (volatile) bit field in C, and here again gcc 
generates a R/M/W access. (compiler problem...?)

ad 2): I'm not quite sure if I've understood the concept of aliased types 
you mentioned in (a)... :-|
Anyways, I modified the example in my first post to include "pragma 
Volatile (T_Type);". Here's what gcc generates:

        movzbl  50, %eax		; X (4) := True
        orl     $16, %eax
        movb    %al, 50
        movq    testpkg__y(%rip), %rdx	; Y (5) := True
        movzbl  (%rdx), %eax
        orl     $32, %eax
        movb    %al, (%rdx)

So X is accessed directly while Y is accessed indirectly. That's why I 
thought it had something to do with Y'Address not being constant... (I 
mean that whenever one uses the package where Y is declared one can still 
change the value of Y'Address). 

Am I missing a point?

Thanks,
Tomas



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Access to fixed memory location
  2007-12-02 22:00   ` Tomas Cernaj
@ 2007-12-02 23:13     ` Samuel Tardieu
  0 siblings, 0 replies; 5+ messages in thread
From: Samuel Tardieu @ 2007-12-02 23:13 UTC (permalink / raw)


>>>>> "Tomas" == Tomas Cernaj <tcernaj.WITHOUTTHIS@gmx.de> writes:

Tomas> So X is accessed directly while Y is accessed
Tomas> indirectly. That's why I thought it had something to do with
Tomas> Y'Address not being constant... (I mean that whenever one uses
Tomas> the package where Y is declared one can still change the value
Tomas> of Y'Address).

Tomas> Am I missing a point?

Yes: the fact that nobody else can change the value of Y'Address :)

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-12-02 23:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-30 19:32 Access to fixed memory location Tomas Cernaj
2007-11-30 21:42 ` Samuel Tardieu
2007-11-30 22:22   ` Samuel Tardieu
2007-12-02 22:00   ` Tomas Cernaj
2007-12-02 23:13     ` Samuel Tardieu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox