This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: problems with optimisation


On 28/12/12 18:14, Kicer wrote:
Dnia piÄtek 28 grudnia 2012 17:33:59 David Brown pisze:
On 28/12/12 16:19, Andrew Haley wrote:
With -O2 there's much less difference:

bar(): bar():

.LFB14:								.LFB14:
	.cfi_startproc							.cfi_startproc
	movl	$3, %edx						movl	$3, %edx
	in %dx, %al							in %dx, %al
	
	movb	$6, %dl					      |		movb	$4, %dl
	movl	%eax, %ecx						movl	%eax, %ecx
	in %dx, %al							in %dx, %al
	
							      >		movb	$6, %dl
							      >		movl	%eax, %edi
							      >		in %dx, %al
	
	movb	$7, %dl							movb	$7, %dl
	movl	%eax, %esi						movl	%eax, %esi
	
							      >		andl	$1, %edi
	
	in %dx, %al							in %dx, %al
	
	movl	%eax, %edi				      |		movl	%eax, %r8d
	
							      >		movsbl	%sil, %esi
	
	movb	$8, %dl							movb	$8, %dl
	subb	%dil, %cl				      |		subb	%r8b, %cl
	in %dx, %al							in %dx, %al
	
	andl	$16, %esi				      |		addl	%edi, %ecx
	
							      >		testb	$16, %sil
	
	setne	%dl							setne	%dl
	
							      >		andl	$1, %esi
	
	addl	%edx, %ecx						addl	%edx, %ecx
	
							      >		subb	%sil, %cl
	
	testb	$16, %al						testb	$16, %al
	setne	%al							setne	%al
	subb	%al, %cl						subb	%al, %cl
	movl	%ecx, %eax						movl	%ecx, %eax
	ret								ret

Without inlining GCC can't tell what your program is doing, and by using
-Os you're preventing GCC from inlining.

Andrew.

There are normally good reasons for picking -Os rather than -O2 for small microcontrollers (the OP is targeting AVRs, which typically have quite small program flash memories).

So the solution here is to manually declare the various functions as
"inline" (or at least "static", so that the compiler will inline them
automatically).  Very often, code that manipulates bits is horrible on a
target like the AVR if the function is not inline, and the compiler has
the bit number(s) as variables - but with inline code generation and
constant folding, you end up with only an instruction or two for
compile-time constant bit numbers.

(To the OP) - also note that there can be significant differences in the
types of code generation and optimisations for different backends.  I
assume you posted x86 assembly because you thought it would be more
familiar to people on this list, but I think it would be more important
to show the real assembly from the target you are using as you might see
different optimisations or missed optimisations.

Finally, there is a mailing list dedicated to gcc on the avr - it might
be worth posting there too, especially if you think the issue is
avr-specific.

David

David: you are right - I used x86 due to its popularity ;)


In my real case I'm observing weird thigs (speaking of inline):

1. when in my code I use -Os and inline functions - gcc doesn't inline code
(and AFAIR, generates warning about it wont't inline because code would
grown).
Code looks funny then:

00000044
<_ZNK7OneWire14InterruptBasedILt56ELh4EE10releaseBusEv.isra.0.1569.1517>:
   44:	bc 98       	cbi	0x17, 4	; 23
   46:	08 95       	ret


plus a few calls like: rcall .-262 ; 0x44 <_ZNK7OneWire14InterruptBasedILt56ELh4EE10releaseBusEv.isra.0.1569.1517>


those calls are completly useless as 'cbi' could be placed instead of them, and the whole function actually consists of 1 command (except ret). This is quite important for me as I loose certain amount of clock ticks here :)

2. when I use -Os and always_inline attribute, I get a messy code like in my
first message (program gets bigger by 70%, and uses 2-3x more stack which is
half of available memory).


It's hard to place whole avr program here as it's big, and it's difficult to introduce a smaller exmaple, because it's getting messy only when program gets bigger.

Andrew: it's inconvenient to use O2 as Os produces a progam which size is 30%
of O2's result.

regards


With -Os, the compiler will obey normal "inline" directives (at least, that is my experience when compiling C on the avr - I have not tried C++ much on it). It won't do any automatic extra inlining, except for static functions that are only used once - which are always inlined as this saves space. Again, I don't know how that plays with template functions or other C++ features.


As far as I know, gcc uses weighting heuristics to decide whether to do something the rcall you mentioned above, compared to using the inlined code directly. It is certainly not impossible that the weightings are not optimal here.

There is currently very little use of C++ with avr-gcc. The avr port maintainers and the avrlibc developers have little experience with C++, and feel they have enough to do with just the C support. But there are a few people on the avr-gcc mailing list that work with C++, and it is certainly worth posting there too - they may be able to give suggestions.

<https://lists.nongnu.org/mailman/listinfo/avr-gcc-list>

mvh.,

David


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]