From: uz Date: Wed, 20 Jan 2010 19:47:44 +0000 (+0000) Subject: Fixed a problem in the optimizer function that rewrites ops that use the X-Git-Tag: V2.13.2~48 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5175f95341e23ce0e38b88ae96ee6c445a63f5b5;p=cc65 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 --- diff --git a/src/cc65/coptstop.c b/src/cc65/coptstop.c index 50fd73b4e..620a73504 100644 --- a/src/cc65/coptstop.c +++ b/src/cc65/coptstop.c @@ -58,6 +58,7 @@ typedef enum { LI_DIRECT = 0x01, /* Direct op may be used */ LI_RELOAD_Y = 0x02, /* Reload index register Y */ LI_REMOVE = 0x04, /* Load may be removed */ + LI_DUP_LOAD = 0x08, /* Duplicate load */ } LI_FLAGS; /* 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; } else if (E->Chg & REG_Y) { RI = &LI->Y; - } + } 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 */ RI->LoadIndex = I; RI->XferIndex = -1; @@ -299,6 +308,14 @@ static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I) 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 */ Tgt->LoadIndex = Src->LoadIndex; 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)) { + /* 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 */ LI->A.LoadIndex = I; 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 */ if ((D->UsedRegs & REG_PTR1) == REG_NONE) {