No interrupts in Optimized compilation

Started by abufadel September 8, 2007
Greetings,
Whenever I turn on the optimization flag (-O3) from (-O0), the
resulting code does not seem to run when downloaded to the 2106.

Any ideas?

Thank you,

A

An Engineer's Guide to the LPC2100 Series

> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of abufadel
> Sent: Saturday, September 08, 2007 4:30 PM
> To: l...
> Subject: [lpc2000] No interrupts in Optimized compilation
> Greetings,
> Whenever I turn on the optimization flag (-O3) from (-O0), the
> resulting code does not seem to run when downloaded to the 2106.
>
> Any ideas?
>
> Thank you,
>
> A
>

There is a known bug in GCC that breaks the interrupt handling code
if optimizations are enabled. You can optimize all of the code,
except anything that is in the interrupt handlers, and it should
work ok.

I would recommend that you use interrupt stubs instead of using the
built in interrupt handling of GCC. There have been many discussions
on this list regarding this, so search the past messages.

Mike
And generally don't use -O3, it's severely broken overall.
Try -O2 or -O1 first.

Baldur

On Sat, Sep 08, 2007 at 05:34:41PM -0600, Michael Anton wrote:
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of abufadel
> > Sent: Saturday, September 08, 2007 4:30 PM
> > To: l...
> > Subject: [lpc2000] No interrupts in Optimized compilation
> >
> >
> > Greetings,
> > Whenever I turn on the optimization flag (-O3) from (-O0), the
> > resulting code does not seem to run when downloaded to the 2106.
> >
> > Any ideas?
> >
> > Thank you,
> >
> > A
> > There is a known bug in GCC that breaks the interrupt handling code
> if optimizations are enabled. You can optimize all of the code,
> except anything that is in the interrupt handlers, and it should
> work ok.
>
> I would recommend that you use interrupt stubs instead of using the
> built in interrupt handling of GCC. There have been many discussions
> on this list regarding this, so search the past messages.
>
> Mike
>
--- In l..., Baldur Gislason wrote:
>
> And generally don't use -O3, it's severely broken overall.
> Try -O2 or -O1 first.
>

I can't say I'd agree with this - we use -O3 for everything (including
ISRs - but then we use stubs and ISRs are just like any other function).

Anyway, we've found that -O3 generally gives the best results, and have
never had a problem with it.

Brendan
--- In l..., "Brendan Murphy"
wrote:
>
> --- In l..., Baldur Gislason wrote:
> >
> > And generally don't use -O3, it's severely broken overall.
> > Try -O2 or -O1 first.
> > I can't say I'd agree with this - we use -O3 for everything
(including
> ISRs - but then we use stubs and ISRs are just like any other
function).
>
> Anyway, we've found that -O3 generally gives the best results, and
have
> never had a problem with it.
>
> Brendan
>

I should add, by the way, that we use GCC 3.3.1, which I believe is a
pretty old version.

Rather old and reliable than new and unreliable, though.....
> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Brendan Murphy
> Sent: Sunday, September 09, 2007 12:48 PM
> To: l...
> Subject: [lpc2000] Re: No interrupts in Optimized compilation
> --- In l..., "Brendan Murphy"
> wrote:
> >
> > --- In l..., Baldur Gislason wrote:
> > >
> > > And generally don't use -O3, it's severely broken overall.
> > > Try -O2 or -O1 first.
> > >
> >
> > I can't say I'd agree with this - we use -O3 for everything
> (including
> > ISRs - but then we use stubs and ISRs are just like any other
> function).
> >
> > Anyway, we've found that -O3 generally gives the best results, and
> have
> > never had a problem with it.
> >
> > Brendan
> > I should add, by the way, that we use GCC 3.3.1, which I believe is a
> pretty old version.
>
> Rather old and reliable than new and unreliable, though.....
>

Well, I use GCC V4.1.1, and always use -O3 for everything, though
I also use interrupt stubs, and I have had no problems.

I would be interested in knowing what the problems (if any) are
however.

Mike
At -O3 at higher, gcc will begin inlining functions, which *might*
interact badly with the __attribute__("interrupt") functionality. I'm
speculating on that, however, I *can* tell you how I make my ISRs safe
with aggressive optimizations, without using assembly stubs.

