On 11/11/2010 10:26, Georg Johann Lay wrote:
David Brown schrieb:
On 09/11/10 18:45, Georg Lay wrote:
David Brown schrieb:
...
May I say I think it's great that you are looking into this?  Program
space access on the AVR was the first thing I thought of when I heard of
the concept of named address spaces in C.

It's great work that this is part of gcc now! Just remember all the
hacks to get near/far support into a C16x target.

Besides access and pointer size, maybe even thinks like

int __far __atomic x;


"__far" as a memory space makes sense.  It may even make sense to have
three extra spaces so that (along with __pgm) you can use all the flash
space in an Mega256, if that is easier or more efficient than using
24-bit pointers to flash.

I don't think "__atomic" is appropriate for a memory space, however.  I
don't know if you've read Linus Torvald's rant against "volatile", but
his point applies here too.  Variables cannot be volatile or atomic in
themselves - it is /accesses/ that are volatile or atomic (declaring a
variable to be "volatile" is simply a shorthand for saying that all
accesses to it should be volatile).

While volatile accesses are fairly cheap, and not /too/ hard to
understand (though many people misunderstand them), atomic accesses are
expensive (since they involve disabling interrupts) and hard to
understand.  Supposing "ax" and "ay" are declared as "int __atomic ax,
ay".  Should the statement "ax += 2" be atomic?  Should "ax = ay"?  I
think it is better to stick to the macros in<util/atomic.h>  - they are
clear and explicit.  An alternative would be to implement the gcc atomic
builtins, since these are also explicit.

The issue with avr is that neither int nor void* is atomic. If there
is a situation line a->b->c->d and one access has to be atomic, it
helps to keep the source clear an reduce overhead because just one (or
maybe more than one) access needs to be atomic. Things like __atomic
should refer to native types that the back end supports. __atomic DI
on avr might be not appropriate and the BE could complain. Same applie
to composites. If a composite has to be treated atomically as a whole,
util/atomic.h is the tool of choice. __atomic just adds an other tool
to your toolbox, and as so often in C, you must know what you are
doing or it will bit you sooner or later, i.e. same as with volatile,
signed overflow, strict aliasing, etc.

And of course, overhead of atomic must be taken into account and be
balanced with other approaches. Disabling interrupts is not a good
thing in an OS, maybe in one with hard real time constraints (with
hard as in *HARD*).

But don't let us stick at __atomic. Was just brainstorming about what
named address spaces (NAS) are capable to do or could be capable to do.

Imagine a __track, that could help in getting finer grained profiling
info in a context where you do /not/ have (potentially) unlimited
resources like embedded systems, or where you want to bring profiling
info closer to the setup, in which the software finally is intended to
run. Again, hard realtime is a good example.


I'd imagine there is lots that could be done with named address spaces. For example, on some targets you have smaller or faster code when addressing particular areas of memory - perhaps because it is internal tightly-coupled ram, or because you have smaller addressing modes (on the 68k, for example, there is a 16-bit signed absolute addressing mode. On the AVR, there is Y+q). These would be natural fits for named address spaces.


Is there any way to add named address spaces at usage time (i.e., compile time for the target code rather than compile time for gcc)? For example, would it be possible to make artificial generic address spaces __space1, __space2, etc., which caused calls to hook functions when data was loaded or stored to the variable. The hook functions could be initially defined with weak linkage and overridden by user code. This would allow the user to implement __track, __bigendian, __eeprom, or whatever by writing their own hook functions and #define'ing __track as __space1.

Obviously hook functions would mean some overhead, due to the function call. But if users found a particular memory space to be useful, then it could always be moved into the compiler later. It is also possible that LTO could be used to eliminate the overhead (does LTO work on the AVR port?).



Contemplating NAS in a more general context as being some kind of
(target specific) qualifier that helps to implement named address spaces.

Looking at NAS from the "named address space" perspective, I can
understand the warnings and the concretization (don't know the word,
  other direction like "abstraction") of what a "subset of" means.

Looking at NAS from the qualifier's perspective, the warnings are
quite confusing, because qualifiers are not mutually exclusive. So
there could be a mask of what qualifiers are on instead of an enum
passed in TARGET_ADDR_SPACE_SUBSET_P and the target can decide what
combination is legal, what warning is appropriate, or if it feels
comfortable with standard setup.

However, at present avr backend badly needs avr developers. It's not a
good idea to build such enhancements atop of all the PRs there...


I agree with that - prioritising is important.  But it is also good to
move forward with new features.

Of course, if you are feeling enthusiastic the next step would be an
__eeprom memory space that worked efficiently on all AVRs...

hmmm, once thought about it. There is an erratum for some AVR with
that (indirect access against direct). To work around that in gcc, gcc
needs to have some knowledge. Moreover (not to familiar with that, the
erratum occured because avr-libc made some implication on how gcc will
inline functions, so that an indirect access finally collapses to a
direct one. As I am sill using avr-gcc-3.4.6 which runs pretty smooth
and the compiler has hot the knowledge, I didn't think about it
further) accessing eeprom is not as easy as accessing flash. Perhaps
some new eeprom- or SFR-relocs could help to shift the information
from avr-gcc to avr-binutils.



Reply via email to