Rewrite the optimization step from c0a1b1b887 to

remove compares not only before RTS but also befoire function calls that don't
use the flags but destroy all of them. The latter is currently the case for
all functions called. This way the optimization covers a lot more cases than
just checking for RTS.
This commit is contained in:
Kugel Fuhr
2025-06-25 20:07:36 +02:00
parent 1feeee9ce0
commit 55d9b2dbd0
3 changed files with 53 additions and 45 deletions

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */