problem with optimization

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem with optimization

3,054 Views
doom
Contributor I

I use cw6.4 and when I use optimization it comes out an annoying problem.

the optimization setting are:

            optimization level 4;

            IPA FILE level  optimization;

 

codes as follows:

void Delay20(void)
{                                                       

    KEYCNT=0;
    while(KEYCNT<=19)
    {
//    asm{NOP};                           
    }


}

 

If I do not use  asm{NOP}; the result of disassmble are :

; 2808: void Delay20(void)
; 2809: {                                                         
; 2810: 
; 2811:     KEYCNT=0;
; 2812:     while(KEYCNT<=19)
; 2813:     {
; 2814: 
; 2815: //    asm{NOP};                             
;
0x00000000                    _Delay20:
;                             Delay20:
0x00000000  0x4E560000               link     a6,#0
;
; 2816:     }
; 2817: 
; 2818: 
;
0x00000004  0x60FE                   bra.s    *+0                   ; 0x00000004
;
; 2819: }
0x00000006  0x4E71                   nop     

 

 

And if use  asm{NOP};  the result of disassmble are :

 

 ; 2807: //~~~~~~~delay20ms~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
; 2808: void Delay20(void)
; 2809: {                                                        
; 2810:  
;
0x00000000                    _Delay20:
;                             Delay20:
0x00000000  0x4E560000               link     a6,#0
;
; 2811:     KEYCNT=0;
; 2812:     while(KEYCNT<=19)
; 2813:     {
; 2814:  
;
0x00000004  0x42B900000000           clr.l    _KEYCNT
0x0000000A  0x7013                   moveq    #19,d0
0x0000000C  0x6002                   bra.s    *+4                   ; 0x00000010
;
; 2815:     asm{NOP};                            
;
0x0000000E  0x4E71                   nop      
;
; 2816:     }
; 2817:  
; 2818:  
;
0x00000010  0xB0B900000000           cmp.l    _KEYCNT,d0
0x00000016  0x64F6                   bcc.s    *-8                   ; 0x0000000e
;
; 2819: }
0x00000018  0x4E5E                   unlk     a6
0x0000001A  0x4E75                   rts      

 

why thy are so different ?It is quite annoying>...

Labels (1)
0 Kudos
Reply
6 Replies

1,736 Views
ChrisJohns
Contributor I

Is KEYCNT global  and updated else where, ie interrupt ?

 

If so declare it volatile and the compiler should do the right thing.

 

0 Kudos
Reply

1,736 Views
doom
Contributor I

Hi

Thanks for your reply.In fact the variable KEYCNT is really updated in a periodic  interrupt.My project works well now.BUT I did not quite catch you.You mean Variables assigned to registers through compiler optimization may be corrupted during execution? If so ,where? Would you plz explain it some further more? 

 

Thanks 

Doom.

Message Edited by doom on 2009-03-31 02:31 AM
0 Kudos
Reply

1,736 Views
jbezem
Contributor III

No, nothing will get 'corrupted', but a variable that is otherwise not used in a loop may get optimized away. Declaring it 'volatile' tells the compiler that the variable may get updated outside of the scope visible to the compiler, so it needs to re-read that variable every time it wants to use the variable.

In your case, the variable apparently was not  declared 'volatile', so the compiler assumed it knew everything there was to know about KEYCNT, and since no modification was visible in the code (without the NOP), the variable was optimized away.

Inserting the NOP, the compiler didn't know at least a small part of the code, so it couldn't optimize as aggressively, even though no 'volatile' was used.

 

If you will, I wrote an article on 'volatile' (and 'const', but that's not relevant here; 'restrict' is mentioned, but not yet included...), which you may find at http://www.bezem.de/pdf/tqinc.pdf.

 

HTH,

 

Johan

0 Kudos
Reply

1,736 Views
doom
Contributor I

Hi

Thanks again!

I have read your article .The last part is a little complicated but it is very helpful.

 

 

 

Regards

 

doom

0 Kudos
Reply

1,736 Views
jbezem
Contributor III

Well, they are not so different to me.

First, your loop seems to be an endless loop, since KEYCNT is never incremented after initialization.

So the first compilation without asm(NOP) simply implements this endless loop by a branch instruction jumping onto itself. 'unlk' and 'rts' are not necessary, since this loop will never exit.

And since the compiler doesn't know anything about the inline assembler code, adding the asm(NOP) will need to include this assembler instruction in the final code, then checking the value of KEYCNT once more just in case the assembler code has changed the value of KEYCNT without the C compiler knowing anything about it. It will remain endless, of course...

 

HTH,

 

Johan

0 Kudos
Reply

1,736 Views
doom
Contributor I

Hi Johan

As a matter of fact, KEYCNT is updated in an interrupt.I take Chris’ advice and my project is working well.Tanks all the same.

 

regards

doom

0 Kudos
Reply