1

I have some code that is being compiled with GCC for a micro. I noticed that when compiling the debug build, the system works just fine. But when I compile the release build, the system does not boot up.

After working on the issue for awhile, I narrowed down the problem to one function where if I specify a lesser optimization level (-O0 instead of -Os), the system will boot up just fine in the release build. So there is presumably a flag that -Os sets that is causing the code in that particular function to not work.

I had planned to track down the underlying issue by taking all the flags that -Os sets, and finding the one that causes the system not to boot.

I was trying to do the following:

__attribute__ ((optimize("-fauto-inc-dec", "-fcompare-elim", "-fcprop-registers", "-fdce", "-fdefer-pop", "-fdelayed-branch", "-fdse", "-fguess-branch-probability", "-fif-conversion2", "-fif-conversion", "-fipa-pure-const", "-fipa-profile", "-fipa-reference", "-fmerge-constants", "-fsplit-wide-types", "-ftree-bit-ccp", "-ftree-builtin-call-dce", "-ftree-ccp", "-ftree-ch", "-ftree-copyrename", "-ftree-dce", "-ftree-dominator-opts", "-ftree-dse", "-ftree-forwprop", "-ftree-fre", "-ftree-phiprop", "-ftree-sra", "-ftree-pta", "-ftree-ter", "-funit-at-a-time")))

and then eliminate flags until the system would boot. The problem is, is that I kept narrowing it down and narrowing it down, until I discovered that I can't get even set a single flag and get the system to boot.

So now I'm thinking that I'm doing something wrong with the way that I'm setting the optimization. If I put in a superfluous non-existent flag somewhere in the middle of those flags, like -fiam-fake-flag, the compiler detects it and spits out an error (which at first made me feel like I was setting these flags correctly).

I don't want to use pragma, because:

" Each function that is defined after this point is as if attribute((optimize("STRING"))) was specified for that function. "

and I only want the optimization on this one function so I can narrow down the problem.

So, am I setting these flags incorrectly? Is there a better way to specify a whole bunch of compiler flags for only 1 specific function?

If it weren't going on a micro, I could just specify all the flags I want in the Makefile and apply it to all functions, but doing so makes the program too big to fit on the micro.

Mike Gibson
  • 342
  • 1
  • 3
  • 14
  • 99.9% of 'code works/doesn't' with -0X set' are UB-style bugs. – Martin James Dec 16 '13 at 16:13
  • @MartinJames: For a standard platform, I'd agree (100%) with that statistic. However, if the OP is working on some wacky microcontroller with an immature toolchain, there's a >0.1% chance that there's a compiler bug, in my experience... – Oliver Charlesworth Dec 16 '13 at 16:17
  • @OliCharlesworth - I get it all the time on ARM uC. It's always been UB-ish, ie. my crappy code :( – Martin James Dec 16 '13 at 16:22
  • I know what code is breaking the system's ability to boot, but was hoping to understand the reason. I am building upon FreeRTOS. The problematic code is a forced delay between SPI messages. In a module that has its own thread, I start a timer and unset a flag. A message cannot be sent until the flag is reset. Upon timer expiry, the flag is reset. The timer, a FreeRTOS module, is supposed to be thread safe, but the timer gets stuck when it tries to set the flag. If the messages can't be sent, the system won't boot. – Mike Gibson Dec 16 '13 at 16:27
  • But the question is, is why do different optimization levels affect the timer's ability to expire and set a flag correctly? – Mike Gibson Dec 16 '13 at 16:29
  • You have your OS in the boot code? – Martin James Dec 16 '13 at 17:56
  • I guess what I put is a bit misleading. The system won't "go live". Many things have to occur for the system to "go live", including sending and receiving messages with the peripherals. It's during this sending/receiving step where things go awry, and prevent the system from "going live", leaving it in an unusable state from the get-go. – Mike Gibson Dec 16 '13 at 18:35
  • Is your flag declared as `volatile`? Try posting the problematic function. – egur Dec 16 '13 at 19:59
  • that is TOTALLY what it was. Thank you, egur. I'm fairly new to programming for hardware, so I didn't have a very strong grasp of volatility. – Mike Gibson Dec 16 '13 at 21:15
  • also, can I not upvote your answer since it was a comment? I'm new to stack overflow too. – Mike Gibson Dec 16 '13 at 21:22

1 Answers1

1

Is your flag declared as volatile? Try posting the problematic function. – egur

that is TOTALLY what it was. Thank you, egur. – Mike Gibson

Armali
  • 18,255
  • 14
  • 57
  • 171