Re: [cc65] Hello, and a memory corruption (?) issue when optimizing

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2013-06-22 16:36:06
Hi!

On Fri, Jun 14, 2013 at 09:16:21PM +0200, Maik Merten wrote:
> in hopes of this possibly being useful, I assembled a minimal
> example which demonstrates the optimizer bug.

I had some time to look into the issue, and think that the following patch
should fix the problem:

------------------------------------------------------------------------------
Index: coptstop.c
===================================================================
--- coptstop.c	(revision 5990)
+++ coptstop.c	(working copy)
@@ -58,7 +58,8 @@
   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_DONT_REMOVE        = 0x08,         /* Load may not be removed */
+  LI_DUP_LOAD           = 0x10,         /* Duplicate load */
 } LI_FLAGS;

 /* Structure that tells us how to load the lhs values */
@@ -245,6 +246,18 @@



+static void HonourUseAndChg (LoadRegInfo* RI, unsigned Reg, const CodeEntry* E)
+/* Honour use and change flags for an instruction */
+{
+    if (E->Chg & Reg) {
+        ClearLoadRegInfo (RI);
+    } else if ((E->Use & Reg) && RI->LoadIndex >= 0) {
+        RI->Flags |= LI_DONT_REMOVE;
+    }
+}
+
+
+
 static void TrackLoads (LoadInfo* LI, CodeEntry* E, int I)
 /* Track loads for a code entry */
 {
@@ -348,17 +361,11 @@
         LI->X.Offs      = (unsigned char) E->RI->In.RegY;

         ClearLoadRegInfo (&LI->Y);
-    } else {
-        if (E->Chg & REG_A) {
-            ClearLoadRegInfo (&LI->A);
+    } else {
+        HonourUseAndChg (&LI->A, REG_A, E);
+        HonourUseAndChg (&LI->X, REG_X, E);
+        HonourUseAndChg (&LI->Y, REG_Y, E);
         }
-        if (E->Chg & REG_X) {
-            ClearLoadRegInfo (&LI->X);
-        }
-        if (E->Chg & REG_Y) {
-            ClearLoadRegInfo (&LI->Y);
-        }
-    }
 }


@@ -646,7 +653,7 @@
     /* Both registers may be loaded with one insn, but DelEntry will in this
      * case clear the other one.
      */
-    if (LI->A.Flags & LI_REMOVE) {
+    if ((LI->A.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
         if (LI->A.LoadIndex >= 0) {
             DelEntry (D, LI->A.LoadIndex);
         }
@@ -654,7 +661,7 @@
             DelEntry (D, LI->A.XferIndex);
         }
     }
-    if (LI->X.Flags & LI_REMOVE) {
+    if ((LI->X.Flags & (LI_REMOVE | LI_DONT_REMOVE)) == LI_REMOVE) {
         if (LI->X.LoadIndex >= 0) {
             DelEntry (D, LI->X.LoadIndex);
         }
------------------------------------------------------------------------------

Please note that I haven't done many tests, but the changes seem pretty safe,
since if they're triggered when they shouldn't all that happens is that code
is left in place that could be removed.

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sun Jun 23 11:08:52 2013

This archive was generated by hypermail 2.1.8 : 2013-06-23 11:08:54 CEST