EmbeddedRelated.com
Forums

Code execution Speed (Rowley vs CC)

Started by Richard May 25, 2008
Consider a function foo

void foo (void)
{
volatile int ix;

/* some code using ix */
}

is it wrong for the compiler to use a register in this context? The
first ANSI standard says "the purpose of volatile is to force an
implementation to suppress optimization that could otherwise occur".
The standard does not stipulate what resources are to be used or not
used in an implementation for automatic variables simply that they
exist for the duration of the block within which they are declared. It
is far from saying don't make assumptions but rather is actually
directing an implementer very carefully. I therefore move that an
automatic variable declared volatile could use a register and conform
to the standard.

I am not sure what the jump table reference is to, but in K&R or ANSI
C, it is a simple task to create an array of pointers to functions.
The control of the placement of that table, if placed in a ROM, is
usually a link time operation. A tool chain supplier usually provides
a suitable section placement scheme. It is also a fairly simple task
to create such a table dynamically.
On 28-May-08, at 5:23 PM, John Heenan wrote:

> This is about as black and white as it can get with regard to
> interpreting a standard which attempts to deal with the 'unknown'.
>
> Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
> qualifiers' states "An object that has volatile-qualified type may be
> modified in ways unknown to the implementation or have other unknown
> side effects."
>
> In simpler terms this tells a compiler DO NOT MAKE ANY ASSUMPTIONS. I
> don't think I need to SPELL OUT why assigning ANY volatile declared
> object to a register is certainly making assumptions about usage of
> the variable.
>
> Point proven. The naive go off thinking every other compiler is
> inferior because using registers shortens code and improves
> benchmarks.
>
> With regard to 'jump tables'. Both CCE and IAR provide KNOWN ways to
> generate jump tables. On enquiry Rowley was dismissive. If there was
> a way of generating jump tables they weren't going to tell us. Rather
> odd given that the MSP430 has some interrupt facilities that are
> ideally suited to jump table use, aside from the enormous general
> benefits of jump tables.
>
> I did notice that a listing of ARM assembly code from C from the OPEN
> SOURCE compiler USED by Rowley, that was posted on another group, did
> produce a jump table. I was impressed and said this on the group.
>
> Despite this don't think projects can be easily ported. Normal ARM
> GCC linker command files are generated by Rowley only as long as they
> are needed and then deleted.
>
> There have been public comments about not been able to identify any
> contributions made from Rowley to the development of the open source
> compiler used by them. The cutting edge contributions, at the time,
> were coming from www.opensourcery.com, which were well ahead of the
> stultifying, politicised and bureaucratic snails pace the open source
> GCC movement was working at.
>
> Make up your own minds about what is doing on.
>
> John Heenan
>
> --- In m..., "Paul Curtis" wrote:
> >
> > John,
> >
> > > From a factual perspective what has emerged is that Rowley
> appears to
> > > use registers for variables that are declared volatile. While this
> > > will help benchmarks, personally I find it bizarre. There is a
> good
> > > argument this violates the C standard.
> >
> > And that argument is, of course, not presented. Your modus
> operandi is to
> > present something without any research or fact, just gut instinct
> (viz
> > "CrossWorks doesn't generate jump tabes" and "CCE uses GCC as its
> > compiler").
> >
> > So, I'm looking for a direct reference to the ISO C standard which
> gives
> > substance to your argument and clearly demonstrates that CrossWorks
> violates
> > the standard in this instance.
> >
> > Can do you that for us, John?
> >
> > --
> > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>

Beginning Microcontrollers with the MSP430

These are the facts. Instead of bullying and projecting prejudices,
is it too much effort to bother to check what was ACTAULLY said and
avoid making assumptions.

1. I replied appropriately to a post with poor quality information
which did not mention the word 'volatile'.
2. I got vicously and inappropriatley attacked by a bully who
deliberately distorted context
3. Another bully opportunistically followed up with a stupid attack
who altered facts.
4. The second bully continued to alter facts after been corrected.
5. Now we have a third bully excusing other bullies.

How dare I have the nerve to defend myself.

John Heenan

--- In m..., Jon Kirwan wrote:
>
> On Wed, 28 May 2008 03:31:56 -0000, John wrote:
>
> >What a sick joke. Even the quote below to supposedly establish
> >context is contextually misleading. It is by no means the original
> >post. Even the quote establishes that the poster was replying to
> >something I posted before.
>
> I think the gist is that Richard indicated (not in his first post on
> the subject, but in one that was responding to your early post to
him)
> he was using the volatile keyword. His comment was, "Yes, the loop
> variables are all decl[a]red volatile and are not being optimized
> away." Richard, so far as I know, was already fully aware of the
need
> for volatile _before_ making his first post (on the subject of speed
> differences between CC and Rowley in the specific case of speed
> optimation and the code fragment Richard was discussing then.)
> Microbit said as much to you, writing, "Richard, the OP, enunciated
> that he WAS using volatile qualifiers, so the last squirm
of 'missing
> context' is rather futile IMO." Microbit was correct in that
comment,
> whether or not it was because of Richard's first post or a later
one,
> and didn't deserve the "bullying sickos" comment you made, which is
> beginning to seem more a matter of psychological projection than
> anything else.
>
> >From a factual perspective what has emerged is that Rowley appears
to
> >use registers for variables that are declared volatile. While this
> >will help benchmarks, personally I find it bizarre. There is a
good
> >argument this violates the C standard.
>
> I'm no expert on C standards, just a sometimes interested reader of
> them. But you should consider citing specifics from the relevant
C90
> or C99 standards documents or else we may be left guessing that you
> mean to suggest from the above that "bizarre to John" == "violates
the
> C standard," an idea to which I think many of us may take some
modest
> exception -- let alone those responsible to actually write and
> maintain c compilers.
>
> Perhaps you didn't mean to write things exactly as you did above,
but
> you seem to be thinking (I can't speak for you, but it could be read
> this way) that Rowley __always__ uses registers for volatile
> variables. I don't think that is the case. The use of R15 in the
> sample code that Richard posted for comparison purposes was a matter
> of the specific DAG and basic block representations and then various
> transformations applied, followed by other optimization steps.
> Compilers are generally free to emit code that are semantically
equal,
> given the language specifications about that subject. Some
compilers
> will emit code that is "better" than others on various scales of
> measure and they are also free to make topological transformations
and
> variable assignments that do not break semantic equality.
>
> Placing an instance or parameter variable into a register instead of
> placing it on a stack is generally (for c, anyway) a matter of
> compiler choice.... so long as the instance values act as the
language
> says they should act. The use of R15 instead of 2(SP) isn't a
matter
> a c coder can specify. For whatever good or bad that may mean, this
> detail of implementation is left to the compiler implementor.
>
> You are permitted to suggest a register be used through the use of
the
> 'register' keyword, but even then the compiler isn't required to
obey
> you. It's just a hint which the compiler may ignore or use, not an
> order that must be obeyed. And there is no means by which you can
> inform the compiler that it should _not_ use a register for a
> parameter or instance variable (auto). That is not specifiable by
a c
> programmer, either by implication or explicit syntax.
>
> I would suppose that the key argument you might make would be in
> regard to the required _number_ of references/assignments or else by
> discussing the _order_ in which these take place. But that wouldn't
> be about whether or not a register was used.
>
> Let's bring back Richard's post on the assembly generated by the two
> compilers for { volatile int j; for( j= 0; j<1050; j++ ) ; }. But
> let's rephrase the code slightly:
>
> #define N (1050)
> {
> volatile int j;
> for( j= 0; j < N; j++ )
> ;
> }
>
> This breaks down to:
> j= 0; /* sequence pt .. assignment to 'j' must take place */
> x:
> if ( j < N ) /* sequence pt .. read of 'j' must take place */
> j++; /* additional read of 'j', one assignment to 'j' */
> goto x;
>
> I'm not positive of my interpretation of 'volatile' and sequence
> points here and I'm very much open to being corrected. But I read
the
> above as requiring, assuming that 'j' isn't modified by some
external
> event (which we are assuming here it is not):
>
> 1 assignment to 'j' due to 'j= 0'
> 1 read of 'j' due to first execution of condition
> N alternated reads of and assignments to 'j' due to 'j++'
> N reads of 'j' due to repeated execution of condition
>
> Thus, given that 'j' starts out as 0 and that N is positive or zero:
>
> N+1 assignments to 'j'
> 2N+1 reads of 'j'
>
> And this sequence of events:
>
> write 'j'
> read 'j'
> N*[ read 'j', write 'j', read 'j' ]
>
> I believe that in the case of a volatile object like 'j', the last
> store to it doesn't have to be included if there is no further read
> taking place in the block. But that doesn't apply to the above case
> as the conditional guarantees that there must always be a read
of 'j'
> as the last step. Also, the ordering must be preserved, as
indicated.
>
> This code was posted by Richard:
>
> Code Composer:
> -------------------------
> mov #0, 2(SP)
> cmp #1050, 2(SP)
> jc L002
> L001: inc 2(SP)
> cmp #1050, 2(SP)
> jnc L001
> L002:
>
> Note that in the above case the variable 'j' is allocated on the
local
> activation record (stack frame) and that a separate frame pointer
> isn't being used, instead just relying upon the "known" position of
SP
> relative to the local variable for the given code fragment's
instance
> of execution. In other words, SP is pointing just past the local
> variable and the code generator knows it.
>
> I believe CC's code conforms. It performs N+1 assignments and 2N+1
> reads and in the correct ordering.
>
> Rowley:
> -------------------------
> mov #0, R15
> L001: add #1, R15
> cmp #1050, R15
> jnc L001
>
> In this case, R15 has been assigned to variable 'j', instead of a
> stack location. That in itself isn't a problem. However, the
> optimized code insists that N be at least 1 instead of at least 0
> (okay, I suppose, given that it knows that N is greater than 0) and
> performs N+1 assignments to 'j' and 2*N reads of 'j' ... which may
be
> off by one.
>
> The sequence of events for Rowley's code seems to be (assuming N is
> greater than 0, of course):
>
> write 'j'
> read 'j'
> write 'j'
> read 'j'
> (N-1)*[ read 'j', write 'j', read 'j' ]
>
> It may be possible to argue here that the required references and
> ordering has not been preserved as required by the standard. I
> haven't cited specifics, though, because my copy of the
specification
> leaves much to be desired in terms of interpretation here and it may
> be better to let those who know the details well make the citations
in
> response to the above point.
>
> But I can see a possible argument on this narrow ledge from my
> neophyte understanding of the specifications I've read. (Note
nothing
> about the use of registers here.)
>
> Jon
>

--- In m..., Veronica Merryfield
wrote:
>
> Consider a function foo
>
> void foo (void)
> {
> volatile int ix;
>
> /* some code using ix */
> }
>
> is it wrong for the compiler to use a register in this context?
> The
> first ANSI standard says "the purpose of volatile is to force an
> implementation to suppress optimization that could otherwise
> occur".

The standard has changed, probably for very good reason. According to
the CURRENT ISO C standard, you have told the compiler that ix may be
modified in ways unknown or have other unknown side effects.

The context you assume is not relevant since you have just told the
compiler not to assume any context by using the type qualifier
volatile.

You have not specified what 'some code using ix' is.

Since the current standard states ix MAY BE modified in ways unknown
then a compiler writer MUST ALLOW ix to be modified in ways unknown.
The simplest way to modify in ways unknown is to force ix to use RAM,
such as in a stack frame with a known order of use, which can be
determined in some compilers quite easily.

Suppose an interrupt gets called and ix is using a register. Then ix
gets destroyed for the duration of the interrupt call. The fact that
ix is restored does not count. While the interrupt is in action the
programmer must look elsewhere in a LESS PORTABLE way for what ix is
from where it has been saved.

It is an incredibly arrogant assumption for a compiler writer to
assume they can infer context, particularly when the compiler has
been told not to assume anything.

The simplest side effect I can think of is the time taken to execute
an instruction with ix.

What if 'some code using ix' includes assembler code to manipulate
the stack frame?

I am not going to make an argument that it is impossible to use or
modify ix if ix is in a register (even when saved to a stack during
the course of an interrupt). That is not the point. The assumption
that it is OK for a compiler writer to depart from general industry
expectations about what volatile does and what a programmer expects
to be able to do, in a portable fashion, with a variable declared
volatile, is a violation of community expectations. Community
expectations must be considered one of the 'unknowns' from a
standards perspective.

Thinking legalistically about what a standard means with regard
to 'unknowns', outside community expectations, is frankly flawed.

John Heenan
> The standard does not stipulate what resources are to be used or
not
> used in an implementation for automatic variables simply that they
> exist for the duration of the block within which they are declared.
It
> is far from saying don't make assumptions but rather is actually
> directing an implementer very carefully. I therefore move that an
> automatic variable declared volatile could use a register and
conform
> to the standard.
>
> I am not sure what the jump table reference is to, but in K&R or
ANSI
> C, it is a simple task to create an array of pointers to
functions.
> The control of the placement of that table, if placed in a ROM, is
> usually a link time operation. A tool chain supplier usually
provides
> a suitable section placement scheme. It is also a fairly simple
task
> to create such a table dynamically.
> On 28-May-08, at 5:23 PM, John Heenan wrote:
>
> > This is about as black and white as it can get with regard to
> > interpreting a standard which attempts to deal with the 'unknown'.
> >
> > Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
> > qualifiers' states "An object that has volatile-qualified type
may be
> > modified in ways unknown to the implementation or have other
unknown
> > side effects."
> >
> > In simpler terms this tells a compiler DO NOT MAKE ANY
ASSUMPTIONS. I
> > don't think I need to SPELL OUT why assigning ANY volatile
declared
> > object to a register is certainly making assumptions about usage
of
> > the variable.
> >
> > Point proven. The naive go off thinking every other compiler is
> > inferior because using registers shortens code and improves
> > benchmarks.
> >
> > With regard to 'jump tables'. Both CCE and IAR provide KNOWN ways
to
> > generate jump tables. On enquiry Rowley was dismissive. If there
was
> > a way of generating jump tables they weren't going to tell us.
Rather
> > odd given that the MSP430 has some interrupt facilities that are
> > ideally suited to jump table use, aside from the enormous general
> > benefits of jump tables.
> >
> > I did notice that a listing of ARM assembly code from C from the
OPEN
> > SOURCE compiler USED by Rowley, that was posted on another group,
did
> > produce a jump table. I was impressed and said this on the group.
> >
> > Despite this don't think projects can be easily ported. Normal ARM
> > GCC linker command files are generated by Rowley only as long as
they
> > are needed and then deleted.
> >
> > There have been public comments about not been able to identify
any
> > contributions made from Rowley to the development of the open
source
> > compiler used by them. The cutting edge contributions, at the
time,
> > were coming from www.opensourcery.com, which were well ahead of
the
> > stultifying, politicised and bureaucratic snails pace the open
source
> > GCC movement was working at.
> >
> > Make up your own minds about what is doing on.
> >
> > John Heenan
> >
> > --- In m..., "Paul Curtis" wrote:
> > >
> > > John,
> > >
> > > > From a factual perspective what has emerged is that Rowley
> > appears to
> > > > use registers for variables that are declared volatile. While
this
> > > > will help benchmarks, personally I find it bizarre. There is a
> > good
> > > > argument this violates the C standard.
> > >
> > > And that argument is, of course, not presented. Your modus
> > operandi is to
> > > present something without any research or fact, just gut
instinct
> > (viz
> > > "CrossWorks doesn't generate jump tabes" and "CCE uses GCC as
its
> > > compiler").
> > >
> > > So, I'm looking for a direct reference to the ISO C standard
which
> > gives
> > > substance to your argument and clearly demonstrates that
CrossWorks
> > violates
> > > the standard in this instance.
> > >
> > > Can do you that for us, John?
> > >
> > > --
> > > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3
processors
> > >
> >
> >
> >
>

On Thu, 29 May 2008 01:16:40 -0000, John wrote:

>
>5. Now we have a third bully excusing other bullies.

So someone who doesn't find your earlier argument persuasive (nor your
current one referencing section 6.7.3), but who struggles to see if
there might be another way to agree in the broadest way is to be said
to be bullying you?

You make me chuckle.

Jon

Sorry if I misinterpreted you. Next time leave the amateurish bullying
psychology out if you expect a polite rerpsonse.

John heenan

--- In m..., Jon Kirwan wrote:
>
> On Thu, 29 May 2008 01:16:40 -0000, John wrote:
>
> >
> >5. Now we have a third bully excusing other bullies.
>
> So someone who doesn't find your earlier argument persuasive (nor your
> current one referencing section 6.7.3), but who struggles to see if
> there might be another way to agree in the broadest way is to be said
> to be bullying you?
>
> You make me chuckle.
>
> Jon
>

On Thu, 29 May 2008 00:23:47 -0000, John wrote:

>Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
>qualifiers' states "An object that has volatile-qualified type may be
>modified in ways unknown to the implementation or have other unknown
>side effects."
>
>In simpler terms this tells a compiler DO NOT MAKE ANY ASSUMPTIONS. I
>don't think I need to SPELL OUT why assigning ANY volatile declared
>object to a register is certainly making assumptions about usage of
>the variable.

I don't find your argument's logic either valid or otherwise
persuasive. Compilers are free to change automatic variables to
register if their addresses aren't taken, so far as I'm aware.

Jon

On Thu, 29 May 2008 03:48:24 -0000, John wrote:

>Sorry if I misinterpreted you. Next time leave the amateurish bullying
>psychology out if you expect a polite rerpsonse.
>
>John heenan

I will be glad to respond in kind. I started out without name calling
and you responded poorly to it. A prod towards better behavior on
your part is well-reasoned under those circumstances. I'd recommend
you take your own above advice.

Jon

>--- In m..., Jon Kirwan wrote:
>>
>> On Thu, 29 May 2008 01:16:40 -0000, John wrote:
>>
>> >
>> >5. Now we have a third bully excusing other bullies.
>>
>> So someone who doesn't find your earlier argument persuasive (nor your
>> current one referencing section 6.7.3), but who struggles to see if
>> there might be another way to agree in the broadest way is to be said
>> to be bullying you?
>>
>> You make me chuckle.
>>
>> Jon
>
Hello John,

You certainly do present some interesting ideas with respect to the
handling of volatile.

In my opinion, the most important thing about volatile is that it
requires every use and every definition of the variable to be kept
intact, and immune from common sub-expression elimination, dead code
elimination and so on. This is obviously essential if the variable is
going to be updated asynchronously by an interrupt routine or if the
variable is bound, by some convoluted pragma for instance, to a device
control register, which may change the state of the device each time it
is read or written.

If a local variable is declared without using the keywords auto, static,
or register, then I can see no reason why the variable should not be
kept in a register, since the semantics of C do not allow the
modification of such a variable by anything external to the scope in
which it is declared.

You did make the interesting point the saving/restoring of a local
volatile variable in a register by an interrupt or even by a callee
would introduce an unwanted use and definition, beyond the programmer's
control. However, in practice, this is perfectly safe thing to do, if
the local volatile variable is in a general purpose register. However,
if the variable were bound, by some pragma say, to a control register,
then obviously you would not want the compiler messing about with the
register. In that case, since device control registers tend to actually
be global resources, such registers would be excluded from the register
save/restore code generated by the compiler on entry/exit to/from an
interrupt/function.

All the best,

Preston Gurd
(the AQ430 C compiler guy)

P.S. the AQ430 C compiler also puts local volatile variables, declared
without register, static, or auto, into registers, so in your sense it
is as guilty as the Rowley compiler!

John Heenan wrote:
> This is about as black and white as it can get with regard to
> interpreting a standard which attempts to deal with the 'unknown'.
>
> Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
> qualifiers' states "An object that has volatile-qualified type may be
> modified in ways unknown to the implementation or have other unknown
> side effects."
>
> In simpler terms this tells a compiler DO NOT MAKE ANY ASSUMPTIONS. I
> don't think I need to SPELL OUT why assigning ANY volatile declared
> object to a register is certainly making assumptions about usage of
> the variable.
>
> Point proven. The naive go off thinking every other compiler is
> inferior because using registers shortens code and improves
> benchmarks.
>

The context I was referring to was that ix is an automatic variable
and within a function.

It is extremely unlikely that an automatic variable would really be
volatile. If a compiler conforms to an EABI that says that automatic
variables use registers first, why would volatile change that.
Similarly, if a compiler implementation can choose to use register
variables as it sees fit, why should volatile change that. If volatile
means that the object may be modified in ways unknown still does not
preclude register use.

However, I do agree that using a register for a volatile is unusual
and would be 'interesting' to implement but it can still satisfy the
requirements of the standard.
On 28-May-08, at 7:48 PM, John Heenan wrote:

> --- In m..., Veronica Merryfield
> wrote:
> >
> > Consider a function foo
> >
> > void foo (void)
> > {
> > volatile int ix;
> >
> > /* some code using ix */
> > }
> >
> > is it wrong for the compiler to use a register in this context?
> > The
> > first ANSI standard says "the purpose of volatile is to force an
> > implementation to suppress optimization that could otherwise
> > occur".
>
> The standard has changed, probably for very good reason. According to
> the CURRENT ISO C standard, you have told the compiler that ix may be
> modified in ways unknown or have other unknown side effects.
>
> The context you assume is not relevant since you have just told the
> compiler not to assume any context by using the type qualifier
> volatile.
>
> You have not specified what 'some code using ix' is.
>
> Since the current standard states ix MAY BE modified in ways unknown
> then a compiler writer MUST ALLOW ix to be modified in ways unknown.
> The simplest way to modify in ways unknown is to force ix to use RAM,
> such as in a stack frame with a known order of use, which can be
> determined in some compilers quite easily.
>
> Suppose an interrupt gets called and ix is using a register. Then ix
> gets destroyed for the duration of the interrupt call. The fact that
> ix is restored does not count. While the interrupt is in action the
> programmer must look elsewhere in a LESS PORTABLE way for what ix is
> from where it has been saved.
>
> It is an incredibly arrogant assumption for a compiler writer to
> assume they can infer context, particularly when the compiler has
> been told not to assume anything.
>
> The simplest side effect I can think of is the time taken to execute
> an instruction with ix.
>
> What if 'some code using ix' includes assembler code to manipulate
> the stack frame?
>
> I am not going to make an argument that it is impossible to use or
> modify ix if ix is in a register (even when saved to a stack during
> the course of an interrupt). That is not the point. The assumption
> that it is OK for a compiler writer to depart from general industry
> expectations about what volatile does and what a programmer expects
> to be able to do, in a portable fashion, with a variable declared
> volatile, is a violation of community expectations. Community
> expectations must be considered one of the 'unknowns' from a
> standards perspective.
>
> Thinking legalistically about what a standard means with regard
> to 'unknowns', outside community expectations, is frankly flawed.
>
> John Heenan
>
> > The standard does not stipulate what resources are to be used or
> not
> > used in an implementation for automatic variables simply that they
> > exist for the duration of the block within which they are declared.
> It
> > is far from saying don't make assumptions but rather is actually
> > directing an implementer very carefully. I therefore move that an
> > automatic variable declared volatile could use a register and
> conform
> > to the standard.
> >
> > I am not sure what the jump table reference is to, but in K&R or
> ANSI
> > C, it is a simple task to create an array of pointers to
> functions.
> > The control of the placement of that table, if placed in a ROM, is
> > usually a link time operation. A tool chain supplier usually
> provides
> > a suitable section placement scheme. It is also a fairly simple
> task
> > to create such a table dynamically.
> >
> >
> > On 28-May-08, at 5:23 PM, John Heenan wrote:
> >
> > > This is about as black and white as it can get with regard to
> > > interpreting a standard which attempts to deal with the 'unknown'.
> > >
> > > Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
> > > qualifiers' states "An object that has volatile-qualified type
> may be
> > > modified in ways unknown to the implementation or have other
> unknown
> > > side effects."
> > >
> > > In simpler terms this tells a compiler DO NOT MAKE ANY
> ASSUMPTIONS. I
> > > don't think I need to SPELL OUT why assigning ANY volatile
> declared
> > > object to a register is certainly making assumptions about usage
> of
> > > the variable.
> > >
> > > Point proven. The naive go off thinking every other compiler is
> > > inferior because using registers shortens code and improves
> > > benchmarks.
> > >
> > > With regard to 'jump tables'. Both CCE and IAR provide KNOWN ways
> to
> > > generate jump tables. On enquiry Rowley was dismissive. If there
> was
> > > a way of generating jump tables they weren't going to tell us.
> Rather
> > > odd given that the MSP430 has some interrupt facilities that are
> > > ideally suited to jump table use, aside from the enormous general
> > > benefits of jump tables.
> > >
> > > I did notice that a listing of ARM assembly code from C from the
> OPEN
> > > SOURCE compiler USED by Rowley, that was posted on another group,
> did
> > > produce a jump table. I was impressed and said this on the group.
> > >
> > > Despite this don't think projects can be easily ported. Normal ARM
> > > GCC linker command files are generated by Rowley only as long as
> they
> > > are needed and then deleted.
> > >
> > > There have been public comments about not been able to identify
> any
> > > contributions made from Rowley to the development of the open
> source
> > > compiler used by them. The cutting edge contributions, at the
> time,
> > > were coming from www.opensourcery.com, which were well ahead of
> the
> > > stultifying, politicised and bureaucratic snails pace the open
> source
> > > GCC movement was working at.
> > >
> > > Make up your own minds about what is doing on.
> > >
> > > John Heenan
> > >
> > > --- In m..., "Paul Curtis" wrote:
> > > >
> > > > John,
> > > >
> > > > > From a factual perspective what has emerged is that Rowley
> > > appears to
> > > > > use registers for variables that are declared volatile. While
> this
> > > > > will help benchmarks, personally I find it bizarre. There is a
> > > good
> > > > > argument this violates the C standard.
> > > >
> > > > And that argument is, of course, not presented. Your modus
> > > operandi is to
> > > > present something without any research or fact, just gut
> instinct
> > > (viz
> > > > "CrossWorks doesn't generate jump tabes" and "CCE uses GCC as
> its
> > > > compiler").
> > > >
> > > > So, I'm looking for a direct reference to the ISO C standard
> which
> > > gives
> > > > substance to your argument and clearly demonstrates that
> CrossWorks
> > > violates
> > > > the standard in this instance.
> > > >
> > > > Can do you that for us, John?
> > > >
> > > > --
> > > > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > > > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3
> processors
> > > >
> > >
> > >
> > >
> >
> >
> >
> >
>

First - to pre-emptively avoid further "negative waves" - I have committed myself to no further
comment on John's thread - no exceptions. But I'm still entitled to a little comment too in the
other topic below I think.. :-)

> variables as it sees fit, why should volatile change that. If volatile
> means that the object may be modified in ways unknown still does not
> preclude register use.

Exactly. Furthermore, as long as the RMW on that register is atomic (which it is on MSP430) then
the compiler can use such a register, even if there was an ISR (which there isn't/wasn't in the
code example of the OP). Should the C variable be larger than a word, then that's a different
story of course.
The fact that wasn't even an ISR to begin with, silences (or should have silenced!) any argument
about CG register use - or lack thereof.

B rgds
Kris

-----Original Message-----
From: m... [mailto:m...] On Behalf Of Veronica Merryfield
Sent: Thursday, 29 May 2008 2:53 PM
To: m...
Subject: Re: [msp430] Re: Volatile and delay loops

The context I was referring to was that ix is an automatic variable
and within a function.

It is extremely unlikely that an automatic variable would really be
volatile. If a compiler conforms to an EABI that says that automatic
variables use registers first, why would volatile change that.
Similarly, if a compiler implementation can choose to use register
variables as it sees fit, why should volatile change that. If volatile
means that the object may be modified in ways unknown still does not
preclude register use.

However, I do agree that using a register for a volatile is unusual
and would be 'interesting' to implement but it can still satisfy the
requirements of the standard.
On 28-May-08, at 7:48 PM, John Heenan wrote:

> --- In m..., Veronica Merryfield
> wrote:
> >
> > Consider a function foo
> >
> > void foo (void)
> > {
> > volatile int ix;
> >
> > /* some code using ix */
> > }
> >
> > is it wrong for the compiler to use a register in this context?
> > The
> > first ANSI standard says "the purpose of volatile is to force an
> > implementation to suppress optimization that could otherwise
> > occur".
>
> The standard has changed, probably for very good reason. According to
> the CURRENT ISO C standard, you have told the compiler that ix may be
> modified in ways unknown or have other unknown side effects.
>
> The context you assume is not relevant since you have just told the
> compiler not to assume any context by using the type qualifier
> volatile.
>
> You have not specified what 'some code using ix' is.
>
> Since the current standard states ix MAY BE modified in ways unknown
> then a compiler writer MUST ALLOW ix to be modified in ways unknown.
> The simplest way to modify in ways unknown is to force ix to use RAM,
> such as in a stack frame with a known order of use, which can be
> determined in some compilers quite easily.
>
> Suppose an interrupt gets called and ix is using a register. Then ix
> gets destroyed for the duration of the interrupt call. The fact that
> ix is restored does not count. While the interrupt is in action the
> programmer must look elsewhere in a LESS PORTABLE way for what ix is
> from where it has been saved.
>
> It is an incredibly arrogant assumption for a compiler writer to
> assume they can infer context, particularly when the compiler has
> been told not to assume anything.
>
> The simplest side effect I can think of is the time taken to execute
> an instruction with ix.
>
> What if 'some code using ix' includes assembler code to manipulate
> the stack frame?
>
> I am not going to make an argument that it is impossible to use or
> modify ix if ix is in a register (even when saved to a stack during
> the course of an interrupt). That is not the point. The assumption
> that it is OK for a compiler writer to depart from general industry
> expectations about what volatile does and what a programmer expects
> to be able to do, in a portable fashion, with a variable declared
> volatile, is a violation of community expectations. Community
> expectations must be considered one of the 'unknowns' from a
> standards perspective.
>
> Thinking legalistically about what a standard means with regard
> to 'unknowns', outside community expectations, is frankly flawed.
>
> John Heenan
>
> > The standard does not stipulate what resources are to be used or
> not
> > used in an implementation for automatic variables simply that they
> > exist for the duration of the block within which they are declared.
> It
> > is far from saying don't make assumptions but rather is actually
> > directing an implementer very carefully. I therefore move that an
> > automatic variable declared volatile could use a register and
> conform
> > to the standard.
> >
> > I am not sure what the jump table reference is to, but in K&R or
> ANSI
> > C, it is a simple task to create an array of pointers to
> functions.
> > The control of the placement of that table, if placed in a ROM, is
> > usually a link time operation. A tool chain supplier usually
> provides
> > a suitable section placement scheme. It is also a fairly simple
> task
> > to create such a table dynamically.
> >
> >
> > On 28-May-08, at 5:23 PM, John Heenan wrote:
> >
> > > This is about as black and white as it can get with regard to
> > > interpreting a standard which attempts to deal with the 'unknown'.
> > >
> > > Paragraph 6 of Section 6.7.3 of the ISO C standard on 'Type
> > > qualifiers' states "An object that has volatile-qualified type
> may be
> > > modified in ways unknown to the implementation or have other
> unknown
> > > side effects."
> > >
> > > In simpler terms this tells a compiler DO NOT MAKE ANY
> ASSUMPTIONS. I
> > > don't think I need to SPELL OUT why assigning ANY volatile
> declared
> > > object to a register is certainly making assumptions about usage
> of
> > > the variable.
> > >
> > > Point proven. The naive go off thinking every other compiler is
> > > inferior because using registers shortens code and improves
> > > benchmarks.
> > >
> > > With regard to 'jump tables'. Both CCE and IAR provide KNOWN ways
> to
> > > generate jump tables. On enquiry Rowley was dismissive. If there
> was
> > > a way of generating jump tables they weren't going to tell us.
> Rather
> > > odd given that the MSP430 has some interrupt facilities that are
> > > ideally suited to jump table use, aside from the enormous general
> > > benefits of jump tables.
> > >
> > > I did notice that a listing of ARM assembly code from C from the
> OPEN
> > > SOURCE compiler USED by Rowley, that was posted on another group,
> did
> > > produce a jump table. I was impressed and said this on the group.
> > >
> > > Despite this don't think projects can be easily ported. Normal ARM
> > > GCC linker command files are generated by Rowley only as long as
> they
> > > are needed and then deleted.
> > >
> > > There have been public comments about not been able to identify
> any
> > > contributions made from Rowley to the development of the open
> source
> > > compiler used by them. The cutting edge contributions, at the
> time,
> > > were coming from www.opensourcery.com, which were well ahead of
> the
> > > stultifying, politicised and bureaucratic snails pace the open
> source
> > > GCC movement was working at.
> > >
> > > Make up your own minds about what is doing on.
> > >
> > > John Heenan
> > >
> > > --- In m..., "Paul Curtis" wrote:
> > > >
> > > > John,
> > > >
> > > > > From a factual perspective what has emerged is that Rowley
> > > appears to
> > > > > use registers for variables that are declared volatile. While
> this
> > > > > will help benchmarks, personally I find it bizarre. There is a
> > > good
> > > > > argument this violates the C standard.
> > > >
> > > > And that argument is, of course, not presented. Your modus
> > > operandi is to
> > > > present something without any research or fact, just gut
> instinct
> > > (viz
> > > > "CrossWorks doesn't generate jump tabes" and "CCE uses GCC as
> its
> > > > compiler").
> > > >
> > > > So, I'm looking for a direct reference to the ISO C standard
> which
> > > gives
> > > > substance to your argument and clearly demonstrates that
> CrossWorks
> > > violates
> > > > the standard in this instance.
> > > >
> > > > Can do you that for us, John?
> > > >
> > > > --
> > > > Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> > > > CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3
> processors
> > > >
> > >
> > >
> > >
> >
> >
> >
> >
>