mirror of
https://github.com/cc65/cc65.git
synced 2025-03-02 18:30:09 +00:00
Added another optimization
git-svn-id: svn://svn.cc65.org/cc65/trunk@1044 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
9552efc1e4
commit
5f577c4260
@ -1112,7 +1112,7 @@ static unsigned OptDecouple (CodeSeg* S)
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static unsigned OptSize1 (CodeSeg* S)
|
||||
/* Do size optimization by calling special subroutines that preload registers.
|
||||
@ -1369,7 +1369,8 @@ static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0,
|
||||
static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptJumpTarget = { OptJumpTarget, "OptJumpTarget", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptRTS = { OptRTS, "OptRTS", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptRTSJumps = { OptRTSJumps, "OptRTSJumps", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptNegA1 = { OptNegA1, "OptNegA1", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptNegA2 = { OptNegA2, "OptNegA2", 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 0, 0, 0, 0, 0 };
|
||||
@ -1434,7 +1435,8 @@ static OptFunc* OptFuncs[] = {
|
||||
&DOptPtrStore1,
|
||||
&DOptPtrStore2,
|
||||
&DOptRTS,
|
||||
&DOptRTSJumps,
|
||||
&DOptRTSJumps1,
|
||||
&DOptRTSJumps2,
|
||||
&DOptShift1,
|
||||
&DOptShift2,
|
||||
/*&DOptSize1,*/
|
||||
@ -1726,7 +1728,7 @@ static void RunOptGroup3 (CodeSeg* S)
|
||||
Changes += RunOptFunc (S, &DOptDeadCode, 1);
|
||||
Changes += RunOptFunc (S, &DOptJumpTarget, 1);
|
||||
Changes += RunOptFunc (S, &DOptCondBranches, 1);
|
||||
Changes += RunOptFunc (S, &DOptRTSJumps, 1);
|
||||
Changes += RunOptFunc (S, &DOptRTSJumps1, 1);
|
||||
Changes += RunOptFunc (S, &DOptBoolTrans, 1);
|
||||
Changes += RunOptFunc (S, &DOptCmp1, 1);
|
||||
Changes += RunOptFunc (S, &DOptCmp2, 1);
|
||||
@ -1762,8 +1764,15 @@ static void RunOptGroup4 (CodeSeg* S)
|
||||
*/
|
||||
RunOptFunc (S, &DOptJumpTarget, 5);
|
||||
|
||||
/* Finally, adjust branch distances */
|
||||
/* Adjust branch distances */
|
||||
RunOptFunc (S, &DOptBranchDist, 3);
|
||||
|
||||
/* Replace conditional branches to RTS. If we had changes, we must run dead
|
||||
* code elimination again, since the change may have introduced dead code.
|
||||
*/
|
||||
if (RunOptFunc (S, &DOptRTSJumps2, 1)) {
|
||||
RunOptFunc (S, &DOptDeadCode, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,12 +43,12 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Replace jumps to RTS by RTS */
|
||||
/* Replace jumps to RTS by RTS */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
unsigned OptRTSJumps (CodeSeg* S)
|
||||
unsigned OptRTSJumps1 (CodeSeg* S)
|
||||
/* Replace jumps to RTS by RTS */
|
||||
{
|
||||
unsigned Changes = 0;
|
||||
@ -88,6 +88,64 @@ unsigned OptRTSJumps (CodeSeg* S)
|
||||
|
||||
|
||||
|
||||
unsigned OptRTSJumps2 (CodeSeg* S)
|
||||
/* Replace long conditional jumps to RTS */
|
||||
{
|
||||
unsigned Changes = 0;
|
||||
|
||||
/* Walk over all entries minus the last one */
|
||||
unsigned I = 0;
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* N;
|
||||
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's an unconditional branch to a local target */
|
||||
if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */
|
||||
(E->Info & OF_LBRA) != 0 && /* Long branch */
|
||||
E->JumpTo != 0 && /* Local label */
|
||||
E->JumpTo->Owner->OPC == OP65_RTS && /* Target is an RTS */
|
||||
(N = CS_GetNextEntry (S, I)) != 0) { /* There is a next entry */
|
||||
|
||||
CodeEntry* X;
|
||||
CodeLabel* LN;
|
||||
opc_t NewBranch;
|
||||
|
||||
/* We will create a jump around an RTS instead of the long branch */
|
||||
X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->JumpTo->Owner->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
|
||||
/* Get the new branch opcode */
|
||||
NewBranch = MakeShortBranch (GetInverseBranch (E->OPC));
|
||||
|
||||
/* Get the label attached to N, create a new one if needed */
|
||||
LN = CS_GenLabel (S, N);
|
||||
|
||||
/* Generate the branch */
|
||||
X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
|
||||
/* Delete the long branch */
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
||||
}
|
||||
|
||||
/* Next entry */
|
||||
++I;
|
||||
|
||||
}
|
||||
|
||||
/* Return the number of changes made */
|
||||
return Changes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Remove dead jumps */
|
||||
/*****************************************************************************/
|
||||
|
@ -49,9 +49,12 @@
|
||||
|
||||
|
||||
|
||||
unsigned OptRTSJumps (CodeSeg* S);
|
||||
unsigned OptRTSJumps1 (CodeSeg* S);
|
||||
/* Replace jumps to RTS by RTS */
|
||||
|
||||
unsigned OptRTSJumps2 (CodeSeg* S);
|
||||
/* Replace long conditional jumps to RTS */
|
||||
|
||||
unsigned OptDeadJumps (CodeSeg* S);
|
||||
/* Remove dead jumps (jumps to the next instruction) */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user