2011/10/31 Georg-Johann Lay <a...@gjlay.de>: > This is a fix for optimization flaw when dividing int by 2. > > There is really no need for a library call. Costs of [U]DIV/[U]MOD are > adjusted > to take into account the costs of CONST_INT operands that must be loaded for > division by means of libgcc call. > > There are some new combiner patterns suffixed .lt0 that so adjustment > frequently seen when division-by-const in lowered to arithmetic in order to > avoid more expensive libcall. > > Moreover, there are two patterns for adding sign-extended QI to HI. These > patterns are shorter, faster and have lower register pressure than explicitly > sign-extending the QI before adding it. Example code is: > > int add (int a, char b) { return a + b; } > int sub (int a, char b) { return a - b; } > > add: > add r24,r22 ; 13 *addhi3.sign_extend1 [length = 4] > adc r25,__zero_reg__ > sbrc r22,7 > dec r25 > ret > > sub: > sub r24,r22 ; 13 *subhi3.sign_extend2 [length = 4] > sbc r25,__zero_reg__ > sbrc r22,7 > inc r25 > ret > > The reg_overlap_mentioned case is just for pathological code like, e.g. > a + (char) a > so that the expected size is 4 instructions. > > Since beginning of time, BRANCH_COST was set to 0 so that some optimization > passes make code happily jumping around. The patch introduces a new command > line option for that; mainly because I don't know the rationale behind setting > BRANCH_COST to 0. > > Regression-tested. > > Ok for trunk? > > Johann > > * config/avr/avr.opt (-mbranch-cost=): New option. > * config/avr/avr.h (BRANCH_COST): Define to avr_branch_cost. > * config/avr/avr.c (avr_rtx_costs_1): Adjust [U]DIV/[U]MOD costs. > * config/avr/avr.md (*addqi3.lt0, *addhi3.lt0, *addsi3.lt0): New insns. > (*addhi3_zero_extend1): Remov % in constraint of operand 1. > (*addhi3.sign_extend1, *subhi3.sign_extend2): New insns. >
Approved. Denis.