Added pcodeflow.c - much of pcode.c will eventually get moved here.
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 10 Jul 2002 13:32:21 +0000 (13:32 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 10 Jul 2002 13:32:21 +0000 (13:32 +0000)
Added the CLRWDT instruction to the list of valid PIC instructions.
Added two new peep hole rules from Frieder Ferlemann.

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

src/pic/pcode.c
src/pic/pcode.h
src/pic/pcodeflow.c [new file with mode: 0644]
src/pic/pcoderegs.c
src/pic/peeph.def

index 49568d18af0094ad80160b47317249e0415add12..41c8f80dc410da1183a16ac61a8472048b9fb7d4 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 = 1;                /* Set true to inundate .asm file */
+int debug_verbose = 0;                /* Set true to inundate .asm file */
 
 static int GpCodeSequenceNumber = 1;
 int GpcFlowSeq = 1;
@@ -435,6 +435,27 @@ pCodeInstruction pciCLRW = {
   PCC_W  // outCond
 };
 
+pCodeInstruction pciCLRWDT = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CLRWDT,
+  "CLRWDT",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
+  NULL, // operand
+  NULL, // flow block
+  NULL, // C source 
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  0,0,  // branch, skip
+  POC_NOP,
+  PCC_NONE, // inCond
+  PCC_NONE  // outCond
+};
+
 pCodeInstruction pciDECF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
    //   genericAnalyze,
@@ -3587,8 +3608,15 @@ void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
 
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*
+ * void LinkFlow(pBlock *pb)
+ *
+ * In BuildFlow, the PIC code has been partitioned into contiguous
+ * non-branching segments. In LinkFlow, we determine the execution
+ * order of these segments. For example, if one of the segments ends
+ * with a skip, then we know that there are two possible flow segments
+ * to which control may be passed.
+ *-----------------------------------------------------------------*/
 void LinkFlow(pBlock *pb)
 {
   pCode *pc=NULL;
@@ -3663,6 +3691,8 @@ void LinkFlow(pBlock *pb)
     
   }
 }
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
index be3cfac247909b88b2d240a8daab36733976cdd5..f25e0c3f714af000bbab9de485a839a22c8d39b8 100644 (file)
@@ -185,6 +185,7 @@ typedef enum
   POC_COMFW,
   POC_CLRF,
   POC_CLRW,
+  POC_CLRWDT,
   POC_DECF,
   POC_DECFW,
   POC_DECFSZ,
