[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug)

From: Szikra Istvan
Subject: Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug)
Date: Sun, 28 Mar 2010 15:37:16 +0200

>> If it's generating calls from my function (unwanted), it could be so
>> kind to put the callee next to the caller.
> It's the linker doing that, and it's simply not smart enough to handle
> that.  It would require to include functions from libgcc.a twice, once
> per section.
Yes it might. And it probably would raise problems for other codes.
Maybe we need some kind of "-keep-section-together=.bootloader" linker
option. (But that would not solve every problem)
My problem here is caused partly because the tool-chain is not in
sync: the compiler is thinking it's being smart, but the linker is
not. The compiler generates function calls from a peace of code, but
does not tell the linker to keep it together. Probably the compiler
doesn't even know, because it doesn't see the big picture. But I do!
so how do I tell the compiler to stop messing around, and I know what
I'm doing so leave that part of the code alone, or stop recognizing
that pattern in the entire project?

>>> Rule of thumb: whenever you are tempted to create a separate
>>> ..bootloader section, you are usually wrong.  The bootloader is simply
>>> a standalone application of its own, so compile/link it that way.
>> In this case you are wrong. [...]It's not a bootloader
> Yes, that's the exception, and that's why I wrote "usually". ;-)
I don't really want this to turn into a discussion about semantics. I
just want to point out that I did not mean that you are wrong about
the rule of thumb. I just meant that your assumption (it being a
standalone bootloader ) was (probably) wrong. (but maybe you knew
-that it was not a bootloader- and just made an unrelated comment
about bootloaders :) Sorry that I did not express myself clearly.

>> Please stop making the compiler "think" it's smarter than me!

This was just a shout out for compiler builders everywhere :)
not directed at anyone particular, and thank you for your explanation

> programmers
> usually *do want* the compiler to optimize the resulting code.
As do I, but there is so much other more important things to optimize
I think any programmers who writes a loop instead of a modulo or
divide by mistake really deserves the result. (Or know why they do it)

> optimization is a large process, mostly being done at the level where
> the compiler is still fairly independent of the target machine (it's
> just got some kind of abstraction of that machine inside),
And this is not target independent, I don't think on x86 this
generates a call to a simple 'div' instruction. The problem here is
that this uC does not have div instruction and it's implemented as a
function. Maybe there is a target specific cost of divide, and that's
not set properly (?)
I don't know where does this happen, and i know writing good optimizer
is really hard, that's why it should not optimize silly stuff. only
stuff programmers really need.

> there is
> nothing like a simple knob where you could tell: "So please, turn just
> *this* optimization off for an AVR."
ohh, but it would be nice, and really I would only need "turn just
*this* optimization off." (for every target)
And ppl who relay on this specific optimization should learn basic C
operators. (IMHO, sorry if this sounds arrogant, but % is shorter and
seems clearer to me, maybe I'm not seeing the point, missing
something? )

Ok, I realize there at least 2 separate issue:
1/ this specific "optimization" (which I would think no one really
need, the writer of the optimizer just had a boring or bad day)
2/ other cases where the compiler generates library calls (be it a
sin, cos, .. function) and they get into wrong section
(on Neuman architecture this is usually hardly a problem except maybe
for near/far pointers, on Harvard architecture the separation of code
and data usually enough, but not always)

On the first: I think (hope) at this point my opinion is clear for
everyone. I hope I did not upset anyone.
On the second: I don't see an easy universal fix. I think it will
always need manual override. The programmer who sees the big picture
should tell the compiler/linker (or whatever) how it should be handled
/ where should it go.
The coder should have the option of manual override:
A/ should library calls be inlined or not (globally or a call-by-call basis)
B/ (if not) which section should the library functions go to

Is A,B possible? How do I do it? linker script? special pragma/attribute?

A few ideas (of course they don't work):
volatile  while (m>=3){
__attribute__((always_inline)) while (m>=3){
__attribute__ ((section (".bootloader"))) while (m>=3){

> If you want something that doesn't optimize your code,
Of course I want c to optimize, but i don't see which way could this
be considered optimization (in this case).
(maybe in speed it does better for large inputs but I'm using -Os,
maybe the optimizer could have some extra input like Maple command
assume( m < 10 );, but it's clearly not that smart because it uses the
same code for m=(PORTA & 0x0f))
For example efforts on automatic vectorization (on x86,x64) are well
spent (IMHO).

> then please use assembly language
I'm already using it for hot spots. (In my understanding that's how
assembly and higher level languages should be used together)
The question is: is it possible to generate at least working code
without resorting to assembly. (to have at least a bit of portability)
Or is it the only viable workaround?

> C compilers are not for you then.  They have been passing your level
> of understanding (being a "high-level language assembler") about 20
> years ago.
I'm not really sure what you mean so I just make a comment: I'm
painfully aware that C is not a HLA. For example on x86 the div
instruction provides both div and mod result in a register pair, where
in C there is no language element for that, a mul word*word results in
a double-word on the hardware, but in C you need to cast the source
operands first, there are many kind of shifts, adc..., but in C there
is no carry handling...
I only want C to produce half decent code, and I rewrite what I must.
I'm not keen to write trigonometric functions in assembly...
It does not bother me so much if the compiler misses some
optimization, if it's getting better. But it seems since gcc 4 the
generated code is getting worse-and-worse for 8 bit platforms. So
maybe gcc 4 is not for me. (maybe it should be used for 32 bit
micro-controllers like ARM and higher)
I really appreciate any effort, considering it's free. I intended
everything only as constructive criticism, so future compilers might
be more flexible and better for everyone. I don't enjoy doing things
if it only wasting my and others time.

>> With this pattern recognition the compiler's writer might made some
>> shitty programmers code better, but made a decent programmers code
>> worse...
> I don't think you are in a position to make such a claim.  It simply
> sounds arrogant.
Ok, it was wrong choice of words, I'm sure they are all kind people
who enjoy writing loops instead of modulo just for fun or a result of
oversight.:) And you are right I don't have the statistics how many
percent of codes these kind of loops occur. It might be very well
something for the optimizer to look for. It was wrong of me to assume
otherwise. I still think writing better code is the right way.
And not taking the choice out of the programmers hand by the
optimizer. Maybe the answer would be a warning message: "Did you meant
to write modulo % or divide /" so ppl can choose if they really want
loop or not. (emphasis on choice)

Thanks in advance for any solution, suggestion, (besides writing it in
assembly which I'll most likely end up doing at this point)
Regards Istvan

reply via email to

[Prev in Thread] Current Thread [Next in Thread]