mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +00:00
Fixed a problem in the optimizer function that rewrites ops that use the
stack. Useless instructions (duplicate loads or transfers) within the sequence are left intact and may cause problems because the interfere with the replacement code. A run of OptRemoveUnusedLoads and friends should fix the problem, bit this step may be disabled, so the routine has to check for this condition and avoid it (by not doing the replacement). git-svn-id: svn://svn.cc65.org/cc65/trunk@4551 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
3d5d3ef76a
commit
5175f95341
@ -58,6 +58,7 @@ typedef enum {
|
|||||||
LI_DIRECT = 0x01, /* Direct op may be used */
|
LI_DIRECT = 0x01, /* Direct op may be used */
|
||||||
LI_RELOAD_Y = 0x02, /* Reload index register Y */
|
LI_RELOAD_Y = 0x02, /* Reload index register Y */
|
||||||
LI_REMOVE = 0x04, /* Load may be removed */
|
LI_REMOVE = 0x04, /* Load may be removed */
|
||||||
|
LI_DUP_LOAD = 0x08, /* Duplicate load */
|
||||||
} LI_FLAGS;
|
} LI_FLAGS;
|
||||||
|
|
||||||
/* Structure that tells us how to load the lhs values */
|
/* Structure that tells us how to load the lhs values */
|
||||||
@ -258,9 +259,17 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
|
|||||||
RI = &LI->X;
|
RI = &LI->X;
|
||||||
} else if (E->Chg & REG_Y) {
|
} else if (E->Chg & REG_Y) {
|
||||||
RI = &LI->Y;
|
RI = &LI->Y;
|
||||||
}
|
}
|
||||||
CHECK (RI != 0);
|
CHECK (RI != 0);
|
||||||
|
|
||||||
|
/* If we had a load or xfer op before, this is a duplicate load which
|
||||||
|
* can cause problems if it encountered between the pushax and the op,
|
||||||
|
* so remember it.
|
||||||
|
*/
|
||||||
|
if (RI->LoadIndex >= 0 || RI->XferIndex >= 0) {
|
||||||
|
RI->Flags |= LI_DUP_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remember the load */
|
/* Remember the load */
|
||||||
RI->LoadIndex = I;
|
RI->LoadIndex = I;
|
||||||
RI->XferIndex = -1;
|
RI->XferIndex = -1;
|
||||||
@ -299,6 +308,14 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
|
|||||||
default: Internal ("Unknown XFR insn in TrackLoads");
|
default: Internal ("Unknown XFR insn in TrackLoads");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we had a load or xfer op before, this is a duplicate load which
|
||||||
|
* can cause problems if it encountered between the pushax and the op,
|
||||||
|
* so remember it.
|
||||||
|
*/
|
||||||
|
if (Tgt->LoadIndex >= 0 || Tgt->XferIndex >= 0) {
|
||||||
|
Tgt->Flags |= LI_DUP_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transfer the data */
|
/* Transfer the data */
|
||||||
Tgt->LoadIndex = Src->LoadIndex;
|
Tgt->LoadIndex = Src->LoadIndex;
|
||||||
Tgt->XferIndex = I;
|
Tgt->XferIndex = I;
|
||||||
@ -308,6 +325,17 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
|
|||||||
|
|
||||||
} else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) {
|
} else if (CE_IsCallTo (E, "ldaxysp") && RegValIsKnown (E->RI->In.RegY)) {
|
||||||
|
|
||||||
|
/* If we had a load or xfer op before, this is a duplicate load which
|
||||||
|
* can cause problems if it encountered between the pushax and the op,
|
||||||
|
* so remember it for both registers involved.
|
||||||
|
*/
|
||||||
|
if (LI->A.LoadIndex >= 0 || LI->A.XferIndex >= 0) {
|
||||||
|
LI->A.Flags |= LI_DUP_LOAD;
|
||||||
|
}
|
||||||
|
if (LI->X.LoadIndex >= 0 || LI->X.XferIndex >= 0) {
|
||||||
|
LI->X.Flags |= LI_DUP_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
/* Both registers set, Y changed */
|
/* Both registers set, Y changed */
|
||||||
LI->A.LoadIndex = I;
|
LI->A.LoadIndex = I;
|
||||||
LI->A.XferIndex = -1;
|
LI->A.XferIndex = -1;
|
||||||
@ -1659,6 +1687,10 @@ static int PreCondOk (StackOpData* D)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((D->Rhs.A.Flags | D->Rhs.X.Flags) & LI_DUP_LOAD) {
|
||||||
|
/* Cannot optimize */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine the zero page locations to use */
|
/* Determine the zero page locations to use */
|
||||||
if ((D->UsedRegs & REG_PTR1) == REG_NONE) {
|
if ((D->UsedRegs & REG_PTR1) == REG_NONE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user