Re: [avr-gcc-list] Program Space String optimization

2005-12-15 Thread David Brown

 On Dec 14, 2005, at 8:57 AM, Joerg Wunsch wrote:

  volatile PGM_P txt= P_Txt;
 
  Your volatile qualifier is at the wrong place.  You're marking the
  object txt points to as volatile, not the pointer itself.  Change
  that into
 
  PGM_P volatile txt = P_Txt;
 
  and it will work.

 Believe that is correct. But the other thing that was tripping him is
 in general all function calls are effectively volatile as well. Call
 a function and expect it will be called simply because you said to,
 the the optimizer probably won't descend into the function and decide
 it can be skipped. If the function is inlined then all bets are off.

 do{} while( (a=pgm_read_byte(txt)) );  // Wait for null char

 While pgm_read_byte(txt) looks like a function call it is totally macro.

 I don't believe this is a problem with the compiler at all, it did
 exactly what it was told it could do.

 --
 David Kelly N4HHE, [EMAIL PROTECTED]


Actually, gcc is getting steadily better at optomising function calls -
there is no reason to assume that function calls are effectively volatile.
Under normal optomisation, the compiler will use what it knows about
previously defined functions to determine if they can be re-ordered,
inlined, or skipped entirely.  Some standard library functions are handled
as special cases, and it is possible to use function attributes in header
files to tell the compiler more (such as const or pure) giving the
compiler lots more freedom to move around the function calls.  With -O2 and
above, unit-at-a-time compilation allows the compiler to use information
about functions later in the same unit, and if you've specified several C
files at the same time, it can use information about all of them.  Thus
assuming that function calls are volatile is dangerous.

mvh.,

David





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-15 Thread bolet (sent by Nabble.com)

Your volatile qualifier is at the wrong place. You're marking the 
object txt points to as volatile, not the pointer itself. Change 
that into 

PGM_P volatile txt = P_Txt; 

and it will work. 

Thank you for your fast answer. I've compiled whith those changes and it works as expected.
I supose I'll have to read more C manuals...

Btw., to make other people's job (who are willing to help you) easier, 
please supply compilable examples (all required #includes present, 
things like Init code here in /* */ comment delimiters). Thank you. 

Sure I will do next time. And Thank you again

 Bolet





Sent from the AVR - gcc forum at Nabble.com:
Re: Program Space String & optimization
___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-15 Thread bolet (sent by Nabble.com)

A solution I would propose is to change the offending line like this (I 
haven't checked this, though): 
  do{} while( (a=(volatile char)(pgm_read_byte(txt))) ); 

Thanks for answering. I've tryed your suggestion with the same result, but
the answer given by Joerg Wunsch (first answer in thread) works OK:

Your volatile qualifier is at the wrong place. You're marking the 
object txt points to as volatile, not the pointer itself. Change 
that into 

PGM_P volatile txt = P_Txt
 
 Thanks
 
 Bolet



Sent from the AVR - gcc forum at Nabble.com:
Re: Program Space String & optimization
___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-14 Thread Joerg Wunsch
bolet (sent by Nabble.com) [EMAIL PROTECTED] wrote:

  The 'end of string' is checked in 'main' (just for test purposes).

A very strange way, indeed...

 volatile PGM_P txt= P_Txt;

Your volatile qualifier is at the wrong place.  You're marking the
object txt points to as volatile, not the pointer itself.  Change
that into

PGM_P volatile txt = P_Txt;

and it will work.

Btw., to make other people's job (who are willing to help you) easier,
please supply compilable examples (all required #includes present,
things like Init code here in /* */ comment delimiters).  Thank you.

-- 
Jorg Wunsch   Unix support engineer
[EMAIL PROTECTED]http://www.interface-systems.de/~j/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-14 Thread Dimitar Dimitrov
On 14.12.2005 11:42, bolet (sent by Nabble.com) wrote:
  The program works OK without optimization. It doesn't work with
 optimization (-o1). The code is:

 ...includes...
 const char P_Txt[] PROGMEM = Just a test..;
 volatile PGM_P txt= P_Txt;

 int main (void)
 {

   ...Init code ... (reg setup  enable int)

do{} while( (a=pgm_read_byte(txt)) );  // Wait for null char
cli(); //Disable int
for (;;);  // Do nothing
return(0);
 }

 SIGNAL (SIG_USART_DATA)
 {
 UDR0=pgm_read_byte(txt++);  //Send a byte and increment  pointer
 }

Hi, 
Your problem seems to be in this line:
   do{} while( (a=pgm_read_byte(txt)) );
In spite of txt being declared as volatile, the pgm_read_byte macro evaluates 
it as a plain uint16_t. To see what I mean, check out these two macros from 
avr/pgmspace.h :
#define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
#define pgm_read_byte(address_short)pgm_read_byte_near(address_short)

A solution I would propose is to change the offending line like this (I 
haven't checked this, though):
   do{} while( (a=(volatile char)(pgm_read_byte(txt))) );



___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Program Space String optimization

2005-12-14 Thread Dave Hansen

From: bolet (sent by Nabble.com) [EMAIL PROTECTED]
[...]
 The program works OK without optimization. It doesn't work with 
optimization (-o1). The code is:


...includes...
const char P_Txt[] PROGMEM = Just a test..;
volatile PGM_P txt= P_Txt;

int main (void)
{

  ...Init code ... (reg setup  enable int)

   do{} while( (a=pgm_read_byte(txt)) );  // Wait for null char
   cli(); //Disable int
   for (;;);  // Do nothing
   return(0);
}

SIGNAL (SIG_USART_DATA)
{
UDR0=pgm_read_byte(txt++);  //Send a byte and increment  pointer
}


The 'do while' assembler code generated (with -o1) :

+0041:   91E00100LDS R30,0x0100
+0043:   91F00101LDS R31,0x0101
+0045:   9184   LPM R24,Z
51:  do{} while( (a=pgm_read_byte(txt)) );  // Wait for null char
+0046:   2388  TST R24
+0047:   F7F1   BRNEPC-0x01  Branch if not equal

52:  cli();  
//Disable int


 As you can see, the LPM instruction is outside the loop, so this is an 
infinite loop.


 -What's wrong with this code?


Seems to be a strange corner case.  I'm not sure the compiler is 
misbehaving, but it might be.  There should be a simple fix.


You've declared 'txt' to be volatile, which is good, but you don't show the 
declaration of  'a'.  And I suspect it's not volatile.  Since 'a' is not 
volatile, subsequent writes to the value may be optimized out.  But the LPM 
should always happen because txt is volatile.


In any case, changing the declaration of 'a' to something like

  unsigned char volatile a;

should do it.  Removing 'a' entirely should fix it as well, but I'm assuming 
you're using it for other reasons.




 -Which is this the correct way to  work with flash data?


You don't seem to be handling flash wrong.



  Any suggestion would be greatly appreciated.


HTH,
  -=Dave




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-14 Thread David Kelly


On Dec 14, 2005, at 8:57 AM, Joerg Wunsch wrote:


volatile PGM_P txt= P_Txt;


Your volatile qualifier is at the wrong place.  You're marking the
object txt points to as volatile, not the pointer itself.  Change
that into

PGM_P volatile txt = P_Txt;

and it will work.


Believe that is correct. But the other thing that was tripping him is  
in general all function calls are effectively volatile as well. Call  
a function and expect it will be called simply because you said to,  
the the optimizer probably won't descend into the function and decide  
it can be skipped. If the function is inlined then all bets are off.


do{} while( (a=pgm_read_byte(txt)) );  // Wait for null char

While pgm_read_byte(txt) looks like a function call it is totally macro.

I don't believe this is a problem with the compiler at all, it did  
exactly what it was told it could do.


--
David Kelly N4HHE, [EMAIL PROTECTED]

Whom computers would destroy, they must first drive mad.



___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Program Space String optimization

2005-12-14 Thread Joerg Wunsch
David Kelly [EMAIL PROTECTED] wrote:

 Believe that is correct. But the other thing that was tripping him
 is in general all function calls are effectively volatile as well.

That's not entirely true.  For standard library functions, if the
compiler knows exactly the result (and knows it has no side effects),
it can do whatever would have happened instead actually calling the
function.  Consider the pgm_read_*() functions to be similar to that
in behaviour: the compiler knows exactly what needs to be done here.

Likewise, GCC can analyze simple functions, and notice they don't have
side effects, and return a constant result, and then skip multiple
invocations if it has the result `cached' still.

 If the function is inlined then all bets are off.

A true inlined function should behave identical to a non-inlined one.
But of course, macros are different here.

-- 
cheers, Jorg   .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)



___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list