mirror of
https://github.com/cc65/cc65.git
synced 2024-07-07 19:29:18 +00:00
Some branch improvements.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4019 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
3381311674
commit
15c420fd39
@ -1014,7 +1014,8 @@ static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 0,
|
|||||||
static OptFunc DOptDecouple = { OptDecouple, "OptDecouple", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptDecouple = { OptDecouple, "OptDecouple", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0, 0, 0, 0 };
|
static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptJumpTarget = { OptJumpTarget, "OptJumpTarget", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptJumpTarget1 = { OptJumpTarget1, "OptJumpTarget1", 100, 0, 0, 0, 0, 0 };
|
||||||
|
static OptFunc DOptJumpTarget2 = { OptJumpTarget2, "OptJumpTarget2", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptLoad1 = { OptLoad1, "OptLoad1", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptLoad1 = { OptLoad1, "OptLoad1", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 };
|
||||||
static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 100, 0, 0, 0, 0, 0 };
|
static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 100, 0, 0, 0, 0, 0 };
|
||||||
@ -1093,7 +1094,8 @@ static OptFunc* OptFuncs[] = {
|
|||||||
&DOptDecouple,
|
&DOptDecouple,
|
||||||
&DOptDupLoads,
|
&DOptDupLoads,
|
||||||
&DOptJumpCascades,
|
&DOptJumpCascades,
|
||||||
&DOptJumpTarget,
|
&DOptJumpTarget1,
|
||||||
|
&DOptJumpTarget2,
|
||||||
&DOptLoad1,
|
&DOptLoad1,
|
||||||
&DOptNegA1,
|
&DOptNegA1,
|
||||||
&DOptNegA2,
|
&DOptNegA2,
|
||||||
@ -1453,7 +1455,8 @@ static unsigned RunOptGroup3 (CodeSeg* S)
|
|||||||
C += RunOptFunc (S, &DOptDeadJumps, 1);
|
C += RunOptFunc (S, &DOptDeadJumps, 1);
|
||||||
C += RunOptFunc (S, &DOptRTS, 1);
|
C += RunOptFunc (S, &DOptRTS, 1);
|
||||||
C += RunOptFunc (S, &DOptDeadCode, 1);
|
C += RunOptFunc (S, &DOptDeadCode, 1);
|
||||||
C += RunOptFunc (S, &DOptJumpTarget, 1);
|
C += RunOptFunc (S, &DOptJumpTarget1, 1);
|
||||||
|
C += RunOptFunc (S, &DOptJumpTarget2, 1);
|
||||||
C += RunOptFunc (S, &DOptCondBranches, 1);
|
C += RunOptFunc (S, &DOptCondBranches, 1);
|
||||||
C += RunOptFunc (S, &DOptRTSJumps1, 1);
|
C += RunOptFunc (S, &DOptRTSJumps1, 1);
|
||||||
C += RunOptFunc (S, &DOptBoolTrans, 1);
|
C += RunOptFunc (S, &DOptBoolTrans, 1);
|
||||||
@ -1549,7 +1552,7 @@ static unsigned RunOptGroup6 (CodeSeg* S)
|
|||||||
* may have opened new oportunities.
|
* may have opened new oportunities.
|
||||||
*/
|
*/
|
||||||
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
||||||
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
|
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
|
||||||
Changes += RunOptFunc (S, &DOptStore5, 1);
|
Changes += RunOptFunc (S, &DOptStore5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,7 +1563,7 @@ static unsigned RunOptGroup6 (CodeSeg* S)
|
|||||||
* may have opened new oportunities.
|
* may have opened new oportunities.
|
||||||
*/
|
*/
|
||||||
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
||||||
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
|
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
|
||||||
Changes += RunOptFunc (S, &DOptStore5, 1);
|
Changes += RunOptFunc (S, &DOptStore5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ unsigned OptRTS (CodeSeg* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned OptJumpTarget (CodeSeg* S)
|
unsigned OptJumpTarget1 (CodeSeg* S)
|
||||||
/* If the instruction preceeding an unconditional branch is the same as the
|
/* If the instruction preceeding an unconditional branch is the same as the
|
||||||
* instruction preceeding the jump target, the jump target may be moved
|
* instruction preceeding the jump target, the jump target may be moved
|
||||||
* one entry back. This is a size optimization, since the instruction before
|
* one entry back. This is a size optimization, since the instruction before
|
||||||
@ -623,6 +623,83 @@ NextEntry:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned OptJumpTarget2 (CodeSeg* S)
|
||||||
|
/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since
|
||||||
|
* it's job is already done.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Changes = 0;
|
||||||
|
|
||||||
|
/* Walk over the entries */
|
||||||
|
unsigned I = 0;
|
||||||
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
|
/* OP that may be skipped */
|
||||||
|
opc_t OPC;
|
||||||
|
|
||||||
|
/* Jump target insn, old and new */
|
||||||
|
CodeEntry* T;
|
||||||
|
CodeEntry* N;
|
||||||
|
|
||||||
|
/* New jump label */
|
||||||
|
CodeLabel* L;
|
||||||
|
|
||||||
|
/* Get next entry */
|
||||||
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
|
/* Check if this is a bcc insn */
|
||||||
|
if (E->OPC == OP65_BCC || E->OPC == OP65_JCC) {
|
||||||
|
OPC = OP65_CLC;
|
||||||
|
} else if (E->OPC == OP65_BCS || E->OPC == OP65_JCS) {
|
||||||
|
OPC = OP65_SEC;
|
||||||
|
} else {
|
||||||
|
/* Not what we're looking for */
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must have a jump target */
|
||||||
|
if (E->JumpTo == 0) {
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the owner insn of the jump target and check if it's the one, we
|
||||||
|
* will skip if present.
|
||||||
|
*/
|
||||||
|
T = E->JumpTo->Owner;
|
||||||
|
if (T->OPC != OPC) {
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the entry following the branch target */
|
||||||
|
N = CS_GetNextEntry (S, CS_GetEntryIndex (S, T));
|
||||||
|
if (N == 0) {
|
||||||
|
/* There is no such entry */
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the label for the instruction following the jump target.
|
||||||
|
* This routine will create a new label if the instruction does
|
||||||
|
* not already have one.
|
||||||
|
*/
|
||||||
|
L = CS_GenLabel (S, N);
|
||||||
|
|
||||||
|
/* Change the jump target to point to this new label */
|
||||||
|
CS_MoveLabelRef (S, E, L);
|
||||||
|
|
||||||
|
/* Remember that we had changes */
|
||||||
|
++Changes;
|
||||||
|
|
||||||
|
NextEntry:
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of changes made */
|
||||||
|
return Changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Optimize conditional branches */
|
/* Optimize conditional branches */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -77,13 +77,18 @@ unsigned OptRTS (CodeSeg* S);
|
|||||||
* label, the dead code elimination should take care of it.
|
* label, the dead code elimination should take care of it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned OptJumpTarget (CodeSeg* S);
|
unsigned OptJumpTarget1 (CodeSeg* S);
|
||||||
/* If the instruction preceeding an unconditional branch is the same as the
|
/* If the instruction preceeding an unconditional branch is the same as the
|
||||||
* instruction preceeding the jump target, the jump target may be moved
|
* instruction preceeding the jump target, the jump target may be moved
|
||||||
* one entry back. This is a size optimization, since the instruction before
|
* one entry back. This is a size optimization, since the instruction before
|
||||||
* the branch gets removed.
|
* the branch gets removed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
unsigned OptJumpTarget2 (CodeSeg* S);
|
||||||
|
/* If a bcs jumps to a sec insn or a bcc jumps to clc, skip this insn, since
|
||||||
|
* it's job is already done.
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned OptCondBranches (CodeSeg* S);
|
unsigned OptCondBranches (CodeSeg* S);
|
||||||
/* If an immidiate load of a register is followed by a conditional jump that
|
/* If an immidiate load of a register is followed by a conditional jump that
|
||||||
* is never taken because the load of the register sets the flags in such a
|
* is never taken because the load of the register sets the flags in such a
|
||||||
|
Loading…
Reference in New Issue
Block a user