* src/pic/pcoderegs.c (pCodeOptime2pCodes): fixed bogus optimization,
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 21 May 2007 09:10:38 +0000 (09:10 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 21 May 2007 09:10:38 +0000 (09:10 +0000)
  closes #1722392
* src/regression/gpsim_assert.h,
* src/regression/Makefile,
* src/regression/pcodeopt.c: regression test for the above fix

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4807 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/pic/pcoderegs.c
src/regression/Makefile
src/regression/gpsim_assert.h
src/regression/pcodeopt.c [new file with mode: 0644]

index 2c66eead70990ddbbdcd6df60d9bfd46765dfcd4..5892b0629e4e5c07ad0c1c9e5a4b398742d6bacf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-05-21 Raphael Neider <rneider AT web.de>
+
+       * src/pic/pcoderegs.c (pCodeOptime2pCodes): fixed bogus optimization,
+         closes #1722392
+       * src/regression/gpsim_assert.h,
+       * src/regression/Makefile,
+       * src/regression/pcodeopt.c: regression test for the above fix
+
 2007-05-08 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * src/SDCCpeeph.c (labelIsUncondJump): ignore identical labels for
index 5c1b8d18896aeef2869e084d918af53d736b10d5..25cdf421b3fd3768ca094091d91c707960944a83 100644 (file)
@@ -523,24 +523,27 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
        if (!isPCI(pc1) || !isPCI(pc2)) return 0;
        if (PCI(pc1)->pcflow != PCI(pc2)->pcflow) return 0;
        
-       if(pc2->seq < pc1->seq) {
+       if (pc2->seq < pc1->seq) {
                pct1 = pc2;
                pc2 = pc1;
                pc1 = pct1;
        }
 
        /* disable this optimization for now -- it's buggy */
-       if(pic14_options.disable_df) return 0;
+       if (pic14_options.disable_df) return 0;
        
        //fprintf(stderr,"pCodeOptime2pCodes\n");
        //pc1->print(stderr,pc1);
        //pc2->print(stderr,pc2);
 
        if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
+           /*
+            * CLRF sets Z
+            * MOVFW affects Z
+            * MOVWF does not touch Z
+            * MOVLW does not touch Z
+            */
                pCode *newpc;
-               int regUsed = 0;
-               int wUsed   = 0;
-               int wSaved  = 0;
                /*
                clrf  reg    ; pc1
                stuff...
@@ -553,41 +556,25 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                */
                DFPRINTF((stderr, "   optimising CLRF reg ... MOVF reg,W to ... MOVLW 0\n"));
                pct2 = findNextInstruction(pc2->next);
-               
-               if(pct2 && PCI(pct2)->op == POC_MOVWF) {
-                       wSaved = wUsed = 1; /* Maybe able to replace with clrf pc2->next->reg. */
-               } else {
-                       wUsed = pCodeSearchCondition(pct2,PCC_W,1) != -1;
-               }
-               regUsed = regUsedinRange(pct2,0,reg);
-               if ((regUsed&&wUsed) || (pCodeSearchCondition(pct2,PCC_Z,0) != -1)) {
-                       /* Do not optimise as exisiting code is required. */
-               } else {
-                       /* Can optimise. */
-                       if(regUsed) {
-                               newpc = newpCode(POC_CLRF, PCI(pc1)->pcop);
-                       } else if(wSaved && !wUsed) {
-                               newpc = newpCode(POC_CLRF, PCI(pct2)->pcop);
-                               pct2->destruct(pct2);
-                       } else {
-                               newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
-                       }
+               if (pCodeSearchCondition(pct2, PCC_Z, 0) == -1) {
+                       /* Z is definitely overwritten before use */
+                       newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
                        
                        pCodeInsertAfter(pc2, newpc);
                        PCI(newpc)->pcflow = PCFL(pcfl_used);
                        newpc->seq = pc2->seq;
                        
                        //fprintf (stderr, "%s:%d(%s): Remove2pcodes (CLRF reg, ..., MOVF reg,W)\n", __FILE__, __LINE__, __FUNCTION__);
-                       Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
-                       total_registers_saved++;  // debugging stats.
+                       Remove2pcodes(pcfl_used, pc2, NULL, reg, 0);
+                       //total_registers_saved++;  // debugging stats.
                }
        } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
                DFPRINTF((stderr, "   optimising CLRF/IORFW\n"));
                
                pct2 = findNextInstruction(pc2->next);
                
-               /* We must ensure that is destroyed before being read---IORLW must be performed unless this is proven. */
-               if(pCodeSearchCondition(pct2, PCC_Z,0) != -1) {
+               /* We must ensure that is destroyed before being read---IORLW must be performed unless this is proven. */
+               if (pCodeSearchCondition(pct2, PCC_Z, 0) != -1) {
                        pct2 = newpCode(POC_IORLW, newpCodeOpLit(0));
                        pct2->seq = pc2->seq;
                        PCI(pct2)->pcflow = PCFL(pcfl_used);
index 685653cba907bd657d17866ebede8276c64c5b0f..e44fb394bea51581398faeed512c88117cc42546 100644 (file)
@@ -52,7 +52,12 @@ Q ?= @ # be quiet
 CC = sdcc
 LINKER = gplink
 TARGETPIC = 16f877
-CFLAGS = -Wl,--map -I ../../device/include/pic -L ../../device/lib/pic/bin -mpic14 -pp$(TARGETPIC) -Wl,-q --no-pcode-opt
+TARGETPIC = 16f84
+CFLAGS = -mpic14 -p$(TARGETPIC)
+CFLAGS += -Wl,-q
+CFLAGS += -Wl,--map -I ../../device/include/pic
+CFLAGS += -L ../../device/lib/pic/bin
+#CFLAGS += --no-pcode-opt
 
 .SUFFIXES: .asm .c .cod .stc
 
@@ -96,6 +101,7 @@ SRC = add.c \
       mult1.c \
       nestfor.c \
       or1.c \
+      pcodeopt.c \
       pointer1.c \
       ptrarg.c \
       ptrfunc.c \
index 5eb6f93ea7761615d9fa66d3684199a81eec1153..8e39858c8d085dfc783997e19c6af32ec4121098 100644 (file)
@@ -34,6 +34,9 @@
   __endasm; \
   __asm \
   .direct "a", STRINGIFY(e) \
+  __endasm; \
+  __asm \
+  nop \
   __endasm;
 
 #define PASSED() \
@@ -42,6 +45,9 @@
   __endasm; \
   __asm \
   .direct "a", "\"PASSED\"" \
+  __endasm; \
+  __asm \
+  nop \
   __endasm;
 
 #define FAILED() \
   nop \
   __endasm; \
   __asm \
-  .direct "a", "\"FAILED\"" \
+  .direct "a", "\"===> FAILED\"" \
+  __endasm; \
+  __asm \
+  nop \
   __endasm;
 
 #endif
diff --git a/src/regression/pcodeopt.c b/src/regression/pcodeopt.c
new file mode 100644 (file)
index 0000000..8be5a2a
--- /dev/null
@@ -0,0 +1,26 @@
+#include "gpsim_assert.h"
+
+/*
+ * Test for buggy pCode optimization on
+ *    CLRF reg ; pc1
+ *    ...
+ *    MOVF reg,W       ; pc2
+ *
+ * Originally, both instructions were removed and pc2 replaced with
+ *    CLRF reg          iff reg was used afterwards, but Z and W were not, or
+ *    MOVLW 0           iff reg and Z were not used afterwards, but W was.
+ * Detection of W being used used to be buggy, though...
+ */
+signed int x=0;
+unsigned char y=1;
+
+void main() {
+    x += y;
+    x += y;
+    if (x != 2) { FAILED(); }
+    if (y != 1) { FAILED(); }
+    //ASSERT(MANGLE(x) == 2);
+    //ASSERT(MANGLE(y) == 1);
+    PASSED();
+}
+