This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler optimisation

Hello,

1.when i use printf with no var_args then the compiler should call puts instead of printf.

ex1:


#include <REGX51.H>
#include <stdio.h>

void main(void)
{
        printf("This must call puts instead of printf");
}


Program Size: data=30.1 xdata=0 code=1103

ex2:


#include <REGX51.H>
#include <stdio.h>

void main(void)
{
        puts("This must call puts instead of printf");
}


Program Size: data=9.0 xdata=0 code=168

The above code links the printf function from the library which is huge(produces 1103 bytes).But the compiler can use puts when there is no var_args given which is much smaller than printf(produces 168 bytes).

2.The Compiler must find and remove the duplicate constant strings

ex3:


#include <REGX51.H>
#include <stdio.h>

void main(void)
{
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
        puts("This string gets duplicated as many time as i use it");
}


Program Size: data=9.0 xdata=0 code=334

ex4:


#include <REGX51.H>
#include <stdio.h>

void main(void)
{
        puts("This string gets duplicated as many time as i use it");
}


Program Size: data=9.0 xdata=0 code=183

3.Bit Test instructions are not used when i actually test for the bit

ex5:


#include <REGX51.H>
#include <stdio.h>


void main(void)
{
        if(P0^1)
        {
                P1 = 10;
        }

}


ASSEMBLY LISTING OF GENERATED OBJECT CODE

             ; FUNCTION main (BEGIN)
                                           ; SOURCE LINE # 6
                                           ; SOURCE LINE # 7
                                           ; SOURCE LINE # 8
0000 E580              MOV     A,P0
0002 6401              XRL     A,#01H
0004 6003              JZ      ?C0002
                                           ; SOURCE LINE # 9
                                           ; SOURCE LINE # 10
0006 75900A            MOV     P1,#0AH
                                           ; SOURCE LINE # 11
                                           ; SOURCE LINE # 13
0009         ?C0002:
0009 22                RET
             ; FUNCTION main (END)

In the above assembly output it should have used a single instruction JNB instead of three MOV,XRL and JZ.This is very basic anybody would object the assembly code produced.

I have not used the compiler much.But the compiler needs a look by the programmers at keil.

The above programs were all compiled with compiler optimisation level set to 9 & favour speed.

About 5 years back i compiled a c51 source code using keil.
Now i recompiled the same source code with the latest compiler from keil and compared the two output .hex files.
Unfortunately it produced exactly the same output.Here i was expecting some code and data size reduction as the compiler must be capable of optimising more.

It seems there was no improvement on the compiler side.

It is not a complaint but in the interest of improving the compiler.

regards,

S.Sheik mohamed

Parents
  • Hello All,

    Thank you all for keeping patience with me.

    I agree that all my allegations were complete wrong.

    1.when i use printf with no var_args then the compiler should call puts instead of printf.

    puts Adds extra linefeed to the string so it cannot be used instead of printf.So i was wrong here.

    But i think the compiler could be supplied with different versions of printf and let the user decide which printf version is best for him.This way compiler & linker need not struggle to find the best printf.

    The optimiser should have used a counter and repeated the following block

    
        MOV     R3,#0FFH
        MOV     R2,#HIGH ?SC_0
        MOV     R1,#LOW ?SC_0
        LCALL   _puts
    
    

    2.The Compiler must find and remove the duplicate constant strings

    No the compiler allocates the string only once.it was again my mistake

    3.Bit Test instructions are not used when i actually test for the bit

    I must have used (P0 & 1) instead of (P0 ^ 1) again my mistake.

    But when i use (P0 & 1) the compiler understood my intention of bit testing but it has assembled it in a different way.

    #include <REGX51.H>
    #include <stdio.h>
    
    
    void main(void)
    {
            if(P0 & 1)
            {
                                    if(P0_1)
                                    {
                    P1 = 10;
                                    }
            }
    
    }
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 5
                                               ; SOURCE LINE # 6
                                               ; SOURCE LINE # 7
    0000 E580              MOV     A,P0
    0002 30E006            JNB     ACC.0,?C0003
                                               ; SOURCE LINE # 8
                                               ; SOURCE LINE # 9
    0005 308103            JNB     P0_1,?C0003
                                               ; SOURCE LINE # 10
                                               ; SOURCE LINE # 11
    0008 75900A            MOV     P1,#0AH
                                               ; SOURCE LINE # 12
                                               ; SOURCE LINE # 13
                                               ; SOURCE LINE # 15
    000B         ?C0003:
    000B 22                RET
                 ; FUNCTION main (END)
    
    

    where it could have simply put "JNB P0_1" instead of "mov a,P0" & "jnb ACC.0"

    But overall if you compile a source file using an old version of the compiler and again with the new version of the compiler the produced hex file is byte to byte same.

    Why the compiler or its optimizer has not improved in reducing the code & data size for many years.

    Once again thank for all your patience

    S.Sheik mohamed

Reply
  • Hello All,

    Thank you all for keeping patience with me.

    I agree that all my allegations were complete wrong.

    1.when i use printf with no var_args then the compiler should call puts instead of printf.

    puts Adds extra linefeed to the string so it cannot be used instead of printf.So i was wrong here.

    But i think the compiler could be supplied with different versions of printf and let the user decide which printf version is best for him.This way compiler & linker need not struggle to find the best printf.

    The optimiser should have used a counter and repeated the following block

    
        MOV     R3,#0FFH
        MOV     R2,#HIGH ?SC_0
        MOV     R1,#LOW ?SC_0
        LCALL   _puts
    
    

    2.The Compiler must find and remove the duplicate constant strings

    No the compiler allocates the string only once.it was again my mistake

    3.Bit Test instructions are not used when i actually test for the bit

    I must have used (P0 & 1) instead of (P0 ^ 1) again my mistake.

    But when i use (P0 & 1) the compiler understood my intention of bit testing but it has assembled it in a different way.

    #include <REGX51.H>
    #include <stdio.h>
    
    
    void main(void)
    {
            if(P0 & 1)
            {
                                    if(P0_1)
                                    {
                    P1 = 10;
                                    }
            }
    
    }
                 ; FUNCTION main (BEGIN)
                                               ; SOURCE LINE # 5
                                               ; SOURCE LINE # 6
                                               ; SOURCE LINE # 7
    0000 E580              MOV     A,P0
    0002 30E006            JNB     ACC.0,?C0003
                                               ; SOURCE LINE # 8
                                               ; SOURCE LINE # 9
    0005 308103            JNB     P0_1,?C0003
                                               ; SOURCE LINE # 10
                                               ; SOURCE LINE # 11
    0008 75900A            MOV     P1,#0AH
                                               ; SOURCE LINE # 12
                                               ; SOURCE LINE # 13
                                               ; SOURCE LINE # 15
    000B         ?C0003:
    000B 22                RET
                 ; FUNCTION main (END)
    
    

    where it could have simply put "JNB P0_1" instead of "mov a,P0" & "jnb ACC.0"

    But overall if you compile a source file using an old version of the compiler and again with the new version of the compiler the produced hex file is byte to byte same.

    Why the compiler or its optimizer has not improved in reducing the code & data size for many years.

    Once again thank for all your patience

    S.Sheik mohamed

Children