diff --git a/src/pic/pcodeflow.c b/src/pic/pcodeflow.c
new file mode 100644 (file)
index 0000000..9fe4d7a
--- /dev/null
@@ -0,0 +1,176 @@
+/*-------------------------------------------------------------------------
+
+   pcodeflow.c - post code generation flow analysis
+
+   Written By -  Scott Dattalo scott@dattalo.com
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   
+-------------------------------------------------------------------------*/
+/*
+  pcodeflow.c
+
+  The purpose of the code in this file is to analyze the flow of the
+  pCode.
+
+*/
+
+#include <stdio.h>
+
+#include "common.h"   // Include everything in the SDCC src directory
+#include "newalloc.h"
+#include "ralloc.h"
+#include "device.h"
+#include "pcode.h"
+#include "pcoderegs.h"
+#include "pcodeflow.h"
+
+#if 0
+
+/* 
+   In the section that follows, an exhaustive flow "tree" is built.
+   It's not a tree that's really built, but instead every possible
+   flow path is constructed. 
+
+   This is really overkill...
+*/
+
+static set *FlowTree=NULL;
+
+void dbg_dumpFlowTree(set *FlowTree)
+{
+  set *segment;
+  pCodeFlow *pcflow;
+
+  fprintf(stderr,"Flow Tree: \n");
+
+  for(segment = setFirstItem(FlowTree); segment; segment=setNextItem(FlowTree)) {
+
+    fprintf(stderr,"Segment:\n");
+
+    for(pcflow=PCFL(setFirstItem(segment)); pcflow; pcflow=PCFL(setNextItem(segment))) {
+      fprintf(stderr, "  0x%03x",pcflow->pc.seq);
+    }
+    fprintf(stderr,"\n");
+  }
+
+}
+
+
+
+
+/*-----------------------------------------------------------------*
+ * void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
+ *-----------------------------------------------------------------*/
+void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
+{
+
+  int nNextFlow=0;
+  pCodeFlowLink *pcflowLink=NULL;
+
+  /* Add this flow to the set if it's not in there already */
+  if(isinSet(segment, pcflow)) {
+    addSetHead(&FlowTree, segment);
+    return;
+  }
+
+  addSetHead(&segment, pcflow);
+
+  /* Continue to add contiguous flows */
+
+  while( pcflow->to && ((nNextFlow = elementsInSet(pcflow->to)) == 1)) {
+    pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
+    pcflow = pcflowLink->pcflow;
+
+    if(isinSet(segment, pcflow)) {
+      addSetIfnotP(&FlowTree, segment);
+      return;
+    }
+
+    addSetIfnotP(&segment, pcflow);
+
+  }
+
+  /* Branch: for each branch, duplicate the set and recursively call */
+  if(pcflow->to && nNextFlow>=2) {
+    pCodeFlow *pcflow_to;
+
+    set *branch_segment=NULL;
+    
+    pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
+    pcflow_to = pcflowLink->pcflow;
+
+    addSetIfnotP(&segment, pcflow);
+
+    pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
+
+    while(pcflowLink) {
+
+      branch_segment = setFromSet(segment);
+      BuildFlowSegment(setFromSet(segment),pcflowLink->pcflow);
+      pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
+    }
+
+    /* add the first branch to this segment */
+    BuildFlowSegment(segment,pcflow_to);
+
+  }
+
+  addSetIfnotP(&FlowTree, segment);
+
+  /* done */
+}
+
+/*-----------------------------------------------------------------*
+ * void BuildFlowTree(pBlock *pb)
+ *-----------------------------------------------------------------*/
+void BuildFlowTree(pBlock *pb)
+{
+  pCodeFlow *pcflow;
+  set *segment;
+
+  FlowTree = newSet();
+
+  /* Start with the first flow object of this pBlock */
+
+  pcflow = PCFL(findNextpCode(pb->pcHead, PC_FLOW));
+
+  segment = newSet();
+  BuildFlowSegment(segment, pcflow);
+
+  pb->FlowTree = FlowTree;
+
+  dbg_dumpFlowTree(FlowTree);
+}
+#endif
+
+void LinkFlow(pBlock *pb)
+{
+  pCode *pc=NULL;
+  pCode *pcflow;
+  pCode *pct;
+
+  //fprintf(stderr,"linkflow \n");
+
+  for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
+       pcflow != NULL;
+       pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
+
+    if(!isPCFL(pcflow))
+      fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
+
+
+  }
+}
index f1c3717306aa9069049c5b66e419ce179929132b..7910f568d6fcf50091149d25effbadd39b0b76f2 100644 (file)
@@ -488,10 +488,10 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
     pct2 = findNextInstruction(pc2->next);
 
     if(PCI(pc2)->op == POC_MOVFW) {
-      
+      /*
        fprintf(stderr, "   MOVWF/MOVFW. instruction after MOVFW is:\n");
        pct2->print(stderr,pct2);
-      
+      */
 
       if(PCI(pct2)->op == POC_MOVWF) {
        /*
@@ -600,7 +600,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
        }
       } else if ( (PCI(pct1)->op == POC_MOVWF) &&
           (PCI(pc2)->op == POC_MOVFW)) {
-       fprintf(stderr,"movwf MOVWF/MOVFW\n");
+       //fprintf(stderr,"movwf MOVWF/MOVFW\n");
        if(optimize_level > 1 && can_free) {
          pct2 = newpCode(POC_MOVFW, PCI(pc1)->pcop);
          pCodeInsertAfter(pc2, pct2);
index 79bdb92be38d297755261d2f70ed443a9d60ade0..44a9b966c6ed8455dd6b9d7bb01269097e376c39 100644 (file)
@@ -258,12 +258,38 @@ replace restart {
        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 {
-       movwf   %1
-       iorlw   0
-       movf    %1,w
+        iorlw   0
 } by {
-       ; peep 10 - Removed unnecessary iorlw
-       movwf   %1
-       movf    %1
+        ; peep 10a - Removed unnecessary iorlw
+} if NZ
+
+// From: Frieder Ferlemann
+
+replace restart {
+        xorlw   0
+} by {
+        ; peep 10b - Removed unnecessary xorlw
+} if NZ
+
+// From: Frieder Ferlemann
+
+replace restart {
+        movf    %1,w
+        movwf   %1
+} by {
+        ; peep 11 - Removed redundant move
+        movf    %1,w
 }