recognisable idiom -- idle question

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	tx_buffer[3] = vserial>>24;
 450:	89 2f       	mov	r24, r25
 452:	99 27       	eor	r25, r25
 454:	aa 27       	eor	r26, r26
 456:	bb 27       	eor	r27, r27
 458:	80 93 81 00 	sts	0x0081, r24

looking at that code, obviously the compiler has recognised that vserial>>24 selects the top byte: it hasn't tried to do 24 shifts. So it has recognised the right side of the equation.

But it hasn't recognised that taken together the whole assignment statement is a recognisable idiom.

Is this generally true about GCC? Can it only recognise idioms on the right of the assignment? It seems odd, given that vserial>>24 is not a sequence point?

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

How is vserial and tx_buffer declared? I assume, given what you have said, that vserial is 32-bits and tx_buffer is eight. Obviously what it is missing is that it need not keep the values in r25-r27 correct, it is still thinking in 32-bits. Try casting the result of the shift to 8-bits before the assignment, it may give the optimizer the hint.

And yes, I have seen this sort of thing before. It is a perennial problem with the 8-bit code produced by gcc and is, to a large extent, a result of the type promotion rules in C. That's not to say that gcc couldn't be a bit more aggressive with its optimization at times, but it does at least try to do the right thing as far as the standard is concerned.

Martin Jay McKee

As with most things in engineering, the answer is an unabashed, "It depends."

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

mckeemj wrote:
a result of the type promotion rules in C. That's not to say that gcc couldn't be a bit more aggressive with its optimization at times, but it does at least try to do the right thing as far as the standard is concerned.

Martin Jay McKee

Hmm yes, all your assumptions about the code were true.

So there isn't actually any type promotion: it's a 32 bit number which is first shifted into a 32 bit number.

I was more wondering about the way GCC works internally, which I don't know anything about. I guess I'm observing that GCC appears to break the code down into small units before compiling. Surely it must have some smarts better than that? I mean, to re-order code, it can't be doing that at the register level can it?

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

I believe no single person comprehends the whole of GCC :)

Compilers tend to compile into an intermediate language first, the so-called back end converts this to the instruction of the specific platform. This is very crude code that needs to be optimized, which is a separate step.

IIRC GCC also has a front-end, that parses C into internal structures before it compiles that into the intermediate language, so it can also compile a completely different language like Pascal or Ada.

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

GCC has a front-end which parses the sourcecode and converts it into a language-independent intermediate form, a middle-end which performs processor-independent optimizations on the intermediate form and a machine-dependent backend which transforms the intermediate form into machine language (or bytecode or whatever) and performs machine-specific optimizations.

This separation means that to add support for a new language you only need a new frontend, and to add support for a new CPU you only need a new backend. All languages and targets also benefit from improvements to the middle-end.

In some cases the linker will perform some additional optimizations, and this step will likely increase in significance in the future (for instance, linking with Microsoft's Visual Studio is disproportionately slower than compiling the sourcecode because a lot of code generation steps have been moved into the linker in order to be able to perform optimizations on the whole program instead of on individual modules).