1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-06 13:29:01 +00:00

New optimization

git-svn-id: svn://svn.cc65.org/cc65/trunk@2436 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-09-14 09:54:24 +00:00
parent 6028eaac0c
commit 3499efea8f
3 changed files with 93 additions and 12 deletions

View File

@ -1542,7 +1542,8 @@ static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0,
static OptFunc DOptSub1 = { OptSub1, "OptSub1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptTest1 = { OptTest1, "OptTest1", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptTransfers = { OptTransfers, "OptTransfers", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptTransfers1 = { OptTransfers1, "OptTransfers1", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptTransfers2 = { OptTransfers2, "OptTransfers2", 60, 0, 0, 0, 0, 0 };
static OptFunc DOptUnusedLoads = { OptUnusedLoads, "OptUnusedLoads", 0, 0, 0, 0, 0, 0 };
static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0, 0 };
@ -1610,7 +1611,8 @@ static OptFunc* OptFuncs[] = {
&DOptSub1,
&DOptSub2,
&DOptTest1,
&DOptTransfers,
&DOptTransfers1,
&DOptTransfers2,
&DOptUnusedLoads,
&DOptUnusedStores,
};
@ -1781,15 +1783,15 @@ static void WriteOptStats (const char* Name)
/* Write a header */
fprintf (F,
"; Optimizer Total Last Total Last\n"
"; Step Runs Runs Chg Chg\n");
"; Optimizer Total Last Total Last\n"
"; Step Runs Runs Chg Chg\n");
/* Write the data */
for (I = 0; I < OPTFUNC_COUNT; ++I) {
const OptFunc* O = OptFuncs[I];
fprintf (F,
"%-20s %6lu %6lu %6lu %6lu\n",
"%-20s %10lu %10lu %10lu %10lu\n",
O->Name,
O->TotalRuns,
O->LastRuns,
@ -1934,7 +1936,7 @@ static unsigned RunOptGroup3 (CodeSeg* S)
C += RunOptFunc (S, &DOptUnusedStores, 1);
C += RunOptFunc (S, &DOptDupLoads, 1);
C += RunOptFunc (S, &DOptStoreLoad, 1);
C += RunOptFunc (S, &DOptTransfers, 1);
C += RunOptFunc (S, &DOptTransfers1, 1);
C += RunOptFunc (S, &DOptPushPop, 1);
Changes += C;
@ -1981,6 +1983,7 @@ static unsigned RunOptGroup5 (CodeSeg* S)
Changes += RunOptFunc (S, &DOptPush1, 1);
Changes += RunOptFunc (S, &DOptPush2, 1);
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
Changes += RunOptFunc (S, &DOptTransfers2, 1);
/* Return the number of changes */
return Changes;

View File

@ -1065,7 +1065,7 @@ unsigned OptStoreLoad (CodeSeg* S)
unsigned OptTransfers (CodeSeg* S)
unsigned OptTransfers1 (CodeSeg* S)
/* Remove transfers from one register to another and back */
{
unsigned Changes = 0;
@ -1081,9 +1081,7 @@ unsigned OptTransfers (CodeSeg* S)
/* Get next entry */
CodeEntry* E = CS_GetEntry (S, I);
/* Check if it is a store instruction followed by a load from the
* same address which is itself not followed by a conditional branch.
*/
/* Check if we have two transfer instructions */
if ((E->Info & OF_XFR) != 0 &&
(N = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (N) &&
@ -1135,6 +1133,82 @@ NextEntry:
unsigned OptTransfers2 (CodeSeg* S)
/* Replace loads followed by a register transfer by a load with the second
* register if possible.
*/
{
unsigned Changes = 0;
/* Walk over the entries */
unsigned I = 0;
while (I < CS_GetEntryCount (S)) {
CodeEntry* N;
/* Get next entry */
CodeEntry* E = CS_GetEntry (S, I);
/* Check if we have a load followed by a transfer where the loaded
* register is not used later.
*/
if ((E->Info & OF_LOAD) != 0 &&
(N = CS_GetNextEntry (S, I)) != 0 &&
!CE_HasLabel (N) &&
(N->Info & OF_XFR) != 0 &&
GetRegInfo (S, I+2, E->Chg) != E->Chg) {
CodeEntry* X = 0;
if (E->OPC == OP65_LDA && N->OPC == OP65_TAX) {
/* LDA/TAX - check for the right addressing modes */
if (E->AM == AM65_IMM ||
E->AM == AM65_ZP ||
E->AM == AM65_ABS ||
E->AM == AM65_ABSY) {
/* Replace */
X = NewCodeEntry (OP65_LDX, E->AM, E->Arg, 0, N->LI);
}
} else if (E->OPC == OP65_LDA && N->OPC == OP65_TAY) {
/* LDA/TAY - check for the right addressing modes */
if (E->AM == AM65_IMM ||
E->AM == AM65_ZP ||
E->AM == AM65_ZPX ||
E->AM == AM65_ABS ||
E->AM == AM65_ABSX) {
/* Replace */
X = NewCodeEntry (OP65_LDY, E->AM, E->Arg, 0, N->LI);
}
} else if (E->OPC == OP65_LDY && N->OPC == OP65_TYA) {
/* LDY/TYA. LDA supports all addressing modes LDY does */
X = NewCodeEntry (OP65_LDA, E->AM, E->Arg, 0, N->LI);
} else if (E->OPC == OP65_LDX && N->OPC == OP65_TXA) {
/* LDX/TXA. LDA doesn't support zp,y, so we must map it to
* abs,y instead.
*/
am_t AM = (E->AM == AM65_ZPY)? AM65_ABSY : E->AM;
X = NewCodeEntry (OP65_LDA, AM, E->Arg, 0, N->LI);
}
/* If we have a load entry, add it and remove the old stuff */
if (X) {
CS_InsertEntry (S, X, I+2);
CS_DelEntries (S, I, 2);
++Changes;
--I; /* Correct for one entry less */
}
}
/* Next entry */
++I;
}
/* Return the number of changes made */
return Changes;
}
unsigned OptPushPop (CodeSeg* S)
/* Remove a PHA/PLA sequence were A is not used later */
{
@ -1264,7 +1338,6 @@ unsigned OptPrecalc (CodeSeg* S)
} else if (E->AM == AM65_ZP) {
int R = ZPRegVal (E->Use, In);
if (RegValIsKnown (R)) {
printf ("A: %02X tmp1: %02X\n", In->RegA, R);
/* Accu EOR zp with known contents */
Arg = MakeHexArg (In->RegA ^ R);
}

View File

@ -102,9 +102,14 @@ unsigned OptDupLoads (CodeSeg* S);
unsigned OptStoreLoad (CodeSeg* S);
/* Remove a store followed by a load from the same location. */
unsigned OptTransfers (CodeSeg* S);
unsigned OptTransfers1 (CodeSeg* S);
/* Remove transfers from one register to another and back */
unsigned OptTransfers2 (CodeSeg* S);
/* Replace loads followed by a register transfer by a load with the second
* register if possible.
*/
unsigned OptPushPop (CodeSeg* S);
/* Remove a PHA/PLA sequence were A is not used later */