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
  • You'll have a hard time arguing that this would be a useless optimization.

    Actually, it's trivially easy to win that argument, because in the case at hand it would be worse than useless --- it'd be flat-out wrong. puts() doesn't do the same thing as printf().

    And why are you accusing the OP of not knowing what he is talking about?

    Because he doesn't. While his first example is at least questionable, the other two are just wrong.

    In item 2. his observation about strings constants not being folded is simply incorrect. One doesn't even have to look at generated code ... it doesn't even grow as much as it would have to if his complaint were true.

    In item 3. his code doesn't do what he thinks it's doing --- there is no bit test in there.

Reply
  • You'll have a hard time arguing that this would be a useless optimization.

    Actually, it's trivially easy to win that argument, because in the case at hand it would be worse than useless --- it'd be flat-out wrong. puts() doesn't do the same thing as printf().

    And why are you accusing the OP of not knowing what he is talking about?

    Because he doesn't. While his first example is at least questionable, the other two are just wrong.

    In item 2. his observation about strings constants not being folded is simply incorrect. One doesn't even have to look at generated code ... it doesn't even grow as much as it would have to if his complaint were true.

    In item 3. his code doesn't do what he thinks it's doing --- there is no bit test in there.

Children
  • Having actually looked at the examples, I can see that he is wrong about all of them. Obviously, I jumped to conclusions because I do believe that C51 isn't as good at optimization as it should be.
    The OP hasn't done his homework. Sorry for the noise.

  • You mean, isn't as good as it could be.

  • Yes, The compiler has removed the duplicate string i confirmed it.
    Very Sorry for the wrong statement.

    But The other two are correct.
    The bit test and the
    printf to puts

    Even though the printf function is a complete different & complicated one,
    when we use no var_arg ie when we use it only to print constant strings then it is completely equivalent to puts.Whether this is done by comiler or linker is not a quetion here.
    So there is no point in using bulky printf instead puts.

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

    The processor's architecture allows for bit test instruction and the compiler did not use that single instruction but used three instructions instead.

  • Look again at your 'C' code - carefully!

    Your 'C' code does not perform a bit test!

    Your 'C' code is just using the standard 'C' exclusive-OR operator...

  • But the compiler knows i test for the bit...

  • when we use [printf] only to print constant strings then it is completely equivalent to puts.

    So you believe --- but that belief is incorrect. Check your facts before you repeat incorrect statements like that. Read the specification of puts() again, carefully.

    The processor's architecture allows for bit test instruction and the compiler did not use that single instruction but used three instructions instead.

    But your code doesn't specify any bit test instruction, so it would have been quite wrong for the compiler to use one. Like I said before, that '^' operator doesn't do what you think it does.

  • if the optimiser uses puts instead printf only when possible then we can reduce the size of the code and increase the speed both at the same time without causing any harm at all.

    1.I did not mean to complain it was a mistake by the compiler.Here i am talking about improvement not mistake.

    2.If it did replace the printf with puts where possible then it would improve the code efficiency and increase the speed.

    3.If we turn off the optimiser then it was not neccessary to replace printf with puts.

    4.The job of the optimiser to my knowledge is to reduce code and increase speed.That is what everybody would like.

    5.Let me know what harm it will do if the optimser replaces (only when possible)printf("Testing"); with puts("Testing");.

    5.Again the compiler knows that i am testing for the bit.And when the optimizer sees the code it should produce the smallest code possible.

    6.Let me know the harm done when the optimiser uses bit test instruction instead of xor.

    The advantage of using puts("This must call puts instead of printf"); instead of printf("This must call puts instead of printf");

    1.Code size reduction
    2.Increase in speed

    Disadvantage NONE

    Let me know if you know the disadvantage... puts over printf

    The advantage of JNB over MOV,XRL and JZ

    1.On instruction instead of three
    2.Increase in speed.

    Disadvantage NONE

    Let me know if you know the disadvantage... JNB over MOV,XRL and JZ

    It is only in the interest of improving the compiler

  • if the optimiser uses puts instead printf only when possible

    What you still don't get is that it in the case at hand, it is not possible.

    then we can reduce the size of the code

    No we can't. That only works if you can replace all printf()s by puts() --- not just some of them. The call to printf() uses exactly as much code space as the one to puts(), and the code for printf() itself will not go away as long as even a single irreducible use of printf() remains.

    5.Let me know what harm it will do if the optimser replaces (only when possible)printf("Testing"); with puts("Testing");.

    Since that's never possible, the question is moot.

    5.Again the compiler knows that i am testing for the bit.

    No, it doesn't. Because you're not. The compilers knows what you actually wrote, not what you think you did.

    And you've been told that about half a dozen times now. It's high time you start listening, instead of just repeating your incorrect claims.