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

Common Code Elimination

Common Code Elimination

cortex-m3 uVision 5.13

I recent had to up the optimization level on my project to level 2 because my code size was too large for my target memory. In doing this I found that it seems to be doing common code elimination where valid routines are not being compiled/linked into the image.

This has caused some routines to be practically wiped out because another is very similar but has some differences. I guess they were common enough for the compiler to decide to get rid of one of them.

I have been Googling and searching everywhere for a way to turn off just the common code elimination but cannot find anything that I can use with uVision.

There is a C51 pragma to change the optimization level to stop this on a file by file basis but the uVision compile causes a error.

There must be a way to turn this off. I understand it is trying to save me space but it is also changing or in some cases eliminating functionality.

Does anyone know of a pragma that will work or something I can do?

Thanks

P.S. of course this happens 2 days before a major delivery on a weekend!!

Parents
  • I have to say I would not have posted a question if there was not a problem.

    And I have to say you should then have posted the question describing the actual problem. You left out every single important fact of the matter.

    The set is is basically the same EXECPT I have print statements in this "common looking" code that are different.

    And you're 100% certain that the optimizer cannot possibly have seen through that simple difference and still joined the code correctly, just using two different tables of string constants with the same function, i.e.:

    void f1(void) {
    // code specific to f1
    // common code with strings specific to f1
    }
    void f2(void) {
    // code specific to f2
    // common code with strings specific to f2
    }
    

    by

    char *f1strings[] = {
      //strings specific to f1
    }
    void f1(void) {
    // code specific to f1
      common(f1strings)
    }
    char *f2strings[] = {
    strings specific to f2
    }
    void f2(void) {
    // code specific to f2
      common(f2strings)
    }
    void common(char *strtable[]) {
      // common code using strings from table
    }
    

    Stepping through code that has had common code elimination applied may well be impossible, at least that the source code level. You really have to look at machine code to see what actually happens.

    And then of course there's always the possibility that the code was eliminated for an entirely different reason than you thought. E.g. the optimizer might have found it to be unreachable, or only reachable if there was undefined behaviour leading up to it.

Reply
  • I have to say I would not have posted a question if there was not a problem.

    And I have to say you should then have posted the question describing the actual problem. You left out every single important fact of the matter.

    The set is is basically the same EXECPT I have print statements in this "common looking" code that are different.

    And you're 100% certain that the optimizer cannot possibly have seen through that simple difference and still joined the code correctly, just using two different tables of string constants with the same function, i.e.:

    void f1(void) {
    // code specific to f1
    // common code with strings specific to f1
    }
    void f2(void) {
    // code specific to f2
    // common code with strings specific to f2
    }
    

    by

    char *f1strings[] = {
      //strings specific to f1
    }
    void f1(void) {
    // code specific to f1
      common(f1strings)
    }
    char *f2strings[] = {
    strings specific to f2
    }
    void f2(void) {
    // code specific to f2
      common(f2strings)
    }
    void common(char *strtable[]) {
      // common code using strings from table
    }
    

    Stepping through code that has had common code elimination applied may well be impossible, at least that the source code level. You really have to look at machine code to see what actually happens.

    And then of course there's always the possibility that the code was eliminated for an entirely different reason than you thought. E.g. the optimizer might have found it to be unreachable, or only reachable if there was undefined behaviour leading up to it.

Children
  • Hi again

    Thank you for your response although some are snippy which is not helpful.

    I am sure that there are differences but as I mentioned those are just in the strings being used by a few sprintf statements. The optimizer doesn't seem to take those into account.

    All I was asking was is there a way to have this type of optimization not occur.

    Obviously I will post all of the details of the two routines to tech support for them to analyze.

  • yes I had thought about it being eliminated for other reasons such as not being reachable. since it was the same (except for the const strings) as the other routine starting at that point and other one was executable, I didn't see a any reason why it wasn't reachable.

    And after I significantly changed it enough for the optimizer to not see it as the same, it reappeared and was executable.

    Good idea though

    I just think it is because it does not consider const strings are part of its common block block analysis.

    I have not seen any other large part of my software like this one eliminated. Just smaller 4 or 5 line sections without const strings.

    The system seems to be running ok now that I forced it not to optimize that one routine.