0

I have a project in which I communicate with some devices using TWI interface. This project like many other of my projects is using a library for communication that was written long time ago and is reliable. Fun part is that in the middle of this project avr-gcc decided to optimize out every instruction that assings 0 to a variable. Let's look at his code:

_hd44780_data.expander_data[0] = 0x06;
_hd44780_data.expander_data[1] = 0x00;
_hd44780_data.expander_data[2] = 0x1F;
twi_write(HD44780_EXPANDER, _hd44780_data.expander_data,
          3, &_hd44780_data.twi_status);

And gcc cuts out _hd44780_data.expander_data[1] = 0x00; Code below, works fine.

_hd44780_data.expander_data[0] = 0x06;
_hd44780_data.expander_data[1] = 0x05;
_hd44780_data.expander_data[1] -= 0x05;
_hd44780_data.expander_data[2] = 0x1F;
twi_write(HD44780_EXPANDER, _hd44780_data.expander_data,
          3, &_hd44780_data.twi_status);

I think that it has somethig to do with optimisation. I'm using avr-gcc (WinAVR 20100110) 4.3.3 These are my CFLAGS:

CFLAGS += -Os -mcall-prologues
CFLAGS += -ffreestanding
CFLAGS += -funit-at-a-time
CFLAGS += -finline-functions
CFLAGS += -fkeep-inline-functions
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += --std=gnu99
CFLAGS += -Wstrict-prototypes
CFLAGS += -mrelax

Another this is that this "optimisation" includes all instructions not only array assignments. What is mostly puzzling for me is that this behavior occurred in the middle of a project. Another thing is that this "optimisation" includes all instructions not only array assignments. What is mostly puzzling for me is that this behavior occurred in the middle of a project. I haven't changed any flags and I haven't updated toolchain.

But ancient Chinese adage says "With the two of you, the compiler is right.", so it would be much appreciated if anyone could point out where I might be going wrong.

mszubart
  • 117
  • 1
  • 3
  • 6
  • Where/how are you declaring and initializing `_hd44780_data`? – Ulfalizer Apr 08 '15 at 10:37
  • 1
    Is _hd44780_data a global (file scope) variable? These are initialised to 0 during startup so the optimisation may be correct if you are just initialising it again. – Jon Apr 08 '15 at 10:38
  • `_hd44780_data` is a global variable and expander_data is a static array of 6 uin8_t bytes. But writing 0 to this array is not the first thing that is done. Also every other assignment of 0 is cut out - even from volatile flags e.g. Let's declare and initialize the flag: `volatile uint8_t flag = 1;` Few hundred lines of code later: `flag = 0;` and this is also removed. – mszubart Apr 08 '15 at 10:50
  • This is addressed in the [AVR Libc FAQ](http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_varinit). In particular, how global and static variables are initialized. – Brett Hale Apr 08 '15 at 11:01
  • Thank you Brett. But I don't think it is a initialization problem. As you can see in my first code sample, twi_write function should write <0x06><0x00><0x1F> to TWI device. FAQ is saying that my data should be all 0 at startup. So compiler removes `_hd44780_data.expander_data[1] = 0x00;` because it is a redundant initialization. But twi_write, writes following values <0x06><0xFF><0x1F>. Why 0xFF if it should be 0x00? When I do the trick with setting data to 5 and then subtracting 5, everyting is ok and 0x00 is written to TWI device. – mszubart Apr 08 '15 at 11:16

0 Answers0