1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-02 15:29:33 +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:
uz 2009-08-15 15:58:21 +00:00
parent 3381311674
commit 15c420fd39
3 changed files with 93 additions and 8 deletions

View File

@ -1014,7 +1014,8 @@ static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 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 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 DOptRTS = { OptRTS, "OptRTS", 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,
&DOptDupLoads,
&DOptJumpCascades,
&DOptJumpTarget,
&DOptJumpTarget1,
&DOptJumpTarget2,
&DOptLoad1,
&DOptNegA1,
&DOptNegA2,
@ -1453,7 +1455,8 @@ static unsigned RunOptGroup3 (CodeSeg* S)
C += RunOptFunc (S, &DOptDeadJumps, 1);
C += RunOptFunc (S, &DOptRTS, 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, &DOptRTSJumps1, 1);
C += RunOptFunc (S, &DOptBoolTrans, 1);
@ -1549,7 +1552,7 @@ static unsigned RunOptGroup6 (CodeSeg* S)
* may have opened new oportunities.
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
Changes += RunOptFunc (S, &DOptStore5, 1);
}
@ -1560,7 +1563,7 @@ static unsigned RunOptGroup6 (CodeSeg* S)
* may have opened new oportunities.
*/
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
Changes += RunOptFunc (S, &DOptJumpTarget1, 5);
Changes += RunOptFunc (S, &DOptStore5, 1);
}

View File

@ -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
* instruction preceeding the jump target, the jump target may be moved
* 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 */
/*****************************************************************************/
@ -1481,7 +1558,7 @@ unsigned OptTransfers4 (CodeSeg* S)
(LoadEntry->AM == AM65_ABS ||
LoadEntry->AM == AM65_ZP ||
LoadEntry->AM == AM65_IMM) &&
!MemAccess (S, Load+1, Xfer-1, LoadEntry->Arg)) {
!MemAccess (S, Load+1, Xfer-1, LoadEntry->Arg)) {
/* Generate the replacement load insn */
CodeEntry* X = 0;

View File

@ -77,13 +77,18 @@ unsigned OptRTS (CodeSeg* S);
* 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
* instruction preceeding the jump target, the jump target may be moved
* one entry back. This is a size optimization, since the instruction before
* 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);
/* 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