Menu ▾ ▴

#1041 PIC14: Optimize decrement-and-branch loops using DECFSZ

None
open
nobody
5
2 days ago
3 days ago
No

The PIC14 backend misses an opportunity to generate DECFSZ for certain 8-bit decrement-and-branch loops.

The existing ifxForOp() matching logic requires the temporary's liveFrom to be at or after the subtraction instruction. This prevents the optimization in cases where the temporary was created earlier, even though the decrement result is used by the immediately following conditional branch.

I have implemented a small extension to genDjnz() that recognizes this pattern while retaining the existing optimization path.

Implementation

The patch:

Extends genDjnz() with an additional register requirement for the new matching path.

Requires a single-byte result mapped to a register.

Checks that the result and left operand are identical.

Requires subtraction by the literal value 1.

Requires an immediately following, matching IFX with a true branch and no false branch.

Checks that the temporary's liveTo does not extend beyond the matching IFX instruction.

Preserves the original genDjnz() behavior for previously recognized patterns.

Only src/pic14/gen.c is modified.

Reproducer

volatile unsigned char result;

void test_djnz_signed(signed char count)
{
    do {
        result++;
    } while (--count);
}

Original SDCC SVN r17110 (PIC16F1939):

BANKSEL r0x1001
DECF    r0x1001,F
MOVF    r0x1001,W
BTFSS   STATUS,2
GOTO    _00105_DS_

With the proposed patch:

BANKSEL r0x1001
DECFSZ  r0x1001,F
GOTO    _00105_DS_

The decrement-and-branch sequence is reduced from four instructions to two, excluding the unchanged BANKSEL.

The same DECFSZ optimization was also confirmed for an unsigned char loop counter.

Validation

The following checks were performed:

Successfully built with SDCC SVN r17110.

Verified code generation for PIC16F1939 and PIC16F18855.

Positive regression examples generate the expected DECFSZ instructions.

Volatile decrement cases remain excluded from the extended optimization.

PIC16F1939 runtime regression tests passed in simulation using COFF-based debugging, with no failures observed.

A controlled fault-injection test in an isolated diagnostic compiler confirmed that violating the liveTo boundary prevents the optimization and falls back to the ordinary decrement sequence.

The patch applies cleanly to the unmodified r17110 source tree using patch --dry-run -p1.

The fault-injection test verifies the rejection and fallback path. It is not a naturally occurring iCode counterexample.

The patch is limited to the PIC14 code generator and does not modify the pCode optimizer or register allocation implementation.

I would appreciate a review of the extended IFX matching conditions and the register/liveness safety checks.

Thank you.

1 Attachments

Discussion

  • Philipp Klaus Krause

    Thanks for the patch. However, I don't feel comfortable adding optimizations to pic14 at the moment. The port has no maintainer, and worse, we currently can't even run regression tests ([bugs:#4241]). IMO, before adding optimizations, we should get pic14 to run the regression tests, and not fail too many of them (ideally we'd get to 0 failures, but that might not be realistic for SDCC 4.7.0).

     

    Related

    Bugs: #4241

  • Philipp Klaus Krause

    Ticket moved from /p/sdcc/bugs/4239/

    Can't be converted:

    • _category: PIC14
     

Log in to post a comment.