From: sdattalo Date: Sun, 14 Jul 2002 21:19:17 +0000 (+0000) Subject: "ancestor" flow logic was implemented. Applied optimization patches from Frieder... X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=1b3660ef412775438c553105a92fcdaa1db4cafc;p=fw%2Fsdcc "ancestor" flow logic was implemented. Applied optimization patches from Frieder Ferlemann for unsigned multiplications. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2039 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/pic/genarith.c b/src/pic/genarith.c index d6e5d796..797c7dfc 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -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 { diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 31f5fda3..bbaede84 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 = 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 * diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 7d5e57f5..1f1394d2 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -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)) diff --git a/src/pic/pcodeflow.c b/src/pic/pcodeflow.c index e3e47e0d..7bc04386 100644 --- a/src/pic/pcodeflow.c +++ b/src/pic/pcodeflow.c @@ -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); + } diff --git a/src/pic/peeph.def b/src/pic/peeph.def index 44a9b966..0dccf7b0 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -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 }