mirror of
https://github.com/cc65/cc65.git
synced 2025-03-03 09:32:33 +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
@ -1369,7 +1369,8 @@ static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0,
|
|||||||
static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 0, 0, 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 DOptJumpTarget = { OptJumpTarget, "OptJumpTarget", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptRTS = { OptRTS, "OptRTS", 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 DOptNegA1 = { OptNegA1, "OptNegA1", 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptNegA2 = { OptNegA2, "OptNegA2", 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 };
|
static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 0, 0, 0, 0, 0 };
|
||||||
@ -1434,7 +1435,8 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptPtrStore1,
|
&DOptPtrStore1,
|
||||||
&DOptPtrStore2,
|
&DOptPtrStore2,
|
||||||
&DOptRTS,
|
&DOptRTS,
|
||||||
&DOptRTSJumps,
|
&DOptRTSJumps1,
|
||||||
|
&DOptRTSJumps2,
|
||||||
&DOptShift1,
|
&DOptShift1,
|
||||||
&DOptShift2,
|
&DOptShift2,
|
||||||
/*&DOptSize1,*/
|
/*&DOptSize1,*/
|
||||||
@ -1726,7 +1728,7 @@ static void RunOptGroup3 (CodeSeg* S)
|
|||||||
Changes += RunOptFunc (S, &DOptDeadCode, 1);
|
Changes += RunOptFunc (S, &DOptDeadCode, 1);
|
||||||
Changes += RunOptFunc (S, &DOptJumpTarget, 1);
|
Changes += RunOptFunc (S, &DOptJumpTarget, 1);
|
||||||
Changes += RunOptFunc (S, &DOptCondBranches, 1);
|
Changes += RunOptFunc (S, &DOptCondBranches, 1);
|
||||||
Changes += RunOptFunc (S, &DOptRTSJumps, 1);
|
Changes += RunOptFunc (S, &DOptRTSJumps1, 1);
|
||||||
Changes += RunOptFunc (S, &DOptBoolTrans, 1);
|
Changes += RunOptFunc (S, &DOptBoolTrans, 1);
|
||||||
Changes += RunOptFunc (S, &DOptCmp1, 1);
|
Changes += RunOptFunc (S, &DOptCmp1, 1);
|
||||||
Changes += RunOptFunc (S, &DOptCmp2, 1);
|
Changes += RunOptFunc (S, &DOptCmp2, 1);
|
||||||
@ -1762,8 +1764,15 @@ static void RunOptGroup4 (CodeSeg* S)
|
|||||||
*/
|
*/
|
||||||
RunOptFunc (S, &DOptJumpTarget, 5);
|
RunOptFunc (S, &DOptJumpTarget, 5);
|
||||||
|
|
||||||
/* Finally, adjust branch distances */
|
/* Adjust branch distances */
|
||||||
RunOptFunc (S, &DOptBranchDist, 3);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned OptRTSJumps (CodeSeg* S)
|
unsigned OptRTSJumps1 (CodeSeg* S)
|
||||||
/* Replace jumps to RTS by RTS */
|
/* Replace jumps to RTS by RTS */
|
||||||
{
|
{
|
||||||
unsigned Changes = 0;
|
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 */
|
/* Remove dead jumps */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -49,9 +49,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned OptRTSJumps (CodeSeg* S);
|
unsigned OptRTSJumps1 (CodeSeg* S);
|
||||||
/* Replace jumps to RTS by RTS */
|
/* Replace jumps to RTS by RTS */
|
||||||
|
|
||||||
|
unsigned OptRTSJumps2 (CodeSeg* S);
|
||||||
|
/* Replace long conditional jumps to RTS */
|
||||||
|
|
||||||
unsigned OptDeadJumps (CodeSeg* S);
|
unsigned OptDeadJumps (CodeSeg* S);
|
||||||
/* Remove dead jumps (jumps to the next instruction) */
|
/* Remove dead jumps (jumps to the next instruction) */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user