#216 |= to a bit variable with a function return value

closed
Maarten Brock
None
5
2007-10-29
2007-07-09
No

could be more compact.

The code below shows rather long code if a
char or bit returning function is used with
an |= operation to a bit variable:

-----8<-----------------------------------------
include <stdbool.h>

bool busy;

unsigned char handle_this_and_return_char(void)
{
return 0;
}

bool handle_this_and_return_bit(void)
{
return 0;
}

bool handle_that_and_return_bit(void)
{
return 0;
}

void init(void) {}
void sleep(void) {}

void main (void)
{
init();

while(1)
{
busy = handle_this_and_return_bit(); /* assignment is nice */
busy |= handle_that_and_return_bit(); /* needs an sloc */
busy |= handle_this_and_return_char(); /* could have used add a,#0xff */

if( !busy )
sleep();
}
}

-----8<-----------------------------------------

; bit_return.c:30: busy = handle_this_and_return_bit(); /* assignment is nice */
0071 12 00 68 lcall _handle_this_and_return_bit
0074 92 00 mov _busy,c

; bit_return.c:31: busy |= handle_that_and_return_bit(); /* needs an sloc */
0076 12 00 6A lcall _handle_that_and_return_bit
0079 92 01 mov _main_sloc0_1_0,c
007B A2 01 mov c,_main_sloc0_1_0
007D 72 00 orl c,_busy
007F 92 00 mov _busy,c

; bit_return.c:32: busy |= handle_this_and_return_char(); /* could have used add a,#0xff */
0081 12 00 64 lcall _handle_this_and_return_char
0084 AA 82 mov r2,dpl
0086 D3 setb c
0087 20 00 04 jb _busy,00110$
008A EA mov a,r2
008B 70 01 jnz 00110$
008D C3 clr c
008E 00110$:
008E 92 00 mov _busy,c

Discussion

  • Logged In: YES
    user_id=589052
    Originator: YES

    if the '!' operator is used on the function
    return value then this code is generated.

    (using the bit instruction "orl c,/_busy"
    would allow for 7 bytes instead of 21 bytes)

    _________________;_______bit_return.c:44:_busy |= !handle_that_and_return_bit ();
    0090_12_00_6A____________lcall____handle_that_and_return_bit
    0093_92_01_______________mov______main_sloc0_1_0,c
    0095_A2_01_______________mov_____c,_main_sloc0_1_0
    0097_B3__________________cpl_____c
    0098_E4__________________clr_____a
    0099_33__________________rlc_____a
    009A_FA__________________mov_____r2,a
    009B_D3__________________setb____c
    009C_20_00_04____________jb_______busy,00111$
    009F_EA__________________mov_____a,r2
    00A0_70_01_______________jnz_____00111$
    00A2_C3__________________clr_____c
    00A3_____________00111$:
    00A3_92_00_______________mov______busy,c

    (To work around Sourceforge's broken white space handling:
    https://sourceforge.net/tracker/?func=detail&aid=1596694&group_id=1&atid=350001
    I substituted ' ' with '_')

     
  • Maarten Brock
    Maarten Brock
    2007-07-19

    Logged In: YES
    user_id=888171
    Originator: NO

    Frieder,

    The sloc for the reception of the function return value is hard to do without. If the function uses parameters on stack for instance the carry may very well be destroyed during stack cleanup after the call. A peephole rule can help though.

    replace {
    mov _main_sloc0_1_0,c
    mov c,_main_sloc0_1_0
    } by {
    mov _main_sloc0_1_0,c
    }

    The genOr could be optimized for "bool = char | bool", but I think one should not be surprised that mixing bool and non-bool generates non-optimal code.

    I tried the piece with the '!' with my local compiled version and it's only 13 bytes as it no longer uses R2. The rest can be further optimized using a peephole rule. But 7 bytes is out of reach IMO.

    replace {
    mov _main_sloc0_1_0,c
    cpl _main_sloc0_1_0
    mov c,_main_sloc0_1_0
    } by {
    cpl c
    mov _main_sloc0_1_0,c
    }

    Maarten

     
  • Logged In: YES
    user_id=589052
    Originator: YES

    Hell Maarten,

    > A peephole rule can help though.

    My first impulse was to fix it halfway with a peephole
    too. But then I held back because of postings like:
    http://www.8052.com/forum/read.phtml?id=140728
    which correctly point to left-overs from peephole fixes.

    > If the function uses parameters on stack for instance the carry
    > may very well be destroyed during stack cleanup after the call

    I was not aware of this but you're right. Stack cleanup is
    probably the only case?

    > I tried the piece with the '!' with my local compiled
    > version and it's only 13 bytes as it no longer uses R2.
    > But 7 bytes is out of reach IMO.

    That's significant!! I'm aware that my second post
    hiddenly asked for the support of the bit instructions
    (orl c,/bit and anl c,/bit)
    and it was not fair to simply have appended that to
    this request:)

    Greetings,
    Frieder

     
  • Maarten Brock
    Maarten Brock
    2007-08-20

    Logged In: YES
    user_id=888171
    Originator: NO

    Heaven(?) Frieder,

    I have no problem with fixing this with a peephole at the moment.

    I'm not sure if stack cleanup is the only case which could cause trouble here. I am therefor reluctant to try to remove the sloc.

    And ORL C,/BIT cannot be used in this example. It's the carry you need to complement, not _busy. That's why I said it's impossible to reach 7 bytes. With the proposed peephole rule the 13 bytes become 10 bytes. And without the sloc the best is still 8 bytes and one less bit in ram.

    I do not think it's worth the trouble to go for the best when it's so much easier and less risky to come pretty near.

    But maybe we can find a way to remove dead moves to slocs like we have for registers and maybe even remove allocated but unused slocs. But there will always be some left-overs from generated code.

    Maarten

     
  • Maarten Brock
    Maarten Brock
    2007-10-29

    • assigned_to: nobody --> maartenbrock
    • status: open --> closed
     
  • Maarten Brock
    Maarten Brock
    2007-10-29

    Logged In: YES
    user_id=888171
    Originator: NO

    Apart from the (unused) spil locations all optimizations have been implemented in SDCC 2.7.4 #4948.