From 75a011f23dc5d4b52d289b6c79a451b602110d7c Mon Sep 17 00:00:00 2001 From: sdattalo Date: Wed, 10 Jul 2002 13:32:21 +0000 Subject: [PATCH] Added pcodeflow.c - much of pcode.c will eventually get moved here. 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 | 36 ++++++++- src/pic/pcode.h | 1 + src/pic/pcodeflow.c | 176 ++++++++++++++++++++++++++++++++++++++++++++ src/pic/pcoderegs.c | 6 +- src/pic/peeph.def | 38 ++++++++-- 5 files changed, 245 insertions(+), 12 deletions(-) create mode 100644 src/pic/pcodeflow.c diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 49568d18..41c8f80d 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -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) } } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ diff --git a/src/pic/pcode.h b/src/pic/pcode.h index be3cfac2..f25e0c3f 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -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 index 00000000..9fe4d7ad --- /dev/null +++ b/src/pic/pcodeflow.c @@ -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 + +#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 "); + + + } +} diff --git a/src/pic/pcoderegs.c b/src/pic/pcoderegs.c index f1c37173..7910f568 100644 --- a/src/pic/pcoderegs.c +++ b/src/pic/pcoderegs.c @@ -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); diff --git a/src/pic/peeph.def b/src/pic/peeph.def index 79bdb92b..44a9b966 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -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 } -- 2.39.5