From: Scott D. <sc...@da...> - 2001-10-18 14:02:17
|
Consider this for loop: void for3(void) { unsigned int i=0; for(i=0; i<10; i++) uint0++; if(i < 10) failures++; } The for loop is implemented perfectly, but the subsequent comparison only looks at the low byte of "i" and compares it to zero, not ten. sdcc -mds390 -c for.c This code uses r2:r3 for "i". In line "for.c 53" (00112$:), i is partially set to zero by assigning 0 to just the low byte (r2). Then r2 is compared to 0, but r3 is ignored in the comparison. It looks like there is an optimization in the iCode some place that is trying to switch over to using a byte instead of an integer, but only partially implementing the optimization. ; ----------------------------------------- ; function for3 ; ----------------------------------------- _for3: ; for.c 56 ; genAssign ; genAssign: resultIsFar = TRUE mov r2,#0x0A mov r3,#0x00 ; genLabel 00105$: ; for.c 51 ; genAssign mov dptr,#_uint0 ; genAssign: resultIsFar = FALSE movx a,@dptr mov r4,a inc dptr movx a,@dptr mov r5,a ; genPlus mov dptr,#_uint0 mov a,#0x01 add a,r4 movx @dptr,a ; Peephole 180 changed mov to clr clr a addc a,r5 inc dptr movx @dptr,a ; genMinus dec r2 cjne r2,#0xff,00111$ dec r3 00111$: ; genIfx mov a,r2 orl a,r3 ; genIfxJump ; Peephole 109 removed ljmp by inverse jump logic jnz 00105$ 00112$: ; for.c 53 ; genAssign ; genAssign: resultIsFar = FALSE mov r2,#0x00 ; genIfx mov a,r2 ; genIfxJump ; Peephole 110 removed ljmp by inverse jump logic jz 00106$ 00113$: ; for.c 54 ; genAssign mov dptr,#_failures ; genAssign: resultIsFar = FALSE movx a,@dptr mov r2,a ; genPlus mov dptr,#_failures mov a,#0x01 add a,r2 movx @dptr,a ; genLabel 00106$: ; genEndFunction ret in the pic14: _for3 ;Function start ;; for.c 56 ;; *** resultRemat 2351 ;; *** genAssign 8114 MOVLW 0x0a MOVWF r0x0C CLRF r0x0D _00125_DS_ INCF _uint0,F BTFSC STATUS,2 INCF (_uint0 + 1),F MOVLW 0xff ADDWF r0x0C,F BTFSS STATUS,0 DECF r0x0D,F MOVF r0x0C,W IORWF r0x0D,W BTFSS STATUS,2 GOTO _00125_DS_ ;; for.c 53 ;; *** genAssign 8114 ;; result AOP_REG, right AOP_LIT, size = 1 CLRF r0x0C MOVF r0x0C,W ;;#;; for.c 54 BTFSS STATUS,2 INCF _failures,F _00126_DS_ RETURN |
From: Johan K. <joh...@id...> - 2001-10-18 15:33:47
|
> void for3(void) > { > unsigned int i=0; > > for(i=0; i<10; i++) > uint0++; > > if(i < 10) > failures++; > > } > > > The for loop is implemented perfectly, but the subsequent comparison only > looks at the low byte of "i" and compares it to zero, not ten. > > sdcc -mds390 -c for.c > > This code uses r2:r3 for "i". In line "for.c 53" (00112$:), i is > partially set to zero by assigning 0 to just the low byte (r2). Then r2 is > compared to 0, but r3 is ignored in the comparison. > > It looks like there is an optimization in the iCode some place that is > trying to switch over to using a byte instead of an integer, but only > partially implementing the optimization. What really happens is: i=10; while (i--) uint0++; i=10; This is the loop reversal. The "if (i<10)" is always false, zero is compared with zero and failures is never incremented. So the optimization is correct but could go much further in this case by removing the whole failures thing. Johan |
From: Scott D. <sc...@da...> - 2001-10-18 15:51:21
|
On Thu, 18 Oct 2001, Johan Knol wrote: > > void for3(void) > > { > > unsigned int i=0; > > > > for(i=0; i<10; i++) > > uint0++; > > > > if(i < 10) > > failures++; > > > > } > > <snip> > What really happens is: > > i=10; > while (i--) > uint0++; > i=10; > > This is the loop reversal. > > The "if (i<10)" is always false, zero is compared with zero and failures is > never incremented. So the optimization is correct but could go much further > in this case by removing the whole failures thing. Clever. It indeed passes the regression test, but I thought it looked a little suspicious (actually I thought it was wrong!). Scott |
From: Johan K. <joh...@id...> - 2001-10-18 19:15:09
|
> > This is the loop reversal. > > > > The "if (i<10)" is always false, zero is compared with zero and failures is > > never incremented. So the optimization is correct but could go much further > > in this case by removing the whole failures thing. > > Clever. It indeed passes the regression test, but I thought it looked a > little suspicious (actually I thought it was wrong!). Now that my attention was drawn to it, I brought back a huge optimization in SDCCcse.c:1.54+1.55 so now the whole zero compare and failures thing is removed. And of course Evelyn barks again :). Johan |