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

Another Optimization Problem

Greetings all,

I'm fairly new to the Keil Toolset and had a question regarding the C51 code optimization levels.

It seems that on Level 8: Reuse Common Entry Code (default), the main() entry function gets completely optimized out if the main() function grows too large. I can avoid this by either changing the optimization level, or by adding the debug flag in the Output tab.

The actual assembly is correct in the .LST file, but if I check the hex file, the main() function doesn't appear at the location specified by the map file.

Is this normal behaviour? Is there some setting I'm misinterpreting somewhere?


TIA,
JG.

Parents
  • Hi there,

    I'm trying to generate a small test case as per Stefan's suggestion, but the problem seems to be code-related (i.e. if the size of the main() function changes, so does the behaviour).

    Changing optimization levels makes the problem seem to go away in this case. Level 8 is the only one that manifests this problem and changing the speed/size emphasis has no effect.

    The versions are:
    C51.exe V7.00
    A51.exe V7.00a
    BL51.exe V5.00
    LIB51.exe V4.23
    OH51.exe V2.6

    I loaded the application into the debugger and checked the disassembly and it looks like the main() is zeroed out, so I guess this means the object file already is missing the main().

    There are no compiler errors or warnings, but during linking, I get 9 "L16: Uncalled Segment, Ignored for Overlay Process" warnings.

    Thanks again for all your help.
    V.

Reply
  • Hi there,

    I'm trying to generate a small test case as per Stefan's suggestion, but the problem seems to be code-related (i.e. if the size of the main() function changes, so does the behaviour).

    Changing optimization levels makes the problem seem to go away in this case. Level 8 is the only one that manifests this problem and changing the speed/size emphasis has no effect.

    The versions are:
    C51.exe V7.00
    A51.exe V7.00a
    BL51.exe V5.00
    LIB51.exe V4.23
    OH51.exe V2.6

    I loaded the application into the debugger and checked the disassembly and it looks like the main() is zeroed out, so I guess this means the object file already is missing the main().

    There are no compiler errors or warnings, but during linking, I get 9 "L16: Uncalled Segment, Ignored for Overlay Process" warnings.

    Thanks again for all your help.
    V.

