Menu

#212 eliminate unnecessary bankswitching

open
nobody
None
1
2007-07-18
2007-06-26
No

Hi.

This is not strictly a bug, but the effect
of that pessimization is rather bad.
If the interrupt handler is defined to use
some regbank other than 0, and it calls some
function that is not set to use any particular
regbank, then the compiler would save all the
regs and switch the bank to 0 before calling
the function. I define the inthandler to use
the specific regbank exactly to save some
stack space and an execution time, but the
effect is quite the reverse.
Unless I am missing something, if the function
is not set to explicitly use some regbank,
there is no need to switch the banks before
calling it. It looks like sdcc doesn't destinguish
between the function that is not set to use
a particular regbank and the function that
was set to use bank 0, which makes the problem.
It always switches to bank 0, but if the
function is not explicitly defined to use bank 0,
then there is no need to switch at all.

Attached is the simple demo program.
Looking into its assembly reveals how many
unneeded things are done, and how much memory
does this consume. It eats about 10 extra bytes
with the useless push/pops, which is way too
much for those poor MCUs with 128bytes of RAM.

Discussion

  • Stas Sergeev

    Stas Sergeev - 2007-06-26

    demo

     
  • Maarten Brock

    Maarten Brock - 2007-06-27

    Logged In: YES
    user_id=888171
    Originator: NO

    Stas,

    As you may or may not have noticed SDCC uses both Rn and ARn to access the registers. The ARn version uses the direct address of the corresponding register and thus needs to know which register bank is currently selected.

    If SDCC would consider any function without __using directive as register bank independent, it would lead to larger code in those places where it now uses ARn.

    In general it is a bad idea to call functions from an ISR.
    And what is wrong with telling those functions you do want to call from an ISR to use the same register bank? You can't share those functions with the main loop anyway unless they are reentrant.

    I don't think we want to change this behaviour.

    Maarten

     
  • Maarten Brock

    Maarten Brock - 2007-06-27
    • milestone: --> 100455
    • status: open --> closed-wont-fix
     
  • Stas Sergeev

    Stas Sergeev - 2007-06-27

    Logged In: YES
    user_id=501371
    Originator: YES

    OK, quite clear, thanks.
    Yes, there were a few small helper functions
    that I wanted to use from both the int handlers
    and main loop (marking them reentrant of course),
    but it is not a big deal to not do so if the
    good reason does exist.
    Though, if possible, could you please
    give a brief explanation (or point to one)
    of why does sdcc use ARx so much?

     
  • Stas Sergeev

    Stas Sergeev - 2007-07-17
    • summary: unnecessary bankswitching --> eliminate unnecessary bankswitching
    • status: closed-wont-fix --> pending-wont-fix
     
  • Stas Sergeev

    Stas Sergeev - 2007-07-17

    Logged In: YES
    user_id=501371
    Originator: YES

    > And what is wrong with telling those functions you do want to call from an
    > ISR to use the same register bank?
    Sorry, I recalled the answer to this
    question only now (amnesia).
    You can't tell the library functions,
    like memcpy, to use bankX. And calling
    the library functions from the inthandler
    is possible if one uses --stack-auto.

    So at least as a feature request, I think
    this entry is viable. But for some reasons
    I can't move that to the feature requests...
    Is it possible to change the tracker setup
    so that people can change the "Data Type"
    field? In other SF projects this is possible.

     
  • Maarten Brock

    Maarten Brock - 2007-07-17

    Logged In: YES
    user_id=888171
    Originator: NO

    If you use --stack-auto ALL functions are reentrant even the ones in the libraries. You cannot use it only on one source file but not on the others.

    And if you want some function from the library to use a certain register bank, just recompile it and adapt the prototype and use that instead.

    I could move this to the feature requests for you, but either I still don't get what you're asking or you did not understand my answer that it is not possible.

    Btw. SDCC uses ARx so much because it's more efficient than moving everything through the accumulator. Consider the following:

    push ar2

    or

    xch a,r2
    push acc
    xch a,r2

     
  • Stas Sergeev

    Stas Sergeev - 2007-07-18
    • status: pending-wont-fix --> open-wont-fix
     
  • Stas Sergeev

    Stas Sergeev - 2007-07-18

    Logged In: YES
    user_id=501371
    Originator: YES

    > If you use --stack-auto ALL functions are reentrant even the ones in the
    > libraries.
    I know.

    > And if you want some function from the library to use a certain register
    > bank, just recompile it and adapt the prototype and use that instead.
    AFAIK sdcc sometimes generates the call
    to the library function internally.
    _gptrget(), _muluint() and the like.

    > don't get what you're asking or you did not understand my answer that it is
    > not possible.
    I understand that it is not possible right
    now. But I wonder if it is really not
    possible at all.

    > Btw. SDCC uses ARx so much because it's more efficient than moving
    > everything through the accumulator. Consider the following:
    Thanks, I see. However, looking into the
    datasheet, I've got an impression that the
    push/pop are the only offenders. Is it
    true, or can you give any other example?

    > xch a,r2
    > push acc
    > xch a,r2
    Maybe it can just be
    mov b,r2
    push b
    as IIRC sdcc uses b as a scratch-pad.
    But that's still a pissimization of course...

     
  • Stas Sergeev

    Stas Sergeev - 2007-07-18
    • status: open-wont-fix --> closed-wont-fix
     
  • Maarten Brock

    Maarten Brock - 2007-07-18

    Logged In: YES
    user_id=888171
    Originator: NO

    Yes sometimes SDCC generates calls to the library internally. _gptrget() is a bad example as it is a special case that is known not to rely on any register bank. But others like _muluint() are not safe in this regard.

    For this to be possible SDCC needs to be extended with something like "__using (none)" to explicitly tell SDCC not to use any register bank dependent code. But even then it can only be used on reentrant functions. I think you're much better off if you try not to call any functions shared with the main loop in an ISR. And if you have to then just make the ISR use register bank 0. Or alternatively make this shared function __naked and write it in (inline) assembly.

    To make this idea possible will require many updates, PUSH and POP are not the only offenders.
    Others are:
    anl AR2,a
    anl AR2,#0
    orl AR2,a
    orl AR2,#0
    xrl AR2,a
    xrl AR2,#0
    mov AR2,R0
    mov AR2,@R0
    mov @R0,AR2
    cjne a,AR2,label

    Using B for a push is only faster (on the original 8051), but not shorter than using A. And it is still slower and longer than the currently generated single push instruction.

    You are right that this is a feature request and thus I moved it. But I've also set it to the lowest priority as I'm not keen on implementing it.

     
  • Maarten Brock

    Maarten Brock - 2007-07-18
    • priority: 5 --> 1
    • milestone: 100455 -->
    • labels: 101550 -->
    • status: closed-wont-fix --> open-wont-fix
     
  • Stas Sergeev

    Stas Sergeev - 2007-07-18

    Logged In: YES
    user_id=501371
    Originator: YES

    > And if you have to then just make the ISR use
    > register bank 0.
    I sometimes need to access the saved registers
    on a stack to modify them. Since sdcc doesn't
    seem to provide any way for accessing the saved
    registers, I mark the function to use a different
    bank and access them by hands.

    > To make this idea possible will require many updates, PUSH and POP are not
    > the only offenders.
    > Others are:
    Oh, that's nasty then...

    > also set it to the lowest priority as I'm not keen on implementing it.
    Right.
    What's the instruction set is this, where
    the memory locations as an operands are more
    preferred, than the registers...

     
  • Stas Sergeev

    Stas Sergeev - 2007-07-18
    • status: open-wont-fix --> open
     

Log in to post a comment.