• AVR Freaks

Hot!compiler optimisation

Page: 123 > Showing page 1 of 3
Author
WesS
Super Member
  • Total Posts : 170
  • Reward points : 0
  • Joined: 2016/06/08 16:51:35
  • Location: 0
  • Status: offline
2019/11/27 19:55:20 (permalink)
4.33 (3)

compiler optimisation

Five years later since I was on the forum and nothing changed:
Access Denied
You don't have permission to access "http://www.microchip.com/forums/post.aspx?" on this server.

Reference #18.b71c1acb.1574909620.304bae51

There was nothing special in my post, no links or anything like this.
 
So I can't post it!
post edited by WesS - 2019/11/27 19:56:45
#1

54 Replies Related Threads

    WesS
    Super Member
    • Total Posts : 170
    • Reward points : 0
    • Joined: 2016/06/08 16:51:35
    • Location: 0
    • Status: offline
    Re: compiler optimisation 2019/11/27 19:57:01 (permalink)
    0 (2)
    I have been working on a project using XC8 ver. 1.45 and PIC16F819. Because I had some issues with the code I had to have a look at the disassembly, and I noticed strange code conversion/compilation.

    Firstly in FREE mode:

    Two lines of C-code - increment variable by 1 and toggle the led:

                    ++countWDog;
                    LED3_PORT ^= 1;
    where LED3_PORT is defined like this:

    #define LED3_PORT           PORTAbits.RA6

     

    I didn't expect to find this:

    Firstly in FREE mode:

    ! ++countWDog;
    0x195: MOVLW 0x1
    0x196: MOVWF 0x48
    0x197: MOVF 0x48, W
    0x198: ADDWF countWDog, F
    ! LED3_PORT ^= 1;
    0x199: SWAPF PORTA, W
    0x19A: MOVWF 0x48
    0x19B: RRF 0x48, F
    0x19C: RRF 0x48, W
    0x19D: ANDLW 0x1
    0x19E: MOVWF 0x48
    0x19F: MOVLW 0x1
    0x1A0: XORWF 0x48, F
    0x1A1: SWAPF 0x48, F
    0x1A2: RLF 0x48, F
    0x1A3: RLF 0x48, F
    0x1A4: MOVF PORTA, W
    0x1A5: XORWF 0x48, W
    0x1A6: ANDLW 0xBF
    0x1A7: XORWF 0x48, W
    0x1A8: MOVWF PORTA


    I expected the compiler to use the (limited) instruction set that this pic has

    To increase by one, use either INCF,  or MOVLW 1, and ADDW. So 1 or 2 instructions.

    To toggle the led, use MOVLW and XORWF or using BSF and BCF instructions - not 16 instructions! How could someone come up with this code?

     

    Next I tried compiler in STANDARD and the code is:

    ! ++countWDog;
    0x172: MOVLW 0x1
    0x176: MOVWF 0x48
    0x177: ADDWF countWDog, F
    ! LED3_PORT ^= 1;
    0x199: SWAPF PORTA, W
    0x19A: MOVWF 0x48
    0x19B: RRF 0x48, F
    0x19C: RRF 0x48, W
    0x19D: ANDLW 0x1
    0x19E: MOVWF 0x48
    0x19F: MOVLW 0x1
    0x1A0: XORWF 0x48, F
    0x1A1: SWAPF 0x48, F
    0x1A2: RLF 0x48, F
    0x1A3: RLF 0x48, F
    0x1A4: MOVF PORTA, W
    0x1A5: XORWF 0x48, W
    0x1A6: ANDLW 0xBF
    0x1A7: XORWF 0x48, W
    0x1A8: MOVWF PORTA


    To increment by 1, still shows some rubbish instruction - MOVWF 0x48

    Nothing changed when toggling the led

     

    Now, the PRO compilation:

    ! ++countWDog;
    0x133: INCF countWDog, F
    ! LED3_PORT ^= 1;
    0x131: MOVLW 0x40
    0x134: XORWF PORTA, F


    So, someone went to so much trouble to create the rubbish code in FREE and STANDARD (you pay for STANDARD!) versions, when there was no need for optimisation. It should be written using KISS principle.

     

    Next project that I had in the past using PIC18F1320 showing the bug in the compiler when the function includes C and assembly.

    Part of the C-function:

     tmp1 = 73; //6;
     j = 0;
     
     while(editData.value > 5){
      editData.value -= 6;
      ++j;
      if(j == 3){
       --tmp1;
       j = 0;
      }
     }
     if(tmp1 > 0x41){
      tmp1 += 7;
     }
    #asm
     MOVF _curchargeCurrent, w, c
     MULWF _tmp1, c // ARG1 * ARG2 -> ; PRODH:PRODL
     MOVFF PRODH, _tmp2, c
     MOVFF PRODL, _curchargeCurrent, c
     MOVF _curchargeCurrent+1, w, c
     MULWF _tmp1, c // ARG1 * ARG2 -> ; PRODH:PRODL
     MOVFF PRODL, _curchargeCurrent+1, c
     MOVF _tmp2, w, c
     ADDWF _curchargeCurrent+1, f, c
    #endasm


    And here is the disassembly:

    ! while(editData.value > 5){
    ! editData.value -= 6;
    0x10C4: MOVLW 0x6
    0x10C6: SUBWF editData, F, ACCESS
    0x10C8: MOVLW 0x0
    0x10CA: SUBWFB 0x17, F, ACCESS
    ! ++j;
    0x10CC: INCF dec_pt, F, ACCESS
    ! if(j == 3){
    0x10CE: MOVLW 0x3
    0x10D0: XORWF dec_pt, W, ACCESS
    0x10D2: BTFSS STATUS, 2, ACCESS
    0x10D4: BRA 0x10DC
    ! --tmp1;
    0x10D6: DECF tmp1, F, ACCESS
    ! j = 0;
    0x10D8: MOVLW 0x0
    0x10DA: MOVWF dec_pt, ACCESS
    ! }
    0x10DC: MOVF 0x17, W, ACCESS
    0x10DE: BNZ 0x10C4
    0x10E0: MOVLW 0x6
    0x10E2: SUBWF editData, W, ACCESS
    0x10E4: BTFSC STATUS, 0, ACCESS
    0x10E6: BRA 0x10C4
    ! }
    ! if(tmp1 > 0x41){
    0x10E8: MOVLW 0x41
    0x10EA: CPFSGT tmp1, ACCESS
    0x10EC: RETURN 0           <<returns from function. Why?
    ! tmp1 += 7;
    0x10EE: MOVLW 0x7
    0x10F0: ADDWF tmp1, F, ACCESS
    ! }
    !#asm

    ! MOVF _curchargeCurrent, w, c
    0x10F2: MOVF curchargeCurrent, W, ACCESS
    ! MULWF _tmp1, c // ARG1 * ARG2 -> ; PRODH:PRODL
    0x10F4: MULWF tmp1, ACCESS
    ! MOVFF PRODH, _tmp2, c
    0x10F6: MOVFF PRODH, tmp2
    0x10F8: NOP
    ! MOVFF PRODL, _curchargeCurrent, c


    As you can see, if the variable tmp1 is less than 0x41 it returns, and never gets to lines written in assembly

    In the STANDARD and PRO, it saves on a couple of instructions in the "while" loop but still returns from the function but this time it is:

    0xF48: RETLW 0x41

    So now, it return with 0x41 and not with 0 like in FREE mode. Although the code is wrong, but still, why retlw 0x41?
    #2
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/27 20:26:12 (permalink)
    0
    Replace this
      if(tmp1 > 0x41){
        tmp1 += 7;
      }
    #asm

    with this
      if(tmp1 > 0x41){
        tmp1 += 7;
      } else {
      }
    #asm

    #3
    WesS
    Super Member
    • Total Posts : 170
    • Reward points : 0
    • Joined: 2016/06/08 16:51:35
    • Location: 0
    • Status: offline
    Re: compiler optimisation 2019/11/27 20:44:32 (permalink)
    0
    1and0
    Replace this
      if(tmp1 > 0x41){
        tmp1 += 7;
      }
    #asm
     

    with this
      if(tmp1 > 0x41){
     
        tmp1 += 7;
      } else {
     
      }
     
    #asm
     



    Thanks. It is not a problem to find a solution, if you know that there is an issue with the code, but I didn't expect this to cause the problem.
    So is it a bug or isn't it?
     
    I just replaced the C-code with assembly put after #asm:
    #asm
     MOVLW 0x41
     CPFSLT _tmp1, c
     BRA skip
     MOVLW 7
     ADDWF _tmp1, c
    skip:
     MOVF _curchargeCurrent, w, c
     MULWF _tmp1, c // ARG1 * ARG2 -> ; PRODH:PRODL
     MOVFF PRODH, _tmp2, c
     MOVFF PRODL, _curchargeCurrent, c
     MOVF _curchargeCurrent+1, w, c
     MULWF _tmp1, c // ARG1 * ARG2 -> ; PRODH:PRODL
     MOVFF PRODL, _curchargeCurrent+1, c
     MOVF _tmp2, w, c
     ADDWF _curchargeCurrent+1, f, c
    #endasm

     
     
    #4
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/27 21:09:32 (permalink)
    0
    WesS
     
    Thanks. It is not a problem to find a solution, if you know that there is an issue with the code, but I didn't expect this to cause the problem.
    So is it a bug or isn't it?

    If you ask me, yes it's a bug; the compiler writer might have another answer. ;)
     

    I just replaced the C-code with assembly put after #asm:

    The empty else{} is a workaround to this issue. A NOP() after the if() also will work.
     
    #5
    crosland
    Super Member
    • Total Posts : 2014
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: online
    Re: compiler optimisation 2019/11/28 04:55:43 (permalink)
    +1 (3)
    WesS
    So, someone went to so much trouble to create the rubbish code in FREE and STANDARD (you pay for STANDARD!) versions, when there was no need for optimisation. It should be written using KISS principle.

     
    Please, not this rubbish again.
     
    Learn how a compiler works. Learn what optimization is and how it works.
     
    Did you try free mode with -O2, which is supported from 2.05?
    #6
    Antipodean
    Super Member
    • Total Posts : 1874
    • Reward points : 0
    • Joined: 2008/12/09 10:19:08
    • Location: Didcot, United Kingdom
    • Status: offline
    Re: compiler optimisation 2019/11/28 09:03:04 (permalink)
    +1 (1)
    crosland
    WesS
    So, someone went to so much trouble to create the rubbish code in FREE and STANDARD (you pay for STANDARD!) versions, when there was no need for optimisation. It should be written using KISS principle.

     
    Please, not this rubbish again.
     
    Learn how a compiler works. Learn what optimization is and how it works.
     
    Did you try free mode with -O2, which is supported from 2.05?




    Agreed, nothing in the post with all the examples to say if it was compiled as -o0, -o1 or -o2, for any of the examples.
     
    Does PRO mode automatically invoke -o2, or some higher level of optimisation?
     
     

    Do not use my alias in your message body when replying, your message will disappear ...

    Alan
    #7
    mlp
    boots too small
    • Total Posts : 946
    • Reward points : 0
    • Joined: 2012/09/10 15:12:07
    • Location: previously Microchip XC8 team
    • Status: offline
    Re: compiler optimisation 2019/11/28 18:42:26 (permalink)
    0
    Anti podean
    Does PRO mode automatically invoke -o2, or some higher level of optimisation?

    It never did while I was there - selected optimisation level was always distinct from Free/Standard(no longer exists)/PRO mode

    Mark (this opinion available for hire)
    #8
    WesS
    Super Member
    • Total Posts : 170
    • Reward points : 0
    • Joined: 2016/06/08 16:51:35
    • Location: 0
    • Status: offline
    Re: compiler optimisation 2019/11/28 20:35:56 (permalink)
    0 (2)
    crosland
    WesS
    So, someone went to so much trouble to create the rubbish code in FREE and STANDARD (you pay for STANDARD!) versions, when there was no need for optimisation. It should be written using KISS principle.

     
    Please, not this rubbish again.
     
    Learn how a compiler works. Learn what optimization is and how it works.
     
    Did you try free mode with -O2, which is supported from 2.05?


    Rubbish again? 
    What is rubbish? The code created by the compiler? I agree.
    Didn't I write that I use XC8 ver. 1.45?
    I chose optimisation (or no optimisation) that is available on the MPLABX Optimisation screen.
    Optimisation: -P -N255 --warn=-3 --asmlist -O0 --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free
    I remember, a couple of years ago, some smart person on the forum told me to learn how to debug code in MPLABX. Which basically was to modify the code to suit buggy MPLABX - change local variables to global, make variable volatile, compile without optimisation etc. That's not debugging the code. You debug the code that you are going to use (the same variable declaration, optimisation etc.), not change it, so the MPLABX can debug it.
     
    Now again, "learn how the compiler works". Why? How would it help me to understand it, how this code was created? I can't change the way the compiler works. I write the code, select optimisation options that are available in MPLABX, or no optimisation, and compile - and it should work. That's what I think, anyway.
    And "learn how optimisation works". If I chose FREE/no optimisation  and got this code - according to you this code is great, that's how you would expect to do it?
    Have a look at incrementing variable by one. Why would you need so many instructions, even if it is a free mode? The pic has one instruction INCF to do it - what is there to optimise?. But even in STANDARD it adds a rubbish instruction which doesn't do anything.
    It is like getting free Android app in the Google Playstore. You get it free, but full of adds. The same is this code, you get it free but full of unnecessary instructions. And, by the way, you get the same in the paid, STANDARD mode.
    You write the code, compile in PRO and guess what. You can't debug some parts of it. So you compile it in FREE so you can debug it, and guess what, the code is too large, and won't fit in the PIC. That's the greatness of the MPLABX.
    Lucky me, it is only my hobby.
     
    So thank you for you input.
    If you are happy with the generated code to toggle the port pin or increment variable - good on you.
     
     
    post edited by WesS - 2019/11/28 20:53:11
    #9
    NKurzman
    A Guy on the Net
    • Total Posts : 18852
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: compiler optimisation 2019/11/28 22:44:17 (permalink)
    +2 (2)
    Rubbish again means a long discussion about how compiler parses the C code to ASM then optimizes it. And why the compiler generates ugly code in the earlier stages.
    There are already threads on the topic in the forum if you want to search for them.

    And note MPLabX is the IDE, not the compiler. It has its own set of issues. The code optimization isn’t one of them.

    As far as you not liking the way to debugging works, Sorry that’s a skill you need to learn to program any micro-controller.
    Code that is easy to debug is less optimized. You can’t it have both ways.
    post edited by NKurzman - 2019/11/28 22:49:44
    #10
    WesS
    Super Member
    • Total Posts : 170
    • Reward points : 0
    • Joined: 2016/06/08 16:51:35
    • Location: 0
    • Status: offline
    Re: compiler optimisation 2019/11/29 01:08:18 (permalink)
    0 (2)
    NKurzman
    Rubbish again means a long discussion about how compiler parses the C code to ASM then optimizes it. And why the compiler generates ugly code in the earlier stages.
    There are already threads on the topic in the forum if you want to search for them.

    Seriously, you think I didn't know what he meant?
    It just made me laugh when I read it. If someone is not interested in the post, he/she should ignore it not call it rubbish.
    That's what 1and0 did, commenting only on what I thought was the bug of the compiler.
     
    Maybe, it can be useful to someone to know that a simple C-code to toggle the port is not that simple to the compiler in FREE and STANDARDS modes, and adding 1 to the variable is not one assembly instruction, what I would expect.
    I certainly didn't expect that. And I was using it in the past many times. And from now on I will use:
                    if(LED5_PORT == 0){
                        LED5_PORT = 1;
                    }
                    else{
                        LED5_PORT = 0;
                    }
    Not perfect, but will do in FREE (or STANDARD) mode. And at least, I know what I will get.
     
    Compiler parsing?
    ! ++countWDog;
    0x172: MOVLW 0x1
    0x176: MOVWF 0x48
    0x177: ADDWF countWDog, F
    This is not an "ugly code generated in early stage", but it is the final code.
    How would anyone explain instruction MOVWF 0x48 in this code in STANDARD mode? If you do it 100 times in your code, you get 100 extra instructions, not doing anything.
     
    NKurzman
    And note MPLabX is the IDE, not the compiler. It has its own set of issues. The code optimization isn’t one of them.

    That's why this post is in XC8 compiler. There is no chance for MPLABX to get any better soon (or ever), especially now, when Microchip added Atmel chips to it.
     
    NKurzman
    As far as you not liking the way to debugging works, Sorry that’s a skill you need to learn to program any micro-controller.

    In my opinion, that's not the skill, but "a way around" debugging, because there is no other option. If you change optimisation level to debug your code - you are not debugging your original code, because the compilation result is different, producing different assembly.
     
    NKurzman
    Code that is easy to debug is less optimized. You can’t it have both ways.

    I would agree with you, if we were talking about PIC32, but not about PIC16 with limited number of instruction, and FSR's. If debugger can't keep track of that?
    Anyway, as I said, it is only a hobby for me, so I can live with the way it is.
     
    #11
    Mysil
    Super Member
    • Total Posts : 3677
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: compiler optimisation 2019/11/29 02:45:37 (permalink)
    +1 (1)
    Hi,
    I would agree with you, if we were talking about PIC32, but not about PIC16 with limited number of instruction, and FSR's. If debugger can't keep track of that?

    There are a lot of tricks the XC8 compiler can and will do to confuse you when optimizing,
    especially when a PRO mode license is available.
    Yes there is a limited number of instructions, and only 1 accumulator,
    but global optimization will bypass function calls, and move around with inline optimizations,
    not only when you ask for it in source code, but also at it's own initiative.
     
        Mysil
    #12
    crosland
    Super Member
    • Total Posts : 2014
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: online
    Re: compiler optimisation 2019/11/29 06:17:49 (permalink)
    +1 (1)
    WesS
    Now again, "learn how the compiler works". Why? How would it help me to understand it, how this code was created? I can't change the way the compiler works. I write the code, select optimisation options that are available in MPLABX, or no optimisation, and compile - and it should work.

    The code works, does it not?
     
    If you understood compiler technology trhen you would realise what unoptimised code is v. optimised code. There is no conspiracy theory to generate bad code and make people pay for a license.
     

    And "learn how optimisation works". If I chose FREE/no optimisation  and got this code - according to you this code is great, that's how you would expect to do it?

    Where did I say the code was great? It's crap, but that's what you expect from not using any optimisation.
     

    You write the code, compile in PRO and guess what. You can't debug some parts of it. So you compile it in FREE so you can debug it, and guess what, the code is too large, and won't fit in the PIC. That's the greatness of the MPLABX.

    See above about understanding compilers. That's the same with ANY compiler. The more optimised the code, the less of a 1:1 relationship to individual source code statements and the more difficult it is to place breakpoints and debug. It's never impossible.
     

    If you are happy with the generated code to toggle the port pin or increment variable - good on you.

    No. I would not be happy. That's why I use v2.10 now, with optimisation set to -O2. No problems debugging, if you understand what has happened to your code.
    #13
    crosland
    Super Member
    • Total Posts : 2014
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: online
    Re: compiler optimisation 2019/11/29 07:38:10 (permalink)
    +2 (2)
    WesS
    I certainly didn't expect that. And I was using it in the past many times. And from now on I will use:
                    if(LED5_PORT == 0){
                        LED5_PORT = 1;
                    }
                    else{
                        LED5_PORT = 0;
                    }
    Not perfect, but will do in FREE (or STANDARD) mode. And at least, I know what I will get.

     
    You are on a hiding to nothing complaining about old tools.
     
    Version 2.10, simple output bit toggle:

    + _high.c: 676: (LATC^=1);
    12940 001C4A 0E01 movlw 1
    12941 001C4C 1A85 xorwf 3973,f,c ;volatile

     
    Regardless of the optimization level chosen.
    #14
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: compiler optimisation 2019/11/29 12:55:32 (permalink)
    +2 (2)
    crosland
    You are on a hiding to nothing complaining about old tools.

    +1

    Version 2.10, simple output bit toggle:

    + _high.c: 676: (LATC^=1);
    12940 001C4A 0E01 movlw 1
    12941 001C4C 1A85 xorwf 3973,f,c ;volatile

    Regardless of the optimization level chosen.

    It's the bitfield that causes code blowout. Unoptimised code is initially allowing for any size bitfield, it doesn't treat a single bit wide bitfield any differently to a multi-bit one.
    That's why "LATCbits.LATC0 ^= 1" generates much more code than "LATC ^= 1;"
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #15
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/29 22:45:39 (permalink)
    +4 (4)
    Here are the optimization levels available for the latest XC8 v2.10 Free mode:
    • - 0 - Do not optimize. The compiler’s goal is to reduce the cost of compilation and to make debugging produce the expected results.
    • - 1 - Optimize. Optimizing compilation takes somewhat longer, and a lot more host memory for a large function. The compiler tries to reduce code size and execution time.
    • - 2 - Optimize even more. The compiler performs nearly all supported optimizations that do not involve a space-speed trade-off.
    • - 3 - Optimize yet more favoring speed (superset of O2).
    • - s - Optimize yet more favoring size (superset of O2).


    For PIC16F819, use MPLAB X v5.30 and XC8 v2.10 Free mode with -O0, -O1, -O2, -O3, and -Os, it generates the same 4 instructions for incrementing an uint8_t variable :(
    !    ++countWDog;
    0x7F7: MOVLW 0x1
    0x7F8: MOVWF __pcstackCOMMON
    0x7F9: MOVF __pcstackCOMMON, W
    0x7FA: ADDWF countWDog, F

    and it generates the same 16 instructions for toggling bit RA6 :(
    !    PORTAbits.RA6 ^= 1;
    0x7EC: SWAPF PORTA, W
    0x7ED: MOVWF __pcstackCOMMON
    0x7EE: RRF __pcstackCOMMON, F
    0x7EF: RRF __pcstackCOMMON, W
    0x7F0: ANDLW 0x1
    0x7F1: MOVWF __pcstackCOMMON
    0x7F2: MOVLW 0x1
    0x7F3: XORWF __pcstackCOMMON, F
    0x7F4: SWAPF __pcstackCOMMON, F
    0x7F5: RLF __pcstackCOMMON, F
    0x7F6: RLF __pcstackCOMMON, F
    0x7F7: MOVF PORTA, W
    0x7F8: XORWF __pcstackCOMMON, W
    0x7F9: ANDLW 0xBF
    0x7FA: XORWF __pcstackCOMMON, W
    0x7FB: MOVWF PORTA


    For PIC18F2520, use the SAME compiler and optimizations, it generates this
    !    ++countWDog;
    0x7FF2: INCF countWDog, F, ACCESS

    and this
    !    PORTAbits.RA6 ^= 1;
    0x7FF4: BTG PORTA, 6, ACCESS


    It is obviously PICC18 Free mode is better than PICC Free mode, so my question is why PICC does not use the same template as PICC18 for generating assembly code? Both PIC16 and PIC18 have the INCF instruction. PIC16 devices do not have a BTG instruction, but it can be implemented with a template consisting of MOVLW/XORWF instructions.
    #16
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/29 23:12:30 (permalink)
    +1 (1)
    Here is what it does to toggle a bit:
    !    PORTAbits.RA6 ^= 1;
    0x7EC: SWAPF PORTA, W               ; copy target bit to bit 0 of temp<0>
    0x7ED: MOVWF __pcstackCOMMON
    0x7EE: RRF __pcstackCOMMON, F
    0x7EF: RRF __pcstackCOMMON, W
    0x7F0: ANDLW 0x1
    0x7F1: MOVWF __pcstackCOMMON
    0x7F2: MOVLW 0x1                    ; toggle temp<0> bit
    0x7F3: XORWF __pcstackCOMMON, F
    0x7F4: SWAPF __pcstackCOMMON, F     ; move temp<0> into desired bit position
    0x7F5: RLF __pcstackCOMMON, F
    0x7F6: RLF __pcstackCOMMON, F
    0x7F7: MOVF PORTA, W                ; replace target bit with temp<0>
    0x7F8: XORWF __pcstackCOMMON, W
    0x7F9: ANDLW 0xBF
    0x7FA: XORWF __pcstackCOMMON, W
    0x7FB: MOVWF PORTA

    which is crappy. :(
     
    #17
    ric
    Super Member
    • Total Posts : 27979
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: compiler optimisation 2019/11/29 23:29:11 (permalink)
    +2 (2)
    1and0
    Here are the optimization levels available for the latest XC8 v2.10 Free mode:
    • - 0 - Do not optimize. The compiler’s goal is to reduce the cost of compilation and to make debugging produce the expected results.
    • - 1 - Optimize. Optimizing compilation takes somewhat longer, and a lot more host memory for a large function. The compiler tries to reduce code size and execution time.
    • - 2 - Optimize even more. The compiler performs nearly all supported optimizations that do not involve a space-speed trade-off.
    • - 3 - Optimize yet more favoring speed (superset of O2).
    • - s - Optimize yet more favoring size (superset of O2).

    Are you sure about the last two? I thought they were the extras that were enabled in pro mode.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #18
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/30 02:48:41 (permalink)
    0
    ric
     
    Are you sure about the last two? I thought they were the extras that were enabled in pro mode.

    You're correct. ;)
    ::: advisory: (2051) The current license does not permit the selected optimization level, using optimization level 2

    #19
    1and0
    Access is Denied
    • Total Posts : 10997
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: compiler optimisation 2019/11/30 04:14:05 (permalink)
    +1 (1)
    For PIC16F819 using XC8 v2.10 Free mode with -O2, here's disassembly for toggling multiple bits:
    !    ADCON0bits.CHS ^= 0b111;
    0x7EB: RRF ADCON0, W                    ; copy target bits to temp LSbits
    0x7EC: MOVWF __pcstackCOMMON
    0x7ED: RRF __pcstackCOMMON, F
    0x7EE: RRF __pcstackCOMMON, W
    0x7EF: ANDLW 0x7
    0x7F0: MOVWF __pcstackCOMMON
    0x7F1: MOVLW 0x7                        ; toggle temp LSbits
    0x7F2: XORWF __pcstackCOMMON, F
    0x7F3: RLF __pcstackCOMMON, F           ; move temp bits into target position
    0x7F4: RLF __pcstackCOMMON, F
    0x7F5: RLF __pcstackCOMMON, F
    0x7F6: MOVF ADCON0, W                   ; replace target bits with temp bits
    0x7F7: XORWF __pcstackCOMMON, W
    0x7F8: ANDLW 0xC7
    0x7F9: XORWF __pcstackCOMMON, W
    0x7FA: MOVWF ADCON0

     
    For PIC18F2520 using XC8 v2.10 Free mode with -O2, here's disassembly for toggling multiple bits:
    !    ADCON0bits.CHS ^= 0b111;
    0x7FDC: MOVLW 0x7                       ; copy target bits to temp LSbits
    0x7FDE: MOVWF __pcstackCOMRAM, ACCESS
    0x7FE0: RRCF ADCON0, W, ACCESS
    0x7FE2: MOVWF 0x2, ACCESS
    0x7FE4: RRCF 0x2, W, ACCESS
    0x7FE6: ANDLW 0xF
    0x7FE8: MOVWF 0x2, ACCESS
    0x7FEA: MOVF __pcstackCOMRAM, W, ACCESS ; toggle temp LSbits
    0x7FEC: XORWF 0x2, F, ACCESS
    0x7FEE: RLCF 0x2, F, ACCESS             ; move temp bits into target position
    0x7FF0: RLCF 0x2, F, ACCESS
    0x7FF2: MOVF ADCON0, W, ACCESS          ; replace target bits with temp bits
    0x7FF4: XORWF 0x2, W, ACCESS
    0x7FF6: ANDLW 0xC3
    0x7FF8: XORWF 0x2, W, ACCESS
    0x7FFA: MOVWF ADCON0, ACCESS

     
    From these few examples, it seems PICC is treating single-bit and multiple-bit bitfields the same, whereas PICC18 does a better job for single-bit bitfields, even at optimization level 0. So, playing devil's advocate -- it cannot be an optimization issue; it's just plain crappy! That is, if PICC18 at -O0 can toggle a single bit with one instruction, why can't PICC do the same with two instructions?!
     
    In assembly it would be simply just this:
    btg     macro   fr,bit
            movlw   1<<(bit)
            xorwf   fr
            endm

    post edited by 1and0 - 2019/11/30 04:44:32
    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2020 APG vNext Commercial Version 4.5