Slade Rich fixed an optimization bug
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 30 Jan 2004 10:26:59 +0000 (10:26 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 30 Jan 2004 10:26:59 +0000 (10:26 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3160 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/pic/pcodepeep.c
src/pic/pcoderegs.c

index cc806f63b10cb2af285ec268f100ba0ce1d97f7e..617213d970538097304222744c350ab8e0d510bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 2004-01-30 Bernhard Held <bernhard AT bernhardheld.de>
 
        * support/regression/tests/libmullong.c: fixed for 64 bit hosts
+       Slade Rich fixed an optimization bug
+       * src/pic/pcodepeep.c,
+       * src/pic/pcoderegs.c
 
 2004-01-30 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
 
index 4a37e7d181d7b613d449ecf5004058aa52ce8bc0..f23249a618a382ed2e741473adb886c862c0a070 100644 (file)
@@ -47,6 +47,7 @@ char *pCode2str(char *str, int size, pCode *pc);
 char *get_op( pCodeOp *pcop,char *buf,int buf_size);
 
 extern pCodeInstruction *pic14Mnemonics[];
+extern pCode * findPrevInstruction(pCode *pci);
 
 
 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
@@ -1476,9 +1477,8 @@ static void * DLL_append(_DLL *list, _DLL *next)
 /* -1 - The Condition was found for a pCode's output               */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-int pCodeSearchCondition(pCode *pc, unsigned int cond)
+int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
 {
-  //fprintf(stderr,"Checking conditions %d\n",cond);
   while(pc) {
 
     /* If we reach a function end (presumably an end since we most
@@ -1488,13 +1488,28 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond)
       return 0;
 
     if(pc->type == PC_OPCODE) {
-      //fprintf(stderr," checking conditions of: ");
-      //pc->print(stderr,pc);
-      //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond);
-      if(PCI(pc)->inCond & cond)
-       return 1;
-      if(PCI(pc)->outCond & cond)
-       return -1;
+      if(PCI(pc)->inCond & cond) {
+        if (contIfSkip) {
+          /* If previous instruction is a skip then continue search as condiction is not certain */
+          pCode *pcp = findPrevInstruction(pc);
+          if (pcp && !isPCI_SKIP(pcp)) {
+            return 1;
+          }
+        } else {
+          return 1;
+        }
+      }
+      if(PCI(pc)->outCond & cond) {
+        if (contIfSkip) {
+          /* If previous instruction is a skip then continue search as condiction is not certain */
+          pCode *pcp = findPrevInstruction(pc);
+          if (pcp && !isPCI_SKIP(pcp)) {
+            return -1;
+          }
+        } else {
+          return -1;
+        }
+      }
     }
 
     pc = pc->next;
@@ -1966,7 +1981,7 @@ int pCodePeepMatchRule(pCode *pc)
       //pcin->print(stderr,pcin);
       
       if (pcin && peepBlock->postFalseCond && 
-         (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
+         (pCodeSearchCondition(pcin,peepBlock->postFalseCond,0) > 0) )
        matched = 0;
 
       //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
index 0ead86a2f96a2354140df8052c5c68c74c3d63dc..f6b26aa0b654296714ff0fc41eaaf69067c793f4 100644 (file)
@@ -40,7 +40,7 @@ extern void dbg_dumpregusage(void);
 extern pCode * findPrevInstruction(pCode *pci);
 extern pBranch * pBranchAppend(pBranch *h, pBranch *n);
 void unlinkpCode(pCode *pc);
-extern int pCodeSearchCondition(pCode *pc, unsigned int cond);
+extern int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip);
 char *pCode2str(char *str, int size, pCode *pc);
 void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...);
 int total_registers_saved=0;
@@ -458,64 +458,38 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
   //pc2->print(stderr,pc2);
 
   if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
-    pCode *pc;
+    pCode *newpc;
     int regUsed = 0;
     int wUsed   = 0;
     int wSaved  = 0;
-    int wChgd   = 0;
-
     /*
-      clrf  reg
+      clrf  reg    ; pc1
       stuff...
-      movf  reg,w
+      movf  reg,w  ; pc2
 
-      can be replaced with (only if next instructions are not going to use W and reg is not used again later)
+      can be replaced with (only if following instructions are not going to use W and reg is not used again later)
 
       stuff...
       movlw 0 or clrf  reg
     */
-
-    pCode *newpc;
     DFPRINTF((stderr, "   optimising CLRF reg ... MOVF reg,W to ... MOVLW 0\n"));