In my own code, most of my interrupts can cause a context switch, so the
automagic __attribute__("interrupt") code is not appropriate. (Instead,
I need to save the process state to a task record, not the stack.) I use:

static void emac_irq(void) __attribute__ ((naked));
static void emac_irq(void)
{
// be very careful not to do anything that can cause stack allocation.
IRQ_TASK_SAVE; // save processor state to task record
emac_irq_real();
IRQ_TASK_RESTORE; // restore processor state from task record
}

void emac_irq_real(void) __attribute__ ((noinline));
void emac_irq_real()
{
// now you can use stack storage.
// the scheduler can also change the currently running task.
}

Note that the function emac_irq_real() is tagged with "noinline". This
is important: if emac_irq_real was inlined, it would cause any stack
allocations to be performed in the prologue of emac_irq-- *before* I had
a chance to save the state.

While I typically compile with -Os (best compromise of speed versus
space for most code), I have tested this at -O3 and -O4 without
problems. (Indeed, it was problems at -O3 and -O4 that caused me to jump
through these hoops.)

Hope this helps,

-Ed
--- In l..., Edwin Olson wrote:
>
> At -O3 at higher, gcc will begin inlining functions, which *might*
> interact badly with the __attribute__("interrupt") functionality.
I'm
> speculating on that, however, I *can* tell you how I make my ISRs
safe
> with aggressive optimizations, without using assembly stubs.
>
> In my own code, most of my interrupts can cause a context switch,
so the
> automagic __attribute__("interrupt") code is not appropriate.
(Instead,
> I need to save the process state to a task record, not the stack.)
I use:
>
> static void emac_irq(void) __attribute__ ((naked));
> static void emac_irq(void)
> {
> // be very careful not to do anything that can cause stack
allocation.
> IRQ_TASK_SAVE; // save processor state to task record
> emac_irq_real();
> IRQ_TASK_RESTORE; // restore processor state from task record
> }
>
> void emac_irq_real(void) __attribute__ ((noinline));
> void emac_irq_real()
> {
> // now you can use stack storage.
> // the scheduler can also change the currently running task.
> }
>
> Note that the function emac_irq_real() is tagged with "noinline".
This
> is important: if emac_irq_real was inlined, it would cause any
stack
> allocations to be performed in the prologue of emac_irq-- *before*
I had
> a chance to save the state.
>
> While I typically compile with -Os (best compromise of speed versus
> space for most code), I have tested this at -O3 and -O4 without
> problems. (Indeed, it was problems at -O3 and -O4 that caused me to
jump
> through these hoops.)
>
> Hope this helps,
>
> -Ed
>

Ed,

My personal preference now for stuff like this, having been bitten
several times over the years with compiler's behaviour when doing
stuff like this, is to avoid as much as possible ANY compiler
extensions.

Some stuff just can't be done with standard 'C' (or whatever language
you happen to be using), such as manipulating stacks, context
switching etc. For these, a short assembler function can be used.

There's no doubt you can solve most compiler issues like the example
you give with compiler options/pragmas/extensions, if you dig deep
enough into the issues and spend enough time at it, but my own
preference would be to avoid them as much as possible, for that very
reason (i.e. the amount of time you have to spend).

Brendan
> My personal preference now for stuff like this, having been bitten
> several times over the years with compiler's behaviour when doing
> stuff like this, is to avoid as much as possible ANY compiler
> extensions.
I absolutely respect that position. In my own case, GNU tools are my
desired destination and so I'm willing to use GCC extensions, whereas
I'd be unwilling to dive in as deeply with other toolchains. Time and
effort invested into learning the ins & outs of GCC has had a recurring
payoff even as I've migrated from architecture to architecture. Your
mileage may vary!

-Ed
Hi,

> And generally don't use -O3, it's severely broken overall.
> Try -O2 or -O1 first.

I find -O3 to work OK. My firmware is compiled with -O3 and works
perfectly. I recognize that there may be a class of source for which it
doesn't work, but in my experience if you have problems with -O3 it's
because "volatile" isn't applied correctly.

-- Paul