Children
  • I get 9 "L16: Uncalled Segment, Ignored for Overlay Process" warnings.

    What segments are uncalled?

    Jon

  • Ok, I think I have some code that will exhibit the problem I'm having. I've tried several combinations of optimizations with and without debug info and the results seem to vary considerably depending on the code. With some code, the main function is deleted with many different settings while with other code, it only gets deleted with a very specific setting. In any case, it would be nice to determine the exact cause.

    The following is the simplest code that I could compile that shows the problem I'm having:

    sfr COM0 = 0xBC;
    
    void DummyCall()
    {
    }
    
    void main()
    {
    unsigned char Temp_A;
    unsigned char Temp_B;
    
    	Temp_A = 0;
    	Temp_B = 1;
    
    	COM0 = 0x55;
    
    	while(1);
    
    	while (1)
    	{
    		while(1);
    		if (1)
    		{
    			do
    			{
    				DummyCall();
    			} while (Temp_A != Temp_B);
    		}
    	}
    }
    

    When I compile with debug info _on_ and level 8 optimization, this is the disassembly:

    C:0x0003 787F MOV R0,#0x7F
    C:0x0005 E4 CLR A
    C:0x0006 F6 MOV @R0,A
    C:0x0007 D8FD DJNZ R0,C:0006
    C:0x0009 758107 MOV SP(0x81),#0x07
    C:0x000C 02000F LJMP main(C:000F)
    C:0x000F E4 CLR A
    C:0x0010 FF MOV R7,A
    C:0x0011 7E01 MOV R6,#0x01
    C:0x0013 75BC55 MOV COM0(0xBC),#0x55
    C:0x0016 80FE SJMP C:0016
    3: void DummyCall()
    C:0x0018 22 RET
    C:0x0019 00 NOP
    C:0x001A 00 NOP
    C:0x001B 00 NOP

    When debug info is turned _off_ the disassembly is this:

    C:0x0000 020003 LJMP C:0003
    C:0x0003 787F MOV R0,#0x7F
    C:0x0005 E4 CLR A
    C:0x0006 F6 MOV @R0,A
    C:0x0007 D8FD DJNZ R0,C:0006
    C:0x0009 758107 MOV SP(0x81),#0x07
    C:0x000C 02000F LJMP C:000F
    C:0x000F 00 NOP
    C:0x0010 00 NOP
    C:0x0011 00 NOP
    C:0x0012 00 NOP
    C:0x0013 00 NOP
    C:0x0014 00 NOP
    C:0x0015 00 NOP
    C:0x0016 00 NOP
    C:0x0017 00 NOP
    C:0x0018 22 RET
    C:0x0019 00 NOP
    C:0x001A 00 NOP

    So, in both cases, when the 8051 boots, it does the initial C_C51STARTUP, then jumps to main() which is at 0x0f. However, one case, the main is all NOPs and the other, there is the correct code.

    I'm really stumped about this. I know the code sample I posted is junk, but it shouldn't make the first few instructions get deleted.

    Vic.

  • I compiled your example. Here are my results.

    1. I ALWAYS receive the following linker warning:

    *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?DUMMYCALL?MAIN

    This makes sense because the main function never actually calls DummyCall and the optimizer figures this out.

    2. For compiling with and without debug information, I use the Debug Information checkbox in the Project Options - Output tab.

    3. Compiling with debug information ON yields the following in the debugger.

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     main(C:000F)
         7: void main()
         8: {
         9: unsigned char Temp_A;
        10: unsigned char Temp_B;
        11:
        12:         Temp_A = 0;
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
        13:         Temp_B = 1;
        14:
    C:0x0011    7E01     MOV      R6,#0x01
        15:         COM0 = 0x55;
        16:
    C:0x0013    75BC55   MOV      COM0(0xBC),#0x55
        17:         while(1);
    C:0x0016    80FE     SJMP     C:0016
         3: void DummyCall()
    C:0x0018    22       RET

    4. Compiling with debug information OFF yields the following:

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     C:000F
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
    C:0x0011    7E01     MOV      R6,#0x01
    C:0x0013    75BC55   MOV      0xBC,#0x55
    C:0x0016    80FE     SJMP     C:0016
    C:0x0018    22       RET      

    These appear to be identical to me.

    5. Finally, I created a HEX file from the build with debug information and I created a HEX file from the build with no debug information. They were identical.

    So, here are a few suggestions.

    • Make sure that we're build the project the same way.

    • Test the HEX files generated from the debug version and the non-debug version to see if they are the same.

    • How are you debugging? Are you using the Keil debugger or another debugger? If using another debugger, how old (or new) is it? Has it incorporated all the latest changes to the OMF51 specification?

    Jon

  • Thanks Jon,

    I was using the Keil debugger to get the disassembly. I've tested the hex file on my system (using the COM0 sfr) and I've examined the Hex file by hand as well. I don't see anything strange.

    When I build, the _only_ thing I changed was the debug info flag.

    Perhaps you _do_ have newer versions of the tools. I'm using OH51 V2.6.

  • Hi Jon,

    I just downloaded the newest tools from Keil and updated everything.

    Seems like the problem is gone and I get the same results as you.

    Thanks a lot for all your help. I just hope the problem is _really_ fixed this time. It just seems a bit scary that things were so intermittent.

  • I just downloaded the newest tools from Keil and updated everything.

    Oops. I guess we should have checked the version number from the beginning.

    Jon

  • Yes, Stefan _did_ ask which versions I was using.

    I looked through the update notes, but didn't find anything specifically related to this problem.

    Might have another surprise waiting for us in a few months :)

  • "I looked through the update notes, but didn't find anything specifically related to this problem."

    Indeed, perhaps Jon can show us where this bug is documented?

    Stefan