diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index e9cf8914f..f7e3d4a1a 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -129,11 +129,11 @@ static OptFunc DOptBoolUnary3 = { OptBoolUnary3, "OptBoolUnary3", 40, 0, static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptBranchDist2 = { OptBranchDist2, "OptBranchDist2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 42, 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp10 = { OptCmp10, "OptCmp10", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 75, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 33, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp9 = { OptCmp9, "OptCmp9", 85, 0, 0, 0, 0, 0 }; @@ -252,11 +252,11 @@ static OptFunc* OptFuncs[] = { &DOptBranchDist, &DOptBranchDist2, &DOptCmp1, - &DOptCmp10, &DOptCmp2, &DOptCmp3, &DOptCmp4, &DOptCmp5, + &DOptCmp6, &DOptCmp7, &DOptCmp8, &DOptCmp9, @@ -731,7 +731,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCondBranch3, 1); C += RunOptFunc (S, &DOptCondBranchC, 1); C += RunOptFunc (S, &DOptRTSJumps1, 1); - C += RunOptFunc (S, &DOptCmp10, 1); /* After OptRTSJumps1 */ + C += RunOptFunc (S, &DOptCmp6, 1); /* After OptRTSJumps1 */ C += RunOptFunc (S, &DOptBoolCmp, 1); C += RunOptFunc (S, &DOptBoolTrans, 1); C += RunOptFunc (S, &DOptBNegA2, 1); /* After OptCondBranch's */ diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 25499dc3c..8f487969e 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -503,6 +503,51 @@ unsigned OptCmp5 (CodeSeg* S) +unsigned OptCmp6 (CodeSeg* S) +/* Remove compare instructions before an RTS or an subroutine call that doesn't +** use the flags. +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* N; + + /* Get next entry */ + CodeEntry* E = CS_GetEntry (S, I); + + /* Check for a compare followed by something else. + ** Note: The test could be improved by checking the flag usage of the + ** function explicitly against the flags set by the compare instruction. + ** For current code generation this makes no difference, however. + */ + if ((E->Info & OF_CMP) != 0 && + (N = CS_GetNextEntry (S, I)) != 0 && + (N->OPC == OP65_RTS || /* Either RTS, or ... */ + (N->OPC == OP65_JSR && /* ... or JSR ... */ + N->JumpTo == 0 && /* ... to external ... */ + (N->Use & PSTATE_ALL) == 0 && /* ... with no flags used ... */ + (N->Chg & PSTATE_ALL) == PSTATE_ALL))) { /* ... but all destroyed */ + + /* Found, remove the compare */ + CS_DelEntry (S, I); + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + + unsigned OptCmp7 (CodeSeg* S) /* Search for a sequence ldx/txa/branch and remove the txa if A is not ** used later. @@ -741,40 +786,3 @@ unsigned OptCmp9 (CodeSeg* S) /* Return the number of changes made */ return Changes; } - - - -unsigned OptCmp10 (CodeSeg* S) -/* Remove compare instructions before an RTS. This is safe since no C function -** passes back something in the flags. -*/ -{ - unsigned Changes = 0; - unsigned I; - - /* Walk over the entries */ - I = 0; - while (I < CS_GetEntryCount (S)) { - - CodeEntry* N; - - /* Get next entry */ - CodeEntry* E = CS_GetEntry (S, I); - - /* Check for a compare followed by an RTS */ - if ((E->Info & OF_CMP) != 0 && /* Compare insn */ - (N = CS_GetNextEntry (S, I)) != 0 && /* Next entry ... */ - N->OPC == OP65_RTS) { /* ... is RTS */ - - /* Found, remove the compare */ - CS_DelEntry (S, I); - ++Changes; - } - - /* Next entry */ - ++I; - } - - /* Return the number of changes made */ - return Changes; -} diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index ff58d37df..acd146822 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -123,6 +123,11 @@ unsigned OptCmp5 (CodeSeg* S); ** jne/jeq L2 */ +unsigned OptCmp6 (CodeSeg* S); +/* Remove compare instructions before an RTS or an exit by jumping to some +** other function. +*/ + unsigned OptCmp7 (CodeSeg* S); /* Search for a sequence ldx/txa/branch and remove the txa if A is not ** used later. @@ -146,11 +151,6 @@ unsigned OptCmp9 (CodeSeg* S); ** flag instead of the carry flag and remove the asl. */ -unsigned OptCmp10 (CodeSeg* S); -/* Remove compare instructions before an RTS. This is safe since no C function -** passes back something in the flags. -*/ - /* End of coptcmp.h */