"ancestor" flow logic was implemented. Applied optimization patches from Frieder...
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 14 Jul 2002 21:19:17 +0000 (21:19 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 14 Jul 2002 21:19:17 +0000 (21:19 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2039 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/pic/genarith.c
src/pic/pcode.c
src/pic/pcode.h
src/pic/pcodeflow.c
src/pic/peeph.def

index d6e5d7968b29617e066bb14461c9799ea969c073..797c7dfc981e6bf6721953ce9fc3307622836209 100644 (file)
@@ -1557,6 +1557,7 @@ void genUMult8XLit_16 (operand *left,
   unsigned int lit;
   unsigned int i,have_first_bit;
   int same;
+  pCodeOp *temp;
 
   if (AOP_TYPE(right) != AOP_LIT){
     fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
@@ -1592,6 +1593,98 @@ void genUMult8XLit_16 (operand *left,
       emitpcode(POC_MOVFW, popGet(AOP(left),0));
       emitpcode(POC_ADDWF, popGet(AOP(left),0));
       emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 5:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      return;
+    case 6:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 7:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 7*F
+      return;
+    case 8:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
+      return;
+    case 9:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 10:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 5*F
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 11:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 11*F
+      return;
+    case 12:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));
+      return;
+    case 13:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 8*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 13*F
+      return;
+    case 14:
+      emitpcode(POC_MOVFW, popGet(AOP(left),0));
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 2*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 3*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 5*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 8*F
+      emitpcode(POC_ADDFW, popGet(AOP(left),0));  // W = 11*F
+      emitpcode(POC_ADDWF, popGet(AOP(left),0));  // F = 14*F
+      return;
+    case 15:
+      temp = popGetTempReg();
+      if(!temp) {
+       fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
+       exit(1);
+      }
+      emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+      emitpcode(POC_MOVWF,  temp);
+      emitpcode(POC_ANDLW,  popGetLit(0xf0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      emitpcode(POC_SWAPFW, temp);
+      emitpcode(POC_SUBWF,  popGet(AOP(left),0));
+      popReleaseTempReg(temp);
       return;
     case 16:
       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
@@ -1603,6 +1696,24 @@ void genUMult8XLit_16 (operand *left,
       emitpcode(POC_ANDLW,  popGetLit(0xf0));
       emitpcode(POC_ADDWF,  popGet(AOP(left),0));
       return;
+    case 32:
+      emitpcode(POC_SWAPF,  popGet(AOP(left),0));
+      emitpcode(POC_RLFW,   popGet(AOP(left),0));
+      emitpcode(POC_ANDLW,  popGetLit(0xe0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      return;
+    case 64:
+      emitpcode(POC_SWAPF,  popGet(AOP(left),0));
+      emitpcode(POC_RLF,    popGet(AOP(left),0));
+      emitpcode(POC_RLFW,   popGet(AOP(left),0));
+      emitpcode(POC_ANDLW,  popGetLit(0xc0));
+      emitpcode(POC_MOVWF,  popGet(AOP(left),0));
+      return;
+    case 128:
+      emitpcode(POC_RRFW,   popGet(AOP(left),0));
+      emitpcode(POC_CLRF,   popGet(AOP(left),0));
+      emitpcode(POC_RRF,    popGet(AOP(left),0));
+      return;
 
     }
   } else {
index 31f5fda3168e8bdf46a27bf261abf40fb6bb9b5c..bbaede8459eb23808e50f27fa9cf5d71d2ac9bf9 100644 (file)
@@ -75,7 +75,7 @@ static pBlock *pb_dead_pcodes = NULL;
 /* Hardcoded flags to change the behavior of the PIC port */
 static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero */
 static int functionInlining = 1;      /* inline functions if nonzero */
-int debug_verbose = 0;                /* Set true to inundate .asm file */
+int debug_verbose = 1;                /* Set true to inundate .asm file */
 
 static int GpCodeSequenceNumber = 1;
 int GpcFlowSeq = 1;
@@ -2707,8 +2707,13 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_FLOW:
-    if(debug_verbose)
-      fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
+    if(debug_verbose) {
+      fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq);
+      if(PCFL(pc)->ancestor)
+       fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
+      fprintf(of,"\n");
+
+    }
     break;
 
   case PC_CSOURCE:
@@ -3368,14 +3373,22 @@ void BuildFlow(pBlock *pb)
       InsertpFlow(pc, &pflow);
       seq = 0;
 
-    } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) {
+    } else if (checkLabel(pc)) { 
 
       /* This instruction marks the beginning of a
        * new flow segment */
 
       pc->seq = 0;
-      seq = 1; 
-      InsertpFlow(findPrevInstruction(pc->prev), &pflow);
+      seq = 1;
+
+      /* If the previous pCode is not a flow object, then 
+       * insert a new flow object. (This check prevents 
+       * two consecutive flow objects from being insert in
+       * the case where a skip instruction preceeds an
+       * instruction containing a label.) */
+
+      if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
+       InsertpFlow(findPrevInstruction(pc->prev), &pflow);
 
       PCI(pc)->pcflow = PCFL(pflow);
       
@@ -4677,11 +4690,10 @@ void AnalyzeFlow(int level)
    * In this phase, the individual flow blocks are examined
    * to determine their order of excution.
    */
-  /*
+
   for(pb = the_pFile->pbHead; pb; pb = pb->next)
     BuildFlowTree(pb);
 
-  */
 
   /* Phase x - Flow Analysis - Used Banks
    *
index 7d5e57f586c43e5f57c84e8c86cd908aa8637d3b..1f1394d2be0937ddec11aa2d9c4407770622f3cc 100644 (file)
@@ -734,6 +734,7 @@ typedef struct peepCommand {
 #define PCL(x)    ((pCodeLabel *)(x))
 #define PCF(x)    ((pCodeFunction *)(x))
 #define PCFL(x)   ((pCodeFlow *)(x))
+#define PCFLINK(x)((pCodeFlowLink *)(x))
 #define PCW(x)    ((pCodeWild *)(x))
 #define PCCS(x)   ((pCodeCSource *)(x))
 
index e3e47e0d4fc1035208010779c0f9d42b139b5c4c..7bc043861e71a2fb74a8333fd3c715b6bbc306e7 100644 (file)
@@ -156,13 +156,9 @@ void BuildFlowTree(pBlock *pb)
 }
 #endif
 
-void BuildFlowTree(pBlock *pb)
+void dbg_dumpFlow(pBlock *pb)
 {
-  pCode *pc=NULL;
   pCode *pcflow;
-  pCode *pct;
-
-  //fprintf(stderr,"linkflow \n");
 
   for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
        pcflow != NULL;
@@ -171,6 +167,183 @@ void BuildFlowTree(pBlock *pb)
     if(!isPCFL(pcflow))
       fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
 
+    fprintf(stderr, "Flow: 0x%x",pcflow->seq);
+    if(PCFL(pcflow) && PCFL(pcflow)->ancestor)
+      fprintf(stderr,", ancestor 0x%x\n",
+             PCFL(pcflow)->ancestor->pc.seq);
+    else {
+      pCodeFlowLink *from = (PCFL(pcflow)->from) ? (PCFLINK(setFirstItem(PCFL(pcflow)->from))) : NULL;
+      fprintf(stderr," no ancestor");
+      while(from) {
+       fprintf(stderr," (0x%x)",from->pcflow->pc.seq);
+       from = setNextItem(PCFL(pcflow)->from);
+      }
+      fprintf(stderr,"\n");
+    }
+  }
+
+}
+/*-----------------------------------------------------------------*
+ * void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
+ *-----------------------------------------------------------------*/
+
+void BuildFlowSegment(pCodeFlow *pcflow)
+{
+  static int recursion=0;
+  pCodeFlow *pcflow_other;
+  set *flowset;
+
+  if(!pcflow)
+    return;
+
+  if(recursion++ > 200) {
+    fprintf(stderr, " exceeded recursion\n");
+    return;
+  }
+
+  fprintf(stderr,"examining 0x%x\n",pcflow->pc.seq);
+
+  if(pcflow->from) {
+
+
+    flowset = pcflow->from;
+
+    if(flowset && flowset->next == NULL) {
+
+      /* 
+        There is a flow before this one. In fact, there's
+        exactly one flow before this one (because ->next is
+        NULL). That means all children of this node pass
+        through both this node and the node immediately 
+        before this one; i.e. they have the same ancestor.
+      */
+
+      if( (NULL == (pcflow_other = PCFLINK(flowset->item)->pcflow)) ||
+         (NULL == pcflow_other)) {
+       fprintf(stderr,"2 error in flow link\n");
+       exit(1);
+      }
+      pcflow->ancestor = pcflow_other->ancestor ;
+
+      fprintf(stderr,"Assigning ancestor 0x%x from flow 0x%x\n",
+             pcflow->ancestor->pc.seq, pcflow_other->pc.seq);
+
+    } else {
+
+      if(flowset == NULL) {
+
+       /* There are no flows before this one.
+        * If this is not the first flow object in the pBlock then 
+        * there's an error */
+
+       if(!pcflow->ancestor) {
+         fprintf(stderr,"error in flow link\n");
+         exit(1);
+
+       } 
+
+      } else {
+
+       /* Flow passes to this flow from multiple flows. Let's
+          look at just one of these. If the one we look at has
+          an ancestor, then that's our ancestor too. If the one
+          we look at doesn't have an ancestor, then that means
+          we haven't traversed that branch of the call tree 
+          yet - but we will */
+
+       pcflow_other = PCFLINK(flowset->item)->pcflow;
+       if(pcflow_other) {
+         fprintf(stderr, "coming from 0x%x\n",pcflow_other->pc.seq);
+         if( pcflow_other->ancestor)
+           pcflow->ancestor = pcflow_other->ancestor;
+       }
+      }
+
+
+    }
+
+  } else {
+    /* there are no nodes before this one */
+    if(!pcflow->ancestor)
+      fprintf(stderr,"3 Error in flow link\n");
+  }
+
+  /* Now let's recursively expand the call tree */
+
+  if(pcflow->ancestor && pcflow->to) {
+    flowset = pcflow->to;
+    while(flowset) {
+      BuildFlowSegment(PCFLINK(flowset->item)->pcflow);
+      flowset = flowset->next;
+    }
+  }
+
+}
+
+void BuildFlowTree(pBlock *pb)
+{
+  pCodeFlow *first_pcflow, *pcflow;
+
+
+  //  fprintf(stderr,"BuildFlowTree \n");
+
+  first_pcflow = PCFL(findNextpCode(pb->pcHead, PC_FLOW));
+  if(!first_pcflow)
+    return;
+
+  /* The very first node is like Adam, it's its own ancestor (i.e. 
+   * there are no other flows in this pBlock prior to the first one).
+   */
+
+  first_pcflow->ancestor = first_pcflow;
+
+  /* For each flow that has only one predecessor, it's easy to 
+     identify the ancestor */
+  pcflow = PCFL(findNextpCode(first_pcflow->pc.next, PC_FLOW));
+
+  while(pcflow) {
+    if(elementsInSet(pcflow->from) == 1) {
+      pCodeFlowLink *from = PCFLINK(setFirstItem(pcflow->from));
+
+      pcflow->ancestor = from->pcflow;
+      /*
+       fprintf(stderr,"Assigning ancestor 0x%x to flow 0x%x\n",
+       pcflow->ancestor->pc.seq, pcflow->pc.seq);
+      */
+    }
+
+    pcflow = PCFL(findNextpCode(pcflow->pc.next, PC_FLOW));
 
   }
+
+  pcflow = PCFL(findNextpCode(first_pcflow->pc.next, PC_FLOW));
+
+  while(pcflow) {
+    if(elementsInSet(pcflow->from) > 1) {
+      pCodeFlow *min_pcflow;
+      pCodeFlowLink *from = PCFLINK(setFirstItem(pcflow->from));
+
+      min_pcflow = from->pcflow;
+
+      while( (from = setNextItem(pcflow->from)) != NULL) {
+       if(from->pcflow->pc.seq < min_pcflow->pc.seq)
+         min_pcflow = from->pcflow;
+      }
+
+      pcflow->ancestor = min_pcflow;
+      /*
+       fprintf(stderr,"Assigning ancestor 0x%x to flow 0x%x from multiple\n",
+       pcflow->ancestor->pc.seq, pcflow->pc.seq);
+      */
+
+    }
+
+    pcflow = PCFL(findNextpCode(pcflow->pc.next, PC_FLOW));
+
+  }
+  
+  //  BuildFlowSegment(pcflow);
+
+  //dbg_dumpFlow(pb);
+  
 }
index 44a9b966c6ed8455dd6b9d7bb01269097e376c39..0dccf7b06ef91d512f93bf939f3a127a4f353417 100644 (file)
@@ -112,7 +112,7 @@ replace restart {
        %4
 %3:    %5
 } by {
-       ;peep 1 - test/jump to test/skip
+       ;     peep 1 - test/jump to test/skip
         %1
        _INVERTBITSKIP_ %2
        %4
@@ -126,7 +126,7 @@ replace restart {
 %4:    %5
 %3:    %6
 } by {
-       ;peep 1b - test/jump to test/skip
+       ;     peep 1b - test/jump to test/skip
         %1
        _INVERTBITSKIP_ %2
 %4:    %5
@@ -156,7 +156,7 @@ replace restart {
        movwf   %1
        movf    %1,w
 } by {
-       ; peep 2 - Removed redundant move
+       ;     peep 2 - Removed redundant move
        movwf   %1
 } if NZ
 
@@ -167,7 +167,7 @@ replace restart {
        btfss   _STATUS,z
        goto    %2
 } by {
-       ; peep 3 - decf/mov/skpz to decfsz
+       ;     peep 3 - decf/mov/skpz to decfsz
        decfsz  %1,f
         goto   %2
 }
@@ -177,7 +177,7 @@ replace restart {
        movf    %1,w
        movf    %1,w
 } by {
-       ; peep 4 - Removed redundant move
+       ;     peep 4 - Removed redundant move
        movf    %1,w
 }
 
@@ -187,7 +187,7 @@ replace restart {
        movwf   %2
        movlw   %1
 } by {
-       ; peep 5 - Removed redundant move
+       ;     peep 5 - Removed redundant move
        movlw   %1
        movwf   %2
 }
@@ -196,7 +196,7 @@ replace restart {
        movwf   %1
        movwf   %1
 } by {
-       ; peep 6 - Removed redundant move
+       ;     peep 6 - Removed redundant move
        movwf   %1
 }
 
@@ -204,7 +204,7 @@ replace restart {
        movlw   0
        iorwf   %1,w
 } by {
-       ; peep 7 - Removed redundant move
+       ;     peep 7 - Removed redundant move
        movf    %1,w
 }
 
@@ -213,7 +213,7 @@ replace restart {
        movwf   %2
        decf    %2,f
 } by {
-       ; peep 8 - Removed redundant move
+       ;     peep 8 - Removed redundant move
        decf    %1,w
        movwf   %2
 }
@@ -223,7 +223,7 @@ replace restart {
        movf    %2,w
        xorwf   %1,w
 } by {
-       ; peep 9a - Removed redundant move
+       ;     peep 9a - Removed redundant move
        movwf   %1
        xorwf   %2,w
 }
@@ -233,7 +233,7 @@ replace restart {
        movf    %2,w
        iorwf   %1,w
 } by {
-       ; peep 9b - Removed redundant move
+       ;     peep 9b - Removed redundant move
        movwf   %1
        iorwf   %2,w
 }
@@ -243,7 +243,7 @@ replace restart {
        movwf   %2
        movf    %2,w
 } by {
-       ; peep 9c - Removed redundant move
+       ;     peep 9c - Removed redundant move
        movf    %1,w
        movwf   %2
 }
@@ -253,27 +253,17 @@ replace restart {
        movf    %1,w
        movwf   %2
 } by {
-       ; peep 9d - Removed redundant move
+       ;     peep 9d - Removed redundant move
        movwf   %1
        movwf   %2
 } if NZ
 
-//replace restart {
-//     movwf   %1
-//     iorlw   0
-//     movf    %1,w
-//} by {
-//     ; peep 10 - Removed unnecessary iorlw
-//     movwf   %1
-//     movf    %1
-//} 
-
 // From: Frieder Ferlemann
 
 replace restart {
         iorlw   0
 } by {
-        ; peep 10a - Removed unnecessary iorlw
+        ;     peep 10a - Removed unnecessary iorlw
 } if NZ
 
 // From: Frieder Ferlemann
@@ -281,7 +271,7 @@ replace restart {
 replace restart {
         xorlw   0
 } by {
-        ; peep 10b - Removed unnecessary xorlw
+        ;     peep 10b - Removed unnecessary xorlw
 } if NZ
 
 // From: Frieder Ferlemann
@@ -290,6 +280,6 @@ replace restart {
         movf    %1,w
         movwf   %1
 } by {
-        ; peep 11 - Removed redundant move
+        ;     peep 11 - Removed redundant move
         movf    %1,w
 }