-    pct1 = pc = findNextInstruction(pc2->next);
+    pct2 = findNextInstruction(pc2->next);
 
-    if(PCI(pct1)->op == POC_MOVWF) {
+    if(pct2 && PCI(pct2)->op == POC_MOVWF) {
       wSaved = wUsed = 1; /* Maybe able to replace with clrf pc2->next->reg. */
-      pc = findNextInstruction(pc->next);
-    }
-    for (; pc; pc = findNextInstruction(pc->next)) {
-      if (isPCI(pc)) {
-        regs *r;
-        if (!wChgd) {
-          if (PCI(pc)->inCond & PCC_W)
-            wUsed = 1;
-          if (PCI(pc)->outCond & PCC_W) {
-            pCode *pcp = findPrevInstruction(pc);
-            if (pcp && !isPCI_SKIP(pcp)) {
-              wChgd = 1; /* W has changed so we no longer care if it is used, however if there is a preceding skip instruction then maybe current W is still going to be used */
-            if (regUsed)
-              break;
-            }
-          }
-        }
-        r = getRegFromInstruction(pc); /* Check if reg is used later. */
-        if (r && (r->rIdx==reg->rIdx)) {
-          if (!(PCI(pc)->outCond & PCC_REGISTER))
-            regUsed = 1;
-          if (wChgd)
-            break;
-        }
-      }
+       } else {
+               wUsed = pCodeSearchCondition(pct2,PCC_W,1) > 0;
     }
-    if(regUsed&&wUsed) {
+    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(pct1)->pcop);
-        pct1->destruct(pct1);
+        newpc = newpCode(POC_CLRF, PCI(pct2)->pcop);
+        pct2->destruct(pct2);
       } else {
         newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
       }
@@ -532,7 +506,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
 
     pct2 = findNextInstruction(pc2->next);
 
-    if(pCodeSearchCondition(pct2, PCC_Z) > 0) {
+    if(pCodeSearchCondition(pct2, PCC_Z,0) > 0) {
       pct2 = newpCode(POC_IORLW, newpCodeOpLit(0));
       pct2->seq = pc2->seq;
       PCI(pct2)->pcflow = PCFL(pcfl_used);
@@ -553,47 +527,36 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
         /*
         Change:
 
-        movwf   reg
-
+        movwf   reg    ; pc1
         stuff...
+        movf    reg,w  ; pc2
+        movwf   reg2   ; pct2
 
-        movf    reg,w
-        movwf   reg2
-
-        To:
+        To: ( as long as 'stuff' does not use reg2 or if following instructions do not use W or reg is not used later)
 
+        movwf   reg2
+        stuff...
 
         */
         reg2 = getRegFromInstruction(pct2);
-        if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
-
-          if(pCodeSearchCondition(pct2, PCC_Z) < 1) {
-            pCode *pct3 = findNextInstruction(pct2->next);
-            DFPRINTF((stderr, "   optimising MOVF reg ... MOVF reg,W MOVWF reg2\n"));
+        /* Check reg2 is not used for something else before it is loaded with reg */
+        if (reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+          pCode *pct3 = findNextInstruction(pct2->next);
+          /* Check following instructions are not relying on the use of W or the Z flag condiction */
+          if ((pCodeSearchCondition(pct3,PCC_Z,0) < 1) || (pCodeSearchCondition(pct3,PCC_W,0) < 1)) {
+            DFPRINTF((stderr, "   optimising MOVF reg ... MOVF reg,W MOVWF reg2 to MOVWF reg2 ...\n"));
             pct2->seq = pc1->seq;
             unlinkpCode(pct2);
-            pCodeInsertAfter(findPrevInstruction(pc1->prev),pct2);
-
-#define usesW(x)       ((x) && (isPCI(x)) && ( (PCI(x)->inCond & PCC_W) != 0))
-
-            if(usesW(pct3))
-              ; // Remove2pcodes(pcfl_used, pc1, NULL, reg, can_free);
+            pCodeInsertBefore(pc1,pct2);
+            if(regUsedinRange(pct2,0,reg))
+              Remove2pcodes(pcfl_used, pc2, NULL, reg, can_free);
             else
               Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
 
             total_registers_saved++;  // debugging stats.
             return 1;
-            } else {
-              //fprintf(stderr,"didn't optimize because Z bit is used\n");
-            }
+          }
         }
-/*
-        fprintf(stderr, " couldn't optimize\n");
-        if(reg2)
-          fprintf(stderr, " %s is used in range\n",reg2->name);
-        else
-          fprintf(stderr, " reg2 is NULL\n");
-*/
       }
     }