How to make an "optimized-away" variable visible?

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Greetings -

 

Continuing to lean on ATmega4809 Xplained Pro. But, now I have a problem.

 

I have a function (a TWI function) that  returns a status value. My program, at this point, is very small and very primitive, and I have no place to write it for observation. As a result, that return value is optimized away, and invisible to the operator (e.g. me). 

 

Is there something that I can do other than change the optimization level that will force it to be not optimized away? Maybe make the return assignment variable volatile? Or, write to some innocent hardware register, like an SPI data register? Anything else that makes sense?

 

Thanks

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The return value probably sits in a register - you'll have to look at the generates assembler to determine this. If the value gets assigned to a variable, then declare the variable volatile - this will force the compiler to write the variable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could write it to one of the GPIO registers, or store it in a global memory location that you've declared as volatile.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure if this will work, but I think it will. I know it works for functions that aren't called at all, but can't confirm it works for variables. 

 

In Atmel Studio, go to project properties -> AVR/GNU Linker -> Optimization and disable Garbage collect unused sections. 

 

There is another option in AVR/GNU C Compiler -> Optimization called Prepare data for garbage collection. Maybe try to uncheck that too, although I don't really know what it does. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The_time wrote:
In Atmel Studio, go to project properties -> AVR/GNU Linker -> Optimization and disable Garbage collect unused sections. 

 

There is another option in AVR/GNU C Compiler -> Optimization called Prepare data for garbage collection. Maybe try to uncheck that too, although I don't really know what it does.

Only affects statically allocated variables.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Isn't the usage of registers, in so far as function call and return, fixed? According to this ABI document, GCC AVR will return a byte variable (for example) in R24.

 

https://gcc.gnu.org/wiki/avr-gcc

 

Or will the optimser look to see if a return value is used by the code that calls a function and then backtrack into the function to optimise away any code that sets up the return value?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Probably the latter. If you have:

type var;

var = fn();

// nothing ever touches "var" after this

then the optimiser could well decide "no point in creating var, no point in calling fn()" because it can see its a completely pointless exercise. Obviously:

volatile type var;

var = fn();

// nothing ever touches "var" after this

is something quite different - it says "you must create var and you must write to it" so all the code would be generated in this case.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess if the optimiser decides to inline a function, then there is no call/return - so no need for the usual call/return semantics ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All of this reminds me why I prefer CVAVR (and am happy to pay real money for it every year) wink

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Brian Fairchild wrote:
All of this reminds me why I prefer CVAVR
Because it generates bloaty/pointless code ?

 

The reason these things are being discarded and hence are not visible is because they are being optimised away - how is optimisation a "Bad Thing(tm)" exactly?

 

Don't want to start a compiler war - there are many things CV is better at than GCC but surely one of GCC's "selling points" is its aggressive optimiser ? Not to say that it is "perfect" as there are still many "missed optimisations" leveled against it, also the argument in recent years that compiler development mainly targets x86/ARM sometimes to the detriment of the AVR port (in some cases its code generation actually gets more "bloaty" over time).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
that return value is optimized away

What optimisation level are you using ?

 

IIRC, there is a -Og - which is supposed to give a reasonable compromise of optimisation against "debuggability"

 

May still not help this particular case, but worth a check ...

 

EDIT

 

This:

-Og

Optimize debugging experience. -Og should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience. It is a better choice than -O0 for producing debuggable code because some compiler passes that collect debug information are disabled at -O0.

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Feb 19, 2020 - 05:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, folks.

 

Some good  stuff to chew on!

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
then the optimiser could well decide "no point in creating var, no point in calling fn()" because it can see its a completely pointless exercise.
Minor nit pick here, but regardless of var usage, fn() WILL be called unless its content is trivial (e.g.. empty).  Anyways, as previously suggested, declaring the returned value variable as volatile is the obvious solution to the OP's query, right?

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed obvious

DCL17-C. Beware of miscompiled volatile-qualified variables - SEI CERT C Coding Standard - Confluence

[mid-page]

The workarounds proposed by Eide and Regehr fix many of the volatile-access bugs in the tested compilers. However, compilers are always changing, so critical sections of code should be compiled as if for deployment, and the compiled object code should be inspected for the correct behavior.

 

Risk Assessment

...

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

Last Edited: Wed. Feb 19, 2020 - 09:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, not those GPIO registers; those are PORTS.

I meant like GPIOR0 and similar (badly named and seldom used, AFAICT.)

(Just as a pre-defined volatile location that you're probably not using yet, and won't consume actual RAM.)

 

Last Edited: Thu. Feb 20, 2020 - 02:58 AM