From: sdattalo Date: Sat, 6 Jul 2002 05:57:42 +0000 (+0000) Subject: Fixed seg fault for empty programs. Added more register optimizations. X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=c2cb349ed277ff586c5613f3addf6ff8307d61bd;p=fw%2Fsdcc Fixed seg fault for empty programs. Added more register optimizations. Added deleteSet() function to delete a set and its contents. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2031 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/SDCCset.c b/src/SDCCset.c index 19babd6e..3007157c 100644 --- a/src/SDCCset.c +++ b/src/SDCCset.c @@ -576,3 +576,30 @@ setToNull (void **item) Safe_free (*item); *item = NULL; } + +/*-----------------------------------------------------------------*/ +/* deleteSet - will throw away the entire list */ +/* note - setToNull doesn't actually throw away the whole list. */ +/* Instead it only throws away the first item. */ +/*-----------------------------------------------------------------*/ +void deleteSet(set **s) +{ + set *curr; + set *next; + + if(!s || !*s) + return; + + curr = *s; + next = curr->next; + while (next) { + Safe_free (curr); + curr = next; + next = next->next; + } + + Safe_free (curr); + + *s = NULL; +} + diff --git a/src/SDCCset.h b/src/SDCCset.h index 39328e63..ea503e57 100644 --- a/src/SDCCset.h +++ b/src/SDCCset.h @@ -80,5 +80,6 @@ void *setFirstItem (set *); void *setNextItem (set *); void setToNull (void **); set *reverseSet (set *); +void deleteSet(set **s); #endif diff --git a/src/pic/gen.c b/src/pic/gen.c index 6057496d..e7441b1b 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -65,7 +65,7 @@ extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void genMult8X8_8 (operand *, operand *,operand *); static int labelOffset=0; -static int debug_verbose=1; +extern int debug_verbose; static int optimized_for_speed = 0; /* max_key keeps track of the largest label number used in @@ -399,15 +399,17 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) if(!resIfx) return; - DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); resIfx->condition = 1; /* assume that the ifx is true */ resIfx->generated = 0; /* indicate that the ifx has not been used */ if(!ifx) { resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */ +/* DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d", __FUNCTION__,__LINE__,resIfx->lbl->key); +*/ } else { if(IC_TRUE(ifx)) { resIfx->lbl = IC_TRUE(ifx); @@ -415,13 +417,15 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) resIfx->lbl = IC_FALSE(ifx); resIfx->condition = 0; } +/* if(IC_TRUE(ifx)) DEBUGpic14_emitcode("; ***","ifx true is non-null"); if(IC_FALSE(ifx)) DEBUGpic14_emitcode("; ***","ifx false is non-null"); +*/ } - DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); + // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); } /*-----------------------------------------------------------------*/ @@ -2602,17 +2606,17 @@ static void genPcall (iCode *ic) /*-----------------------------------------------------------------*/ static int resultRemat (iCode *ic) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (SKIP_IC(ic) || ic->op == IFX) - return 0; + // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (SKIP_IC(ic) || ic->op == IFX) + return 0; - if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) { - symbol *sym = OP_SYMBOL(IC_RESULT(ic)); - if (sym->remat && !POINTER_SET(ic)) - return 1; - } + if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) { + symbol *sym = OP_SYMBOL(IC_RESULT(ic)); + if (sym->remat && !POINTER_SET(ic)) + return 1; + } - return 0; + return 0; } #if defined(__BORLANDC__) || defined(_MSC_VER) @@ -3746,11 +3750,12 @@ static void genCmp (operand *left,operand *right, // resolvedIfx rTrueIfx; symbol *truelbl; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); +/* if(ifx) { DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true")); DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true")); } - +*/ resolveIfx(&rFalseIfx,ifx); truelbl = newiTempLabel(NULL); @@ -3764,10 +3769,8 @@ static void genCmp (operand *left,operand *right, unsigned long mask = (0x100 << (8*(size-1))) - 1; lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); #ifdef _swapp - DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit); - lit = (lit - 1) & mask; - DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask); + lit = (lit - 1) & mask; right = left; left = tmp; rFalseIfx.condition ^= 1; @@ -7885,7 +7888,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype) return ; } - +#if 0 /*-----------------------------------------------------------------*/ /* genDataPointerGet - generates code when ptr offset is known */ /*-----------------------------------------------------------------*/ @@ -7920,7 +7923,7 @@ static void genDataPointerGet (operand *left, freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } - +#endif /*-----------------------------------------------------------------*/ /* genNearPointerGet - pic14_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ @@ -7929,11 +7932,11 @@ static void genNearPointerGet (operand *left, iCode *ic) { asmop *aop = NULL; - regs *preg = NULL ; + //regs *preg = NULL ; char *rname ; sym_link *rtype, *retype; sym_link *ltype = operandType(left); - char buffer[80]; + //char buffer[80]; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 8713b457..2acf43f5 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -75,11 +75,13 @@ 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 */ static int GpCodeSequenceNumber = 1; int GpcFlowSeq = 1; extern void RemoveUnusedRegisters(void); +extern void RegsUnMapLiveRanges(void); extern void BuildFlowTree(pBlock *pb); extern void pCodeRegOptimizeRegUsage(void); @@ -1762,19 +1764,22 @@ 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) */ + unlinkpCode(pc); + + deleteSet(&PCFL(pc)->registers); + deleteSet(&PCFL(pc)->from); + deleteSet(&PCFL(pc)->to); free(pc); + } pCode *newpCodeFlow(void ) @@ -1786,7 +1791,6 @@ pCode *newpCodeFlow(void ) pcflow->pc.type = PC_FLOW; pcflow->pc.prev = pcflow->pc.next = NULL; - //pcflow->pc.from = pcflow->pc.to = pcflow->pc.label = NULL; pcflow->pc.pb = NULL; // pcflow->pc.analyze = genericAnalyze; @@ -1795,9 +1799,6 @@ pCode *newpCodeFlow(void ) pcflow->pc.seq = GpcFlowSeq++; - pcflow->nuses = 7; - pcflow->uses = Safe_calloc(pcflow->nuses, sizeof(set *)); - pcflow->from = pcflow->to = NULL; pcflow->inCond = PCC_NONE; @@ -2631,9 +2632,11 @@ static void genericPrint(FILE *of, pCode *pc) fprintf(of,"%s",str); /* Debug */ - fprintf(of, "\t;key=%03x",pc->seq); - if(PCI(pc)->pcflow) - fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq); + if(debug_verbose) { + fprintf(of, "\t;key=%03x",pc->seq); + if(PCI(pc)->pcflow) + fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq); + } } #if 0 { @@ -2675,7 +2678,8 @@ static void genericPrint(FILE *of, pCode *pc) break; case PC_FLOW: - fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq); + if(debug_verbose) + fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq); break; case PC_CSOURCE: @@ -3150,7 +3154,9 @@ regs * getRegFromInstruction(pCode *pc) switch(PCI(pc)->pcop->type) { case PO_INDF: case PO_FSR: - return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0); + return PCOR(PCI(pc)->pcop)->r; + + // return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0); case PO_BIT: case PO_GPR_TEMP: @@ -3255,7 +3261,8 @@ void AnalyzepBlock(pBlock *pb) void InsertpFlow(pCode *pc, pCode **pflow) { - PCFL(*pflow)->end = pc; + if(*pflow) + PCFL(*pflow)->end = pc; if(!pc || !pc->next) return; @@ -3276,7 +3283,7 @@ void BuildFlow(pBlock *pb) { pCode *pc; pCode *last_pci=NULL; - pCode *pflow; + pCode *pflow=NULL; int seq = 0; if(!pb) @@ -3285,11 +3292,13 @@ void BuildFlow(pBlock *pb) //fprintf (stderr,"build flow start seq %d ",GpcFlowSeq); /* Insert a pCodeFlow object at the beginning of a pBlock */ - pflow = newpCodeFlow(); /* Create a new Flow object */ - pflow->next = pb->pcHead; /* Make the current head the next object */ - pb->pcHead->prev = pflow; /* let the current head point back to the flow object */ - pb->pcHead = pflow; /* Make the Flow object the head */ - pflow->pb = pb; + InsertpFlow(pb->pcHead, &pflow); + + //pflow = newpCodeFlow(); /* Create a new Flow object */ + //pflow->next = pb->pcHead; /* Make the current head the next object */ + //pb->pcHead->prev = pflow; /* let the current head point back to the flow object */ + //pb->pcHead = pflow; /* Make the Flow object the head */ + //pflow->pb = pb; for( pc = findNextInstruction(pb->pcHead); pc != NULL; @@ -3347,7 +3356,8 @@ void BuildFlow(pBlock *pb) } //fprintf (stderr,",end seq %d",GpcFlowSeq); - PCFL(pflow)->end = pb->pcTail; + if(pflow) + PCFL(pflow)->end = pb->pcTail; } /*-------------------------------------------------------------------*/ @@ -3359,27 +3369,31 @@ void BuildFlow(pBlock *pb) /*-----------------------------------------------------------------*/ void unBuildFlow(pBlock *pb) { - pCode *pc; + pCode *pc,*pcnext; if(!pb) return; pc = pb->pcHead; + while(pc) { - pCode *pcn = pc->next; + pcnext = pc->next; if(isPCI(pc)) { + pc->seq = 0; - PCI(pc)->pcflow = NULL; - pc = pcn; - } else if(isPCFL(pc)) { - unlinkpCode(pc); + if(PCI(pc)->pcflow) { + //free(PCI(pc)->pcflow); + PCI(pc)->pcflow = NULL; + } + + } else if(isPCFL(pc) ) pc->destruct(pc); - } else - pc = pcn; + pc = pcnext; } + } /*-----------------------------------------------------------------*/ @@ -4138,6 +4152,9 @@ int OptimizepBlock(pBlock *pb) */ pc = findNextInstruction(pb->pcHead); + if(!pc) + return 0; + pcprev = pc->prev; do { @@ -4560,12 +4577,13 @@ void mergepBlocks(char dbName) } /*-----------------------------------------------------------------*/ -/* AnalyzeBanking - Called after the memory addresses have been */ -/* assigned to the registers. */ +/* AnalyzeFlow - Examine the flow of the code and optimize */ /* */ /*-----------------------------------------------------------------*/ -void AnalyzeBanking(void) + +void AnalyzeFlow(void) { + static int times_called=0; pBlock *pb; @@ -4573,6 +4591,18 @@ void AnalyzeBanking(void) return; + /* if this is not the first time this function has been called, + then clean up old flow information */ + if(times_called++) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) + unBuildFlow(pb); + + RegsUnMapLiveRanges(); + + } + + GpcFlowSeq = 1; + /* Phase 2 - Flow Analysis - Register Banking * * In this phase, the individual flow blocks are examined @@ -4613,15 +4643,6 @@ void AnalyzeBanking(void) BuildFlowTree(pb); */ - /* Phase x - Flow Analysis - Used Banks - * - * In this phase, the individual flow blocks are examined - * to determine the Register Banks they use - */ - - for(pb = the_pFile->pbHead; pb; pb = pb->next) - BanksUsedFlow(pb); - /* Phase x - Flow Analysis - Used Banks * * In this phase, the individual flow blocks are examined @@ -4642,6 +4663,7 @@ void AnalyzeBanking(void) OptimizepCode('*'); + /* for(pb = the_pFile->pbHead; pb; pb = pb->next) DumpFlow(pb); @@ -4656,6 +4678,7 @@ void AnalyzeBanking(void) FillFlow(PCFL(pcflow)); } } + /* for(pb = the_pFile->pbHead; pb; pb = pb->next) { pCode *pcflow; @@ -4669,6 +4692,29 @@ void AnalyzeBanking(void) */ } +/*-----------------------------------------------------------------*/ +/* AnalyzeBanking - Called after the memory addresses have been */ +/* assigned to the registers. */ +/* */ +/*-----------------------------------------------------------------*/ + +void AnalyzeBanking(void) +{ + pBlock *pb; + + /* Phase x - Flow Analysis - Used Banks + * + * In this phase, the individual flow blocks are examined + * to determine the Register Banks they use + */ + + AnalyzeFlow(); + AnalyzeFlow(); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + BanksUsedFlow(pb); +} + /*-----------------------------------------------------------------*/ /* buildCallTree - look at the flow and extract all of the calls */ /* */ diff --git a/src/pic/pcode.h b/src/pic/pcode.h index c6d1ec2b..be3cfac2 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -441,11 +441,11 @@ typedef struct pCodeFlow pCode *end; /* Last pCode in this flow. Note that the first pCode is pc.next */ - set **uses; /* map the pCode instruction inCond and outCond conditions + /* set **uses; * map the pCode instruction inCond and outCond conditions * in this array of set's. The reason we allocate an * array of pointers instead of declaring each type of * usage is because there are port dependent usage definitions */ - int nuses; /* number of uses sets */ + //int nuses; /* number of uses sets */ set *from; /* flow blocks that can send control to this flow block */ set *to; /* flow blocks to which this one can send control */ diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 3aeb99d9..9df610d2 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -2002,7 +2002,7 @@ int pCodePeepMatchRule(pCode *pc) pcin->prev = pc->prev; - //#if 0 +#if 0 { /* DEBUG */ /* Converted the deleted pCodes into comments */ @@ -2034,7 +2034,7 @@ int pCodePeepMatchRule(pCode *pc) if(pc_cline2) pc_cline2->pc.next = NULL; } - //#endif +#endif if(pcin) pCodeDeleteChain(pc,pcin); diff --git a/src/pic/pcoderegs.c b/src/pic/pcoderegs.c index f536987f..82c585cb 100644 --- a/src/pic/pcoderegs.c +++ b/src/pic/pcoderegs.c @@ -206,20 +206,22 @@ void pCodeRegMapLiveRanges(pBlock *pb) pCodeRegMapLiveRangesInFlow(PCFL(pcflow)); } - +#if 0 for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); pcflow != NULL; pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { regs *r = setFirstItem(PCFL(pcflow)->registers); - //fprintf(stderr,"flow seq %d\n", pcflow->seq); + fprintf(stderr,"flow seq %d\n", pcflow->seq); + while (r) { - //fprintf(stderr, " %s\n",r->name); + fprintf(stderr, " %s\n",r->name); r = setNextItem(PCFL(pcflow)->registers); } } +#endif // dbg_dumpregusage(); @@ -279,10 +281,6 @@ void RemoveRegsFromSet(set *regset) reg = regset->item; regset = regset->next; -/* - for (reg = setFirstItem(regset) ; reg ; - reg = setNextItem(regset)) { -*/ used = elementsInSet(reg->reglives.usedpCodes); if(used <= 1) { @@ -365,7 +363,7 @@ void RemoveUnusedRegisters(void) /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg) +static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int can_free) { if(!reg) return; @@ -377,8 +375,10 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg) Remove1pcode(pc2, reg); deleteSetItem (&(PCFL(pcflow)->registers), reg); - reg->isFree = 1; - reg->wasUsed = 0; + if(can_free) { + reg->isFree = 1; + reg->wasUsed = 0; + } } @@ -409,6 +409,127 @@ int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg) return 0; } +/*-----------------------------------------------------------------* + * void pCodeOptime2pCodes(pCode *pc1, pCode *pc2) + * + * ADHOC pattern checking + * Now look for specific sequences that are easy to optimize. + * Many of these sequences are characteristic of the compiler + * (i.e. it'd probably be a waste of time to apply these adhoc + * checks to hand written assembly.) + * + * + *-----------------------------------------------------------------*/ +void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free) +{ + pCode *pct1, *pct2; + regs *reg1, *reg2; + + if(pc2->seq < pc1->seq) { + pct1 = pc2; + pc2 = pc1; + pc1 = pct1; + } + + + if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){ + + /* + clrf reg + stuff... + movf reg,w + + can be replaced with + + stuff... + movlw 0 + */ + + pCode *newpc; + //fprintf(stderr, " CLRF/MOVFW. instruction after MOVFW is:\n"); + pct1 = findNextInstruction(pc2->next); + //t->print(stderr,t); + + if(PCI(pct1)->op == POC_MOVWF) { + newpc = newpCode(POC_CLRF, PCI(pct1)->pcop); + pct1->destruct(pct1); + } else { + newpc = newpCode(POC_MOVLW, newpCodeOpLit(0)); + } + + pCodeInsertAfter(pc2, newpc); + PCI(newpc)->pcflow = PCFL(pcfl_used); + newpc->seq = pc2->seq; + + Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + total_registers_saved++; // debugging stats. + + } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){ + //fprintf(stderr, " CLRF/IORFW.\n"); + + Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + total_registers_saved++; // debugging stats. + + } else if(PCI(pc1)->op == POC_MOVWF) { + + 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) { + reg2 = getRegFromInstruction(pct2); + if(reg2 && !regUsedinRange(pc1,pc2,reg2)) { + pct2->seq = pc1->seq; + unlinkpCode(pct2); + pCodeInsertAfter(pc1,pct2); + Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + total_registers_saved++; // debugging stats. + return; + } +/* + fprintf(stderr, " couldn't optimize\n"); + if(reg2) + fprintf(stderr, " %s is used in range\n",reg2->name); + else + fprintf(stderr, " reg2 is NULL\n"); +*/ + } + } + + pct1 = findPrevInstruction(pc1->prev); + if(pct1 && + (PCI(pct1)->pcflow == PCI(pc1)->pcflow) && + (PCI(pct1)->op == POC_MOVFW)) { + + reg1 = getRegFromInstruction(pct1); + if(reg1 && !regUsedinRange(pc1,pc2,reg1)) { + //fprintf(stderr, " MOVF/MOVFW. \n"); + /* + movf reg1,w + movwf reg + + stuff... + opcode reg,w + */ + pct2 = newpCode(PCI(pc2)->op, PCI(pct1)->pcop); + pCodeInsertAfter(pc2, pct2); + PCI(pct2)->pcflow = PCFL(pcfl_used); + pct2->seq = pc2->seq; + + Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + Remove2pcodes(pcfl_used, pct1, NULL, reg1, 0); + total_registers_saved++; // debugging stats. + + } + } + + + } + +} + /*-----------------------------------------------------------------* * void pCodeRegOptimeRegUsage(pBlock *pb) *-----------------------------------------------------------------*/ @@ -419,7 +540,7 @@ void OptimizeRegUsage(set *fregs) while(fregs) { - pCode *pcfl_used, *pcfl_assigned; + pCode *pcfl_used, *pcfl_assigned; /* Step through the set by directly accessing the 'next' pointer. * We could also step through by using the set API, but the @@ -446,9 +567,6 @@ void OptimizeRegUsage(set *fregs) */ pCode *pc1, *pc2; - pCode *pct1, *pct2; /* two temporaries */ - regs *reg1, *reg2; - /* fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n", reg->name, @@ -469,117 +587,12 @@ void OptimizeRegUsage(set *fregs) if(pcfl_used->seq == pcfl_assigned->seq) { //fprintf(stderr, " and used in same flow\n"); - if(pc2->seq < pc1->seq) { - pct1 = pc2; - pc2 = pc1; - pc1 = pct1; - } - - //pc1->print(stderr,pc1); - //pc2->print(stderr,pc2); - - - /* ADHOC pattern checking - * Now look for specific sequences that are easy to optimize. - * Many of these sequences are characteristic of the compiler - * (i.e. it'd probably be a waste of time to apply these adhoc - * checks to hand written assembly.) - * - */ - if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){ - - /* - clrf reg - stuff... - movf reg,w - - can be replaced with - - stuff... - movlw 0 - */ - - pCode *newpc; - //fprintf(stderr, " CLRF/MOVFW. instruction after MOVFW is:\n"); - pct1 = findNextInstruction(pc2->next); - //t->print(stderr,t); - - if(PCI(pct1)->op == POC_MOVWF) { - newpc = newpCode(POC_CLRF, PCI(pct1)->pcop); - pct1->destruct(pct1); - } else { - newpc = newpCode(POC_MOVLW, newpCodeOpLit(0)); - } - - pCodeInsertAfter(pc2, newpc); - PCI(newpc)->pcflow = PCFL(pcfl_used); - newpc->seq = pc2->seq; - - Remove2pcodes(pcfl_used, pc1, pc2, reg); - total_registers_saved++; // debugging stats. - - } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){ - //fprintf(stderr, " CLRF/IORWF.\n"); - - Remove2pcodes(pcfl_used, pc1, pc2, reg); - total_registers_saved++; // debugging stats. - - } else if(PCI(pc1)->op == POC_MOVWF) { - - pct2 = findNextInstruction(pc2->next); - - if(PCI(pc2)->op == POC_MOVFW) { - //fprintf(stderr, " MOVWF/MOVFW. instruction after MOVFW is:\n"); - // t->print(stderr,t); - - if(PCI(pct2)->op == POC_MOVWF) { - reg2 = getRegFromInstruction(pct2); - if(reg2 && !regUsedinRange(pc1,pc2,reg2)) { - pct2->seq = pc1->seq; - unlinkpCode(pct2); - pCodeInsertAfter(pc1,pct2); - Remove2pcodes(pcfl_used, pc1, pc2, reg); - total_registers_saved++; // debugging stats. - continue; - } - } - } - - pct1 = findPrevInstruction(pc1->prev); - if(pct1 && - (PCI(pct1)->pcflow == PCI(pc1)->pcflow) && - (PCI(pct1)->op == POC_MOVFW)) { - - reg1 = getRegFromInstruction(pct1); - if(reg1 && !regUsedinRange(pc1,pc2,reg1)) { - //fprintf(stderr, " MOVF/MOVFW. \n"); - /* - movf reg1,w - movwf reg - - stuff... - opcode reg,w - */ - pct2 = newpCode(PCI(pc2)->op, PCI(pct1)->pcop); - pCodeInsertAfter(pc2, pct2); - PCI(pct2)->pcflow = PCFL(pcfl_used); - pct2->seq = pc2->seq; - - Remove2pcodes(pcfl_used, pc1, pc2, reg); - Remove2pcodes(pcfl_used, pct1, NULL, reg1); - total_registers_saved++; // debugging stats. - - } - } - - } + pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 1); } else { // fprintf(stderr, " and used in different flows\n"); - //pc1->print(stderr,pc1); - //pc2->print(stderr,pc2); } } else if(pcfl_used) { @@ -590,11 +603,13 @@ void OptimizeRegUsage(set *fregs) } else { //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); - Remove2pcodes(pcfl_assigned, pc1, pc2, reg); + Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1); total_registers_saved++; // debugging stats. } } else { + /* register has been used either once, or more than twice */ + if(used && !pcfl_used && pcfl_assigned) { pCode *pc; @@ -619,8 +634,11 @@ void OptimizeRegUsage(set *fregs) reg->wasUsed = 0; total_registers_saved++; // debugging stats. - } + } else if(used > 2) { + + /* examine the number of times this register is used */ + } } } @@ -634,6 +652,7 @@ void pCodeRegOptimizeRegUsage(void) int passes = 4; int saved = 0; + int t = total_registers_saved; do { saved = total_registers_saved; @@ -648,6 +667,11 @@ void pCodeRegOptimizeRegUsage(void) } while( passes-- && (total_registers_saved != saved)); + + if(total_registers_saved == t) + fprintf(stderr, "No registers saved on this pass\n"); + + /* fprintf(stderr,"dynamically allocated regs:\n"); dbg_regusage(dynAllocRegs); @@ -656,6 +680,38 @@ void pCodeRegOptimizeRegUsage(void) fprintf(stderr,"direct regs:\n"); dbg_regusage(dynDirectRegs); */ +} + + +/*-----------------------------------------------------------------* + * void RegsUnMapLiveRanges(set *regset) + * + *-----------------------------------------------------------------*/ +void RegsSetUnMapLiveRanges(set *regset) +{ + regs *reg; + + while(regset) { + reg = regset->item; + regset = regset->next; + + + deleteSet(®->reglives.usedpCodes); + deleteSet(®->reglives.usedpFlows); + deleteSet(®->reglives.assignedpFlows); + + } + +} + +void RegsUnMapLiveRanges(void) +{ + RegsSetUnMapLiveRanges(dynAllocRegs); + RegsSetUnMapLiveRanges(dynStackRegs); + RegsSetUnMapLiveRanges(dynDirectRegs); + RegsSetUnMapLiveRanges(dynProcessorRegs); + RegsSetUnMapLiveRanges(dynDirectBitRegs); + RegsSetUnMapLiveRanges(dynInternalRegs); } diff --git a/src/pic/peeph.def b/src/pic/peeph.def index 1ffe50d8..e7a5a865 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -237,3 +237,13 @@ replace restart { movwf %1 iorwf %2,w } + +replace restart { + movf %1,w + movwf %2 + movf %2,w +} by { + ; peep 9c - Removed redundant move + movf %1,w + movwf %2 +}