[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] using exceptions

From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] using exceptions
Date: Thu, 03 May 2012 10:33:44 +0200
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

Gabriel Dos Reis schrieb:
Georg-Johann Lay wrote:
Gabriel Dos Reis wrote:

I guess I would need to get my feet wet with
1. minimal free-standing  C++ implementations without exceptions
2. get support for RTTI (without exceptions)
3. exceptions (assuming 1 and 2 are done successfully)

Regarding 2., I would like to understand the general policy:  RTTI data are
generally const and should be best stored in read only location.  What is
the general preference for AVR?  Put read only data in program memory or
data segment?  Apologies for the triviality but the recent discussion about
__func__ got me thinking.

The preferred place is program memory, i.e. flash, i.e. something like
.progmem section.

Read-only data is located in .rodata which is located in RAM.

This is because const qualifier is not enough to put data in flash,
just assume:

char bar (const char *p)
  return *p;

char foo (char *p)
  char c = bar (p);
  *p = 0;
  return c;

bar() must not read from flash.

Yes, "const" qualifier on *parameters* is not enough.
However "const" qualifier on *objects* should be enough.
(and for C++, we now have "constexpr" to statically
guarantee that)

That's not enough.

The reason is that it's completely legal in C to access a
non-const object through a const-qualified pointer as
lined out in bar being called by foo above.

I think this is okay for C++, too?

The only safe setting where an object O may be put into
flash without the user explicitely requesting it are:

A) *All* use sites of the object are known and they
never change O.

B) There is no section attribute attached to O.

Besides that, we need

C) The compiler supplies us with this knowledge *and*
allows us to hook in in oder to produce appropriate
code to locate the object and access it appropriately,
e.g. to quality *all* involved pointers targeting the
object appropriately.

Notice I use "object" in the weak meaning as "something",
i.e. "object" may also be a string literal or vtable.

A, B and C are currently only satisfied for one single
place in avr-gcc, namely casesi insn:

A is true because because the BE emits code for casesi
and is able to locate the table, see TARGET_ASM_FUNCTION_RODATA_SECTION.
This might break C++ if it uses .gnu.linkonce.r. in
unknown ways.

There are several other places that satisfy A and B, but
C does not hold:

i) Lookp tables resulting from tree-switch-conversion, see PR49857.
ii) vtables
iii) rtti tables

The difference between i) and ii), iii) is that putting tables in
flash for i) is not an ABI change whereas ii) and iii) are:

Suppose you compile a file that generates respective tables and link
against objects generated by an older compiler version.

In that case the assertion would be that the use site may escape the
scope, but the out-of-scope places are just as well administered by
compiler code and not by user code. Thus, the assertion is that the
handling of the compiler is the same over all modules involved, which
means a new ABI. Except v/rtti-tables are only present in exactly
one module and only accessed from there, of course. I don't new enough
of C++ for this, but in that case the change would just be an
optimization and not an ABI change, similar to i) and casesi.

From the compiler's analysis capabilitied, I'd guess A is satisfied
for way more cases, e.g. static consts. The compiler knows if
references escape scope, for example by taking address of such object
and return or pass it.

The issue is not locating the data, it's accessing the data with the right
instructions, i.e. LPM* for data in flash and LD* and ST* for data in RAM.

yes; I agree.  My question though was whether there was a general
policy about where to put things we know are never going to change
in program memory because of RAM being so scarce.

Similar issues as with rtti arise with vtables, see PR43745.

A, B anc C mentioned above.

GCC offers TARGET_VTABLE_USES_DESCRIPTORS, but it appears to be
very specific, and the vtable hooks don't appear to be generic
enough as to tell "use this kond of pointer to access that".

FYI, notice that avr does not implement TARGET_PTRMEMFUNC_VBIT_LOCATION
and instead sets FUNCTION_BOUNDARY to 8. The last setting is
confusing if you miss TARGET_PTRMEMFUNC_VBIT_LOCATION is undefined
because the right setting for FUNCTION_BOUNDARY is 16.

RAM is a very scarce resource on AVRs, but with current GCC it is not
possible to place+access rtti/vtable data in flash.

The right feature would be something like an internal, "artificial"
address space to qualify/locate respective pointers/data.
This should be easier than adding named address spaces as full-featured
C++ extension.

Agreed.  I will talk to Jason to see what can be done here.

IMO, the implementation of address spaces in GCC is bit myopic.
AS are just a kind of target specific qualifiers. While AS
qualifiers are mutually exclusive, "ordinary" qualifiers are not.

I wonder why there is nothing like target specific qualifiers in GCC
where the target decised what compination of whalifiers is legal or
worth an error or warning and how they transform with pointer mess.

One reason might be limited space for TYPE_QUALS? Dunno...

However, I'd guess that none of the code to handle address spaces is present
in C++ part and/or FE as named addresses are not a G++ feature, so there
is no need to have named address code in C++ (or other languages' parts)
in the compiler.

Agreed.  I would like to refrain from full fledged named address spaces in the
C++ front-end until the WG21 committee got a clear direction.  On the other
hand something like the one you describes above should suffice.

You got contact to the WG?

IMO there are some migging spots in the AS specification, for example in
code like

const __flash char *str = "literal"

This is not allowed in current spec as C/C++ standard is too dominant,
there is a "string literals are always generic" or similar and the
AS spec does not cover it.

In the example above, the /only/ way to access the literal is through
str which points to flash. Thus, the canonical and only reasonable
place to put the literal is __flash address space.

This has been overseen by the WG, obvioulsy the spec was writte for
some different architecture in mind.

Attaching obvious semantics to the line above or making it
implementation defined and let the backend decide would make
it much easier to port code

const char *str = "literal";

from big flatform to

const __flash char *str = "literal";

Instead of rewriting to

const __flash char dummy[] = "literal";
const __flash char *str = dummy;

in particular with more elaborate initializers that contain
string literals.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]