Function inlining works well now. Added more flow analysis.
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 2 Jun 2002 22:40:29 +0000 (22:40 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 2 Jun 2002 22:40:29 +0000 (22:40 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2021 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/pic/genarith.c
src/pic/glue.c
src/pic/pcode.c
src/pic/pcodepeep.c

index de312a503aafa1efc7831f4a270325dbbf94bc24..2e701a04254b396bf9930c553fc06c952df182bc 100644 (file)
@@ -905,13 +905,11 @@ void genPlus (iCode *ic)
        if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
          emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
        else {
-         if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
-             (AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) ||
-             (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
-           emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0));
-         } else {
-           emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0));
-         }
+         PIC_OPCODE poc = POC_ADDFW;
+
+         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL)
+           poc = POC_ADDLW;
+         emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0));
          if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
            emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
        }
index e41cd3dfebb8f49d95944ce2819f2c6cb4fbf78c..c3248fdcdf89329773626340297a980eebd92162 100644 (file)
@@ -818,11 +818,11 @@ picglue ()
   //#ifdef PCODE_DEBUG
   //printCallTree(stderr);
   //#endif
-/*
+
   InlinepCode();
 
   AnalyzepCode('*');
-*/
+
   pcode_test();
 
 
index c330f6f3fce837f223d0df8729a241ba75530b48..f3d3f56fe2c2a8cfe9abb0561bcee5f80ad6bfd3 100644 (file)
@@ -80,6 +80,10 @@ static int GpcFlowSeq = 1;
 #define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip && PCI(x)->isBitInst)
 #define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
 #define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
+#define isPCL(x)        ((PCODE(x)->type == PC_LABEL))
+#define isPCW(x)        ((PCODE(x)->type == PC_WILD))
+#define isPCCS(x)       ((PCODE(x)->type == PC_CSOURCE))
+
 #define isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
 #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
 
@@ -1744,6 +1748,19 @@ pCode *newpCodeFunction(char *mod,char *f)
 /* newpCodeFlow                                                    */
 /*-----------------------------------------------------------------*/
 
+void destructpCodeFlow(pCode *pc)
+{
+  if(!pc || !isPCFL(pc))
+    return;
+
+  if(PCFL(pc)->uses)
+    free(PCFL(pc)->uses);
+/*
+  if(PCFL(pc)->from)
+  if(PCFL(pc)->to)
+*/
+  free(pc);
+}
 
 pCode *newpCodeFlow(void )
 {
@@ -1758,7 +1775,7 @@ pCode *newpCodeFlow(void )
   pcflow->pc.pb = NULL;
 
   //  pcflow->pc.analyze = genericAnalyze;
-  pcflow->pc.destruct = genericDestruct;
+  pcflow->pc.destruct = destructpCodeFlow;
   pcflow->pc.print = genericPrint;
 
   pcflow->pc.seq = GpcFlowSeq++;
@@ -2294,7 +2311,7 @@ static void unlinkPC(pCode *pc)
 }
 static void genericDestruct(pCode *pc)
 {
-  fprintf(stderr,"warning, calling default pCode destructor\n");
+  //fprintf(stderr,"warning, calling default pCode destructor\n");
 
   unlinkPC(pc);
 
@@ -2574,7 +2591,7 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_FLOW:
-    fprintf(of,";Start of new flow, seq=%d\n",pc->seq);
+    fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
     break;
 
   case PC_CSOURCE:
@@ -2657,8 +2674,12 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
 
   }
 
+  //fprintf (stderr, "%s \n",__FUNCTION__);
+  //pcl->print(stderr,pcl);
+  //pc->print(stderr,pc);
   while(b) {
     if(b->pc == pc) {
+      //fprintf (stderr, "found label\n");
 
       /* Found a label */
       if(bprev) {
@@ -2675,30 +2696,6 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
     b = b->next;
   }
 
-#if 0
-
-  original stuff:
-
-  bprev = NULL;
-  b = pcl->label;
-  while(b) {
-    if(b->pc == pc) {
-
-      /* Found a label */
-      if(bprev) {
-       bprev->next = b->next;  /* Not first pCode in chain */
-       free(b);
-      } else {
-       pc->destruct(pc);
-       pcl->label = b->next;   /* First pCode in chain */
-       free(b);
-      }
-      return;  /* A label can't occur more than once */
-    }
-    bprev = b;
-    b = b->next;
-  }
-#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -2848,6 +2845,7 @@ static void genericAnalyze(pCode *pc)
 }
 #endif
 
+/*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
 {
@@ -2871,6 +2869,25 @@ int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
   return FALSE;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+int checkLabel(pCode *pc)
+{
+  pBranch *pbr;
+
+  if(pc && isPCI(pc)) {
+    pbr = PCI(pc)->label;
+    while(pbr) {
+      if(isPCL(pbr->pc) && (PCL(pbr->pc)->key >= 0))
+       return TRUE;
+
+      pbr = pbr->next;
+    }
+  }
+
+  return FALSE;
+}
+
 /*-----------------------------------------------------------------*/
 /* findLabel - Search the pCode for a particular label             */
 /*-----------------------------------------------------------------*/
@@ -3169,22 +3186,43 @@ void BuildFlow(pBlock *pb)
     pc->seq = seq++;
     PCI(pc)->pcflow = PCFL(pflow);
 
-    if(PCI(pc)->isSkip || PCI(pc)->isBranch)  {
+    if( PCI(pc)->isSkip) {
 
-      /* The instruction immediately following this one 
-       * marks the beginning of a new flow segment */
+      /* The two instructions immediately following this one 
+       * mark the beginning of a new flow segment */
+
+      while(pc && PCI(pc)->isSkip) {
+
+       PCI(pc)->pcflow = PCFL(pflow);
+       pc->seq = seq-1;
+       seq = 1;
+
+       InsertpFlow(pc, &pflow);
+       pc=findNextInstruction(pc->next);
+      }
+
+      seq = 0;
+
+      if(!pc)
+       break;
+
+      PCI(pc)->pcflow = PCFL(pflow);
+      pc->seq = 0;
+      InsertpFlow(pc, &pflow);
+
+    } else if ( PCI(pc)->isBranch && !checkLabel(findNextInstruction(pc->next)))  {
 
       InsertpFlow(pc, &pflow);
       seq = 0;
-         
-    } else if (PCI_HAS_LABEL(pc)) {
+
+    } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) {
 
       /* This instruction marks the beginning of a
        * new flow segment */
 
       pc->seq = 0;
       seq = 1; 
-      InsertpFlow(pc->prev, &pflow);
+      InsertpFlow(findPrevInstruction(pc->prev), &pflow);
 
       PCI(pc)->pcflow = PCFL(pflow);
       
@@ -3197,6 +3235,38 @@ void BuildFlow(pBlock *pb)
   PCFL(pflow)->end = pb->pcTail;
 }
 
+/*-------------------------------------------------------------------*/
+/* unBuildFlow(pBlock *pb) - examine the code in a pBlock and build  */
+/*                           the flow blocks.                        */
+/*
+ * unBuildFlow removes pCodeFlow objects from a pCode chain
+ */
+/*-----------------------------------------------------------------*/
+void unBuildFlow(pBlock *pb)
+{
+  pCode *pc;
+
+  if(!pb)
+    return;
+
+  pc = pb->pcHead;
+  while(pc) {
+    pCode *pcn = pc->next;
+
+    if(isPCI(pc)) {
+      pc->seq = 0;
+      PCI(pc)->pcflow = NULL;
+      pc = pcn;
+    } else if(isPCFL(pc)) {
+      unlinkPC(pc);
+      pc->destruct(pc);
+    } else 
+      pc = pcn;
+
+  }
+
+}
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 void dumpCond(int cond)
@@ -3227,6 +3297,33 @@ void dumpCond(int cond)
 
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void FlowStats(pCodeFlow *pcflow)
+{
+
+  pCode *pc;
+
+  if(!isPCFL(pcflow))
+    return;
+
+  fprintf(stderr, " FlowStats - flow block (seq=%d)\n", pcflow->pc.seq);
+
+  pc = findNextpCode(PCODE(pcflow), PC_OPCODE); 
+
+  if(!pc) {
+    fprintf(stderr, " FlowStats - empty flow (seq=%d)\n", pcflow->pc.seq);
+    return;
+  }
+
+
+  fprintf(stderr, "  FlowStats inCond: ");
+  dumpCond(pcflow->inCond);
+  fprintf(stderr, "  FlowStats outCond: ");
+  dumpCond(pcflow->outCond);
+
+}
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 void FillFlow(pCodeFlow *pcflow)
@@ -3241,35 +3338,39 @@ void FillFlow(pCodeFlow *pcflow)
   //  fprintf(stderr, " FillFlow - flow block (seq=%d)\n", pcflow->pc.seq);
 
   pc = findNextpCode(PCODE(pcflow), PC_OPCODE); 
+
   if(!pc) {
-    //    fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq);
+    //fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq);
     return;
   }
 
   cur_bank = -1;
 
   do {
-    //regs *reg;
+    regs *reg;
 
-    int inCond = PCI(pc)->inCond;
-    int outCond = PCI(pc)->outCond;
-#if 0
-    if( (reg = getRegFromInstruction(pc)) != NULL) {
-      if(isSTATUS_REG(reg)) {
+    if(isPCI(pc)) {
+
+      int inCond = PCI(pc)->inCond;
+      int outCond = PCI(pc)->outCond;
 
-       //fprintf(stderr, "  FillFlow - Status register\n");
+      if( (reg = getRegFromInstruction(pc)) != NULL) {
+       if(isSTATUS_REG(reg)) {
 
-       /* Check to see if the register banks are changing */
-       if(PCI(pc)->isModReg) {
+         //fprintf(stderr, "  FillFlow - Status register\n");
+         //pc->print(stderr,pc);
+         /* Check to see if the register banks are changing */
+         if(PCI(pc)->isModReg) {
 
-         pCodeOp *pcop = PCI(pc)->pcop;
-         switch(PCI(pc)->op) {
+           pCodeOp *pcop = PCI(pc)->pcop;
+           switch(PCI(pc)->op) {
+             /*
            case POC_BSF:
              if(PCORB(pcop)->bit == PIC_RP0_BIT)
                fprintf(stderr, "  FillFlow - Set RP0\n");
              //outCond |= PCC_REG_BANK1;
              if(PCORB(pcop)->bit == PIC_RP1_BIT) 
-               fprintf(stderr, "  FillFlow - Set RP1\n");
+               //fprintf(stderr, "  FillFlow - Set RP1\n");
              //outCond |= PCC_REG_BANK3;
              break;
 
@@ -3281,38 +3382,39 @@ void FillFlow(pCodeFlow *pcflow)
                fprintf(stderr, "  FillFlow - Clr RP1\n");
              //outCond |= PCC_REG_BANK3;
              break;
-
-         default:
-           fprintf(stderr, "  FillFlow - Status register is getting Modified by:\n");
-           genericPrint(stderr, pc);
+             */
+           default:
+             fprintf(stderr, "  FillFlow - Status register is getting Modified by:\n");
+             genericPrint(stderr, pc);
+           }
          }
-       }
 
-      } else
-       inCond |= PCC_REG_BANK0 << (REG_BANK(reg) & 3);
-    }
-#endif
-
-    pcflow->inCond |= (inCond &  ~pcflow->outCond);
-    pcflow->outCond |= outCond;
-
-    
+       } else
+         inCond |= PCC_REG_BANK0 << (REG_BANK(reg) & 3);
+      }
 
+      pcflow->inCond |= (inCond &  ~pcflow->outCond);
+      pcflow->outCond |= outCond;
+    } 
 
-    pc = findNextpCode(pc->next, PC_OPCODE);
-  } while (pc && (pc != pcflow->end));
+    pc = pc->next;
+  } while (pc && (pc != pcflow->end) && !isPCFL(pc));
 
-#if 0
-  if(!pc)
+/*
+  if(!pc ) {
     fprintf(stderr, "  FillFlow - Bad end of flow\n");
-
+  } else {
+    fprintf(stderr, "  FillFlow - Ending flow with\n  ");
+    pc->print(stderr,pc);
+  }
 
   fprintf(stderr, "  FillFlow inCond: ");
   dumpCond(pcflow->inCond);
   fprintf(stderr, "  FillFlow outCond: ");
   dumpCond(pcflow->outCond);
-#endif
+*/
 }
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
@@ -3334,10 +3436,9 @@ void LinkFlow(pBlock *pb)
   pCode *pcflow;
   pCode *pct;
 
-  
+  //fprintf(stderr,"linkflow \n");
   for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
-      (pcflow = findNextpCode(pcflow, PC_FLOW)) != NULL;
-      pcflow = pcflow->next) {
+       (pcflow = findNextpCode(pcflow->next, PC_FLOW)) != NULL;) {
 
     if(!isPCFL(pcflow))
       fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
@@ -3356,19 +3457,19 @@ void LinkFlow(pBlock *pb)
       continue;
     }
 
-    if(isPCI_BRANCH(pc)) {
-      //fprintf(stderr, "ends with branch\n");
+    //if(isPCI_BRANCH(pc)) {
+    //fprintf(stderr, "ends with branch\n");
 
-      continue;
-    }
-#if 0
-    if(pc) {
-      fprintf(stderr, "has an unrecognized ending:\n");
-      pc->print(stderr,pc);
+    // continue;
+    //}
+    #if 0
+    if(isPCI(pc)) {
+      fprintf(stderr, "ends with non-branching instruction:\n");
+      //pc->print(stderr,pc);
     }
     else 
       fprintf(stderr, "has no end pcode\n");
-#endif 
+    #endif 
     
   }
 }
@@ -3431,6 +3532,32 @@ pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs)
   return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void exchangeLabels(pCodeLabel *pcl, pCode *pc)
+{
+
+  if(isPCI(pc) && 
+     (PCI(pc)->pcop) && 
+     (PCI(pc)->pcop->type == PO_LABEL)) {
+
+    pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop);
+
+    //fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key);
+    if(pcol->pcop.name)
+      free(pcol->pcop.name);
+
+    sprintf(buffer,"_%05d_DS_",pcl->key);
+
+    pcol->pcop.name = Safe_strdup(buffer);
+    pcol->key = pcl->key;
+    //pc->print(stderr,pc);
+
+  }
+
+
+}
+
 /*-----------------------------------------------------------------*/
 /* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
 /*                            pCode chain if they're not used.     */
@@ -3442,21 +3569,50 @@ void pBlockRemoveUnusedLabels(pBlock *pb)
   if(!pb)
     return;
 
+  for(pc = pb->pcHead; (pc=findNextInstruction(pc->next)) != NULL; ) {
+
+    pBranch *pbr = PCI(pc)->label;
+    if(pbr && pbr->next) {
+      pCode *pcd = pb->pcHead;
+
+      //fprintf(stderr, "multiple labels\n");
+      //pc->print(stderr,pc);
+
+      pbr = pbr->next;
+      while(pbr) {
+
+       while ( (pcd = findInstructionUsingLabel(PCL(PCI(pc)->label->pc), pcd)) != NULL) {
+         //fprintf(stderr,"Used by:\n");
+         //pcd->print(stderr,pcd);
+
+         exchangeLabels(PCL(pbr->pc),pcd);
+
+         pcd = pcd->next;
+       }
+       pbr = pbr->next;
+      }
+    }
+  }
+
   for(pc = pb->pcHead; pc; pc = pc->next) {
 
-    if(pc->type == PC_LABEL)
+    if(isPCL(pc)) // pc->type == PC_LABEL)
       pcl = PCL(pc);
-    else if ((pc->type == PC_OPCODE) && PCI(pc)->label)
+    else if (isPCI(pc) && PCI(pc)->label) //((pc->type == PC_OPCODE) && PCI(pc)->label)
       pcl = PCL(PCI(pc)->label->pc);
     else continue;
 
-      /* This pCode is a label, so search the pBlock to see if anyone
-       * refers to it */
+    //fprintf(stderr," found  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
+
+    /* This pCode is a label, so search the pBlock to see if anyone
+     * refers to it */
 
     if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) {
+    //if( !findInstructionUsingLabel(pcl, pb->pcHead)) {
       /* Couldn't find an instruction that refers to this label
        * So, unlink the pCode label from it's pCode chain
        * and destroy the label */
+      //fprintf(stderr," removed  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
 
       DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label));
       if(pc->type == PC_LABEL) {
@@ -3800,8 +3956,17 @@ void AnalyzeBanking(void)
       FillFlow(PCFL(pcflow));
     }
   }
+/*
+  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+    pCode *pcflow;
+    for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
+        (pcflow = findNextpCode(pcflow, PC_FLOW)) != NULL;
+        pcflow = pcflow->next) {
 
-
+      FlowStats(PCFL(pcflow));
+    }
+  }
+*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -3928,12 +4093,14 @@ void AnalyzepCode(char dbName)
   do {
 
     DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1));
+    //fprintf(stderr," Analyzing pCode: PASS #%d\n",i+1);
 
     /* First, merge the labels with the instructions */
     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
       if('*' == dbName || getpBlock_dbName(pb) == dbName) {
 
        DFPRINTF((stderr," analyze and merging block %c\n",dbName));
+       //fprintf(stderr," analyze and merging block %c\n",dbName);
        pBlockMergeLabels(pb);
        AnalyzepBlock(pb);
       } else {
@@ -4402,6 +4569,7 @@ void InlinepCode(void)
 
   /* Loop through all of the function definitions and count the
    * number of times each one is called */
+  //fprintf(stderr,"inlining %d\n",__LINE__);
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
 
@@ -4420,10 +4588,15 @@ void InlinepCode(void)
     }
   }
 
+  //fprintf(stderr,"inlining %d\n",__LINE__);
 
   /* Now, Loop through the function definitions again, but this
    * time inline those functions that have only been called once. */
 
   InlineFunction(the_pFile->pbHead);
+  //fprintf(stderr,"inlining %d\n",__LINE__);
+
+  for(pb = the_pFile->pbHead; pb; pb = pb->next)
+    unBuildFlow(pb);
 
 }
index 6963f5fb385ee982b26defd462ad806c6805a3b3..9083d1b932493c7fe39741f563cbcf20bf5a1210 100644 (file)
@@ -1862,7 +1862,7 @@ void pCodeDeleteChain(pCode *f,pCode *t)
   while(f && f!=t) {
     DFPRINTF((stderr,"delete pCode:\n"));
     pc = f->next;
-    f->print(stderr,f);
+    //f->print(stderr,f);
     //f->delete(f);  this dumps core...
 
     f = pc;
@@ -1967,7 +1967,7 @@ int pCodePeepMatchRule(pCode *pc)
        pcin->prev = pc->prev;
 
 
-
+#if 0
       {
        /*     DEBUG    */
        /* Converted the deleted pCodes into comments */
@@ -1999,6 +1999,7 @@ int pCodePeepMatchRule(pCode *pc)
        if(pc_cline2)
          pc_cline2->pc.next = NULL;
       }
+#endif
 
       if(pcin)
        pCodeDeleteChain(pc,pcin);