Re: [Mspgcc-users] Instruction reordering

2015-11-28 Thread David Brown
It is always nice to get confirmation, especially from the person that 
actually maintained and re-wrote the code in question!

As Peter points out, discussing the behaviour of the compiler is always 
on the assumption that the compiler does not have bugs there.  The later 
gcc 4 versions that Peter put together had fewer bugs and more features 
than the gcc 3 msp430 port.  We use them on a couple of projects (we 
have not moved to the new TI/Red Hat port), and I have been very happy 
with the tools.

We too are moving more and more to Cortex M devices (Freescale Kinetis 
mostly).  But when working with high temperature electronics, the msp430 
can still be a good choice - there is a 150C qualified msp430, with 
partial qualification (excluding some peripherals) at 175C.  There are 
no other microcontrollers of any sort, AFAIK, that are comparable in 
size and power consumption that work at high temperatures.  One day, I 
am sure someone (probably TI!) will release an M3/M4 for high 
temperature - but until then, we will use the msp430 for such 
specialised projects.

mvh.,

David


On 28/11/15 13:35, Peter Bigot wrote:
> Your colleague is mistaken regarding re-ordering of access to
> volatile-qualified objects.  David's description is correct and nicely
> detailed.  In the example a will always be written before b unless the
> compiler is broken.
>
> (I should point out that mspgcc in the 3.2.3 era in fact probably *was*
> broken with respect to correct ordering of some volatile operations,
> because of a hack intended to improve peripheral register access
> performance. There were errors in volatile behavior when I started
> maintenance that didn't get cleaned up until sometime around August
> 2011.  There's probably traffic in the list archive around that time
> that explains the problem.)
>
> MSP430 writes of 16-bit values in any version of mspgcc I released would
> be atomic except if they occurred to an object declared with the
> "packed" attribute, in which case the byte values would be written
> separately to prevent alignment problems.  (There were bugs in this
> usage too.)
>
> I also use ARM Cortex devices these days, and am very pleased to see
> that TI is moving the MSP432 to using CMSIS-Core--compatible peripheral
> structure definitions as of March 2016
> (http://processors.wiki.ti.com/index.php/MSP432_CMSIS_Update?DCMP=epd-mcu-msp-gen&HQS=MSP432CMSIS).
> If the Tiva and CC3K folks were that adaptable I might still use TI chips.
>
> Peter
>
> On Fri, Nov 27, 2015 at 9:04 PM, Wayne Uroda  > wrote:
>
> Thanks very much David.
>
> I already disable interrupts when I need an atomic operation, such
> as a write to 32 bit variable or a read-modify-write on a 16bit
> variable.
>
> Am I right to assume that simple writes to 16 bit variables are
> always atomic on MSP430? Eg done = 0xabcd, the CPU doesn't do two
> byte writes or anything dumb like that, the memory will be X (don't
> care) before the write and will be 0xabcd after, or should I disable
> interrupts for all writes to shared memory (shared with an ISR)?
>
>
> My colleague asserts that the compiler is even free to reorder
> volatile accesses, like
>
> volatile int a;
> volatile int b;
> int c;
>
> int main()
> {
>  a = 5;
>  b = 0;
>  c = 1;
>  return 0;
> }
>
> You are saying that the compiler will always write a before b, even
> without a memory barrier. Is that right?
>
> But in the above, the write to c can happen anywhere, as far as I
> understand.
>
> Lastly, this compiler (3.2.3) is only used on our legacy projects.
> More recently we are using the last LTS of mspgcc before Ti/RH
> started their port.
> I've not seriously tried to use the new RH compiler, and my company
> is largely moving away from MSP430 towards ARM Cortex now.
>
> Thanks
> - Wayne
>
>
>
>  > On 27 Nov 2015, at 23:19, David Brown  > wrote:
>  >
>  >> On 27/11/15 12:32, Wayne Uroda wrote:
>  >> Hello,
>  >>
>  >> I have a question about instruction reordering in the compiler.
>  >>
>  >> In this blog
>  >> http://preshing.com/20120625/memory-ordering-at-compile-time/ It
> says
>  >> that a compiler barrier should be used where writes to memory must
>  >> not be reordered.
>  >
>  > Looks like good information.
>  >
>  >>
>  >> My MSP430 code is all bare metal, foreground-background code and
> I am
>  >> not using any type of RTOS, so it could be considered lock-free.
>  >>
>  >> Anyway, a new employee at my work pointed out that the compiler is
>  >> free to reorder my memory writes, even those marked volatile. I said
>  >> that I had never actually seen mspgcc do this, but now I am curious:
>  >> will mspgcc reorder memory writes, eg to global variables? Is this
> 

Re: [Mspgcc-users] Instruction reordering

2015-11-28 Thread Peter Bigot
Your colleague is mistaken regarding re-ordering of access to
volatile-qualified objects.  David's description is correct and nicely
detailed.  In the example a will always be written before b unless the
compiler is broken.

(I should point out that mspgcc in the 3.2.3 era in fact probably *was*
broken with respect to correct ordering of some volatile operations,
because of a hack intended to improve peripheral register access
performance. There were errors in volatile behavior when I started
maintenance that didn't get cleaned up until sometime around August 2011.
There's probably traffic in the list archive around that time that explains
the problem.)

MSP430 writes of 16-bit values in any version of mspgcc I released would be
atomic except if they occurred to an object declared with the "packed"
attribute, in which case the byte values would be written separately to
prevent alignment problems.  (There were bugs in this usage too.)

I also use ARM Cortex devices these days, and am very pleased to see that
TI is moving the MSP432 to using CMSIS-Core--compatible peripheral
structure definitions as of March 2016 (
http://processors.wiki.ti.com/index.php/MSP432_CMSIS_Update?DCMP=epd-mcu-msp-gen&HQS=MSP432CMSIS).
If the Tiva and CC3K folks were that adaptable I might still use TI chips.

Peter

On Fri, Nov 27, 2015 at 9:04 PM, Wayne Uroda  wrote:

> Thanks very much David.
>
> I already disable interrupts when I need an atomic operation, such as a
> write to 32 bit variable or a read-modify-write on a 16bit variable.
>
> Am I right to assume that simple writes to 16 bit variables are always
> atomic on MSP430? Eg done = 0xabcd, the CPU doesn't do two byte writes or
> anything dumb like that, the memory will be X (don't care) before the write
> and will be 0xabcd after, or should I disable interrupts for all writes to
> shared memory (shared with an ISR)?
>
>
> My colleague asserts that the compiler is even free to reorder volatile
> accesses, like
>
> volatile int a;
> volatile int b;
> int c;
>
> int main()
> {
> a = 5;
> b = 0;
> c = 1;
> return 0;
> }
>
> You are saying that the compiler will always write a before b, even
> without a memory barrier. Is that right?
>
> But in the above, the write to c can happen anywhere, as far as I
> understand.
>
> Lastly, this compiler (3.2.3) is only used on our legacy projects. More
> recently we are using the last LTS of mspgcc before Ti/RH started their
> port.
> I've not seriously tried to use the new RH compiler, and my company is
> largely moving away from MSP430 towards ARM Cortex now.
>
> Thanks
> - Wayne
>
>
>
> > On 27 Nov 2015, at 23:19, David Brown  wrote:
> >
> >> On 27/11/15 12:32, Wayne Uroda wrote:
> >> Hello,
> >>
> >> I have a question about instruction reordering in the compiler.
> >>
> >> In this blog
> >> http://preshing.com/20120625/memory-ordering-at-compile-time/ It says
> >> that a compiler barrier should be used where writes to memory must
> >> not be reordered.
> >
> > Looks like good information.
> >
> >>
> >> My MSP430 code is all bare metal, foreground-background code and I am
> >> not using any type of RTOS, so it could be considered lock-free.
> >>
> >> Anyway, a new employee at my work pointed out that the compiler is
> >> free to reorder my memory writes, even those marked volatile. I said
> >> that I had never actually seen mspgcc do this, but now I am curious:
> >> will mspgcc reorder memory writes, eg to global variables? Is this
> >> dependent on the msp430 side of gcc (the backend), or more on the
> >> AST/RTL side?
> >
> > The compiler can re-order any reads or writes it likes, except volatile
> > accesses.  The order of volatile accesses will always match the source
> > code.  But the compiler can move non-volatile reads and writes back and
> > forth between volatile accesses.
> >
> > So if you have non-volatile variables a, b, c, and volatile variables u,
> > v, and source code like this:
> >
> > a = 1;
> > u = 100;
> > b = 2;
> > v = 200;
> > c = 3;
> >
> > Then the compiler can generate code like this:
> >
> > a = 1;
> > c = 3;
> > u = 100;
> > v = 200;
> > b = 2;
> >
> > But it may not generate code like this:
> >
> > a = 1;
> > v = 200;
> > b = 2;
> > u = 100;
> > c = 3;
> >
> > (The same applies to reads.)
> >
> > The volatile accesses must be exact, in the same number and the same
> > order with respect to other volatile accesses.  But the non-volatile
> > accesses can be moved around as much as the compiler wants.
> >
> > Note that variable accesses can also be moved around with respect to
> > function calls, /if/ the compiler knows the function does not make
> > volatile accesses.
> >
> > The compiler can also eliminate "dead" stores, or unused reads.  Given:
> >
> > a = 1;
> > u = 100;
> > a = 2;
> > v = 200;
> > a = 3;
> >
> > The compiler can generate:
> >
> > u = 100;
> > v = 200;
> > a = 3;
> >
> > or
> >
> > a = 3;
> > u = 100;
> > v = 100;
> >
> >
> >>
> >> Or to put it another way, should I be re

Re: [Mspgcc-users] Instruction reordering

2015-11-27 Thread Wayne Uroda
Thanks very much David.

I already disable interrupts when I need an atomic operation, such as a write 
to 32 bit variable or a read-modify-write on a 16bit variable.

Am I right to assume that simple writes to 16 bit variables are always atomic 
on MSP430? Eg done = 0xabcd, the CPU doesn't do two byte writes or anything 
dumb like that, the memory will be X (don't care) before the write and will be 
0xabcd after, or should I disable interrupts for all writes to shared memory 
(shared with an ISR)?


My colleague asserts that the compiler is even free to reorder volatile 
accesses, like

volatile int a;
volatile int b;
int c;

int main()
{
a = 5;
b = 0;
c = 1;
return 0;
}

You are saying that the compiler will always write a before b, even without a 
memory barrier. Is that right?

But in the above, the write to c can happen anywhere, as far as I understand.

Lastly, this compiler (3.2.3) is only used on our legacy projects. More 
recently we are using the last LTS of mspgcc before Ti/RH started their port.
I've not seriously tried to use the new RH compiler, and my company is largely 
moving away from MSP430 towards ARM Cortex now.

Thanks
- Wayne



> On 27 Nov 2015, at 23:19, David Brown  wrote:
> 
>> On 27/11/15 12:32, Wayne Uroda wrote:
>> Hello,
>> 
>> I have a question about instruction reordering in the compiler.
>> 
>> In this blog 
>> http://preshing.com/20120625/memory-ordering-at-compile-time/ It says
>> that a compiler barrier should be used where writes to memory must
>> not be reordered.
> 
> Looks like good information.
> 
>> 
>> My MSP430 code is all bare metal, foreground-background code and I am
>> not using any type of RTOS, so it could be considered lock-free.
>> 
>> Anyway, a new employee at my work pointed out that the compiler is
>> free to reorder my memory writes, even those marked volatile. I said
>> that I had never actually seen mspgcc do this, but now I am curious:
>> will mspgcc reorder memory writes, eg to global variables? Is this
>> dependent on the msp430 side of gcc (the backend), or more on the
>> AST/RTL side?
> 
> The compiler can re-order any reads or writes it likes, except volatile
> accesses.  The order of volatile accesses will always match the source
> code.  But the compiler can move non-volatile reads and writes back and
> forth between volatile accesses.
> 
> So if you have non-volatile variables a, b, c, and volatile variables u,
> v, and source code like this:
> 
> a = 1;
> u = 100;
> b = 2;
> v = 200;
> c = 3;
> 
> Then the compiler can generate code like this:
> 
> a = 1;
> c = 3;
> u = 100;
> v = 200;
> b = 2;
> 
> But it may not generate code like this:
> 
> a = 1;
> v = 200;
> b = 2;
> u = 100;
> c = 3;
> 
> (The same applies to reads.)
> 
> The volatile accesses must be exact, in the same number and the same
> order with respect to other volatile accesses.  But the non-volatile
> accesses can be moved around as much as the compiler wants.
> 
> Note that variable accesses can also be moved around with respect to
> function calls, /if/ the compiler knows the function does not make
> volatile accesses.
> 
> The compiler can also eliminate "dead" stores, or unused reads.  Given:
> 
> a = 1;
> u = 100;
> a = 2;
> v = 200;
> a = 3;
> 
> The compiler can generate:
> 
> u = 100;
> v = 200;
> a = 3;
> 
> or
> 
> a = 3;
> u = 100;
> v = 100;
> 
> 
>> 
>> Or to put it another way, should I be reviewing my shared (between
>> background and ISR) variables and placing compiler barriers where
>> variables must be stored in an exact order?
> 
> Yes, these must be handled carefully.  In particular, volatile accesses
> give no indication about how non-volatile accesses are handled.
> Sometimes people write code like this:
> 
> int data[4];
> volatile bool newData;
> 
> void update(int x) {
>data[0] = data[1];
>data[1] = data[2];
>data[2] = data[3];
>data[3] = x;
>newData = true;
> }
> 
> And they think that making the newData flag a volatile is sufficient.
> It is /not/ sufficient - the compiler can set newData before doing
> anything with the data[] array.  And then your interrupt code will work
> fine in all your testing, and hit a race condition when the customer is
> watching.
> 
> You have to make each access to "data" here volatile, or you need a
> memory barrier between "data[3] = x;" and "newData = true;".  A memory
> barrier tells the compiler that all memory writes before the barrier
> need to be completed, no writes after the barrier may be started, and
> any data read before the barrier is now invalid.
> 
> And note that even then, nothing in memory barriers or volatile access
> will ensure that the reads or writes are atomic.
> 
> Some useful macros/functions:
> 
> #define volatileAccess(v) *((volatile typeof((v)) *) &(v))
> 
> static inline void compilerBarrier(void) {
>asm volatile("" ::: "memory");
> }
> 
> 
>> 
>> I am using a very old version of mspgcc, 3.2.3, I think it was the
>> last stable Windows binary rel

Re: [Mspgcc-users] Instruction reordering

2015-11-27 Thread David Brown
On 27/11/15 12:32, Wayne Uroda wrote:
> Hello,
> 
> I have a question about instruction reordering in the compiler.
> 
> In this blog 
> http://preshing.com/20120625/memory-ordering-at-compile-time/ It says
> that a compiler barrier should be used where writes to memory must
> not be reordered.

Looks like good information.

> 
> My MSP430 code is all bare metal, foreground-background code and I am
> not using any type of RTOS, so it could be considered lock-free.
> 
> Anyway, a new employee at my work pointed out that the compiler is
> free to reorder my memory writes, even those marked volatile. I said
> that I had never actually seen mspgcc do this, but now I am curious:
> will mspgcc reorder memory writes, eg to global variables? Is this
> dependent on the msp430 side of gcc (the backend), or more on the
> AST/RTL side?

The compiler can re-order any reads or writes it likes, except volatile
accesses.  The order of volatile accesses will always match the source
code.  But the compiler can move non-volatile reads and writes back and
forth between volatile accesses.

So if you have non-volatile variables a, b, c, and volatile variables u,
v, and source code like this:

a = 1;
u = 100;
b = 2;
v = 200;
c = 3;

Then the compiler can generate code like this:

a = 1;
c = 3;
u = 100;
v = 200;
b = 2;

But it may not generate code like this:

a = 1;
v = 200;
b = 2;
u = 100;
c = 3;

(The same applies to reads.)

The volatile accesses must be exact, in the same number and the same
order with respect to other volatile accesses.  But the non-volatile
accesses can be moved around as much as the compiler wants.

Note that variable accesses can also be moved around with respect to
function calls, /if/ the compiler knows the function does not make
volatile accesses.

The compiler can also eliminate "dead" stores, or unused reads.  Given:

a = 1;
u = 100;
a = 2;
v = 200;
a = 3;

The compiler can generate:

u = 100;
v = 200;
a = 3;

or

a = 3;
u = 100;
v = 100;


> 
> Or to put it another way, should I be reviewing my shared (between
> background and ISR) variables and placing compiler barriers where
> variables must be stored in an exact order?

Yes, these must be handled carefully.  In particular, volatile accesses
give no indication about how non-volatile accesses are handled.
Sometimes people write code like this:

int data[4];
volatile bool newData;

void update(int x) {
data[0] = data[1];
data[1] = data[2];
data[2] = data[3];
data[3] = x;
newData = true;
}

And they think that making the newData flag a volatile is sufficient.
It is /not/ sufficient - the compiler can set newData before doing
anything with the data[] array.  And then your interrupt code will work
fine in all your testing, and hit a race condition when the customer is
watching.

You have to make each access to "data" here volatile, or you need a
memory barrier between "data[3] = x;" and "newData = true;".  A memory
barrier tells the compiler that all memory writes before the barrier
need to be completed, no writes after the barrier may be started, and
any data read before the barrier is now invalid.

And note that even then, nothing in memory barriers or volatile access
will ensure that the reads or writes are atomic.

Some useful macros/functions:

#define volatileAccess(v) *((volatile typeof((v)) *) &(v))

static inline void compilerBarrier(void) {
asm volatile("" ::: "memory");
}


> 
> I am using a very old version of mspgcc, 3.2.3, I think it was the
> last stable Windows binary release before the CPUX instructions
> started making their way in, sorry I don't know the version, from
> 2008/2009 maybe?
> 

That was probably the final release before the mspgcc 4 project was
started.  And now there is a new port msp430-elf from Red Hat and TI,
which is where you should go for moving on for the future.

gcc 3.2.3 did not optimise as aggressively as newer gcc, so it will do a
lot less re-arrangement of code.  In general, the compiler will
re-arrange the order of writes if it has good reason to do so - if the
result is smaller and/or faster.  If it makes no difference, then it
will not re-order the writes.





--
___
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users