From 42ac194ab811f6198733c7fd82b07de8da31831f Mon Sep 17 00:00:00 2001 From: sdattalo Date: Thu, 4 Jul 2002 19:45:40 +0000 Subject: [PATCH] More enhancements to register optimization algorithms. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2028 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/gen.c | 3 +- src/pic/pcode.c | 55 +++++--- src/pic/pcode.h | 9 +- src/pic/pcodeflow.h | 1 + src/pic/pcodepeep.c | 48 +++++-- src/pic/pcoderegs.c | 268 ++++++++++++++++++++++++-------------- src/pic/peeph.def | 28 ++++ src/pic/ralloc.h | 20 ++- src/regression/b.c | 6 +- src/regression/create_stc | 2 +- src/regression/simulate | 4 +- 11 files changed, 292 insertions(+), 152 deletions(-) diff --git a/src/pic/gen.c b/src/pic/gen.c index b734cf6a..6057496d 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -1383,7 +1383,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset)); case AOP_STR: - DEBUGpic14_emitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]); return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); /* pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); @@ -3030,7 +3030,6 @@ static void genRet (iCode *ic) } if(size) { emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr)); - pic14_emitcode("movwf","%s",fReturn[offset]); } offset++; } diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 36d2aa7c..6aad5703 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -176,7 +176,7 @@ pCodeInstruction pciADDLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -197,7 +197,7 @@ pCodeInstruction pciANDLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z) // outCond }; @@ -260,7 +260,7 @@ pCodeInstruction pciBCF = { 1,1, // dest, bit instruction 0,0, // branch, skip POC_BSF, - PCC_REGISTER, // inCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond PCC_REGISTER // outCond }; @@ -281,8 +281,8 @@ pCodeInstruction pciBSF = { 1,1, // dest, bit instruction 0,0, // branch, skip POC_BCF, - PCC_REGISTER, // inCond - PCC_REGISTER // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond }; pCodeInstruction pciBTFSC = { @@ -302,8 +302,8 @@ pCodeInstruction pciBTFSC = { 0,1, // dest, bit instruction 1,1, // branch, skip POC_BTFSS, - PCC_REGISTER, // inCond - PCC_NONE // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + PCC_EXAMINE_PCOP // outCond }; pCodeInstruction pciBTFSS = { @@ -323,8 +323,8 @@ pCodeInstruction pciBTFSS = { 0,1, // dest, bit instruction 1,1, // branch, skip POC_BTFSC, - PCC_REGISTER, // inCond - PCC_NONE // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + PCC_EXAMINE_PCOP // outCond }; pCodeInstruction pciCALL = { @@ -680,7 +680,7 @@ pCodeInstruction pciIORLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z) // outCond }; @@ -764,7 +764,7 @@ pCodeInstruction pciMOVLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_NONE, // inCond + (PCC_NONE | PCC_LITERAL), // inCond PCC_W // outCond }; @@ -826,7 +826,7 @@ pCodeInstruction pciRETLW = { 0,0, // dest, bit instruction 1,0, // branch, skip POC_NOP, - PCC_NONE, // inCond + PCC_LITERAL, // inCond PCC_W // outCond }; @@ -994,7 +994,7 @@ pCodeInstruction pciSUBLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -1120,7 +1120,7 @@ pCodeInstruction pciXORLW = { 0,0, // dest, bit instruction 0,0, // branch, skip POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -1593,11 +1593,11 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop) memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction)); pci->pcop = pcop; - if(pci->inCond == PCC_EXAMINE_PCOP) - pci->inCond = RegCond(pcop); + if(pci->inCond & PCC_EXAMINE_PCOP) + pci->inCond |= RegCond(pcop); - if(pci->outCond == PCC_EXAMINE_PCOP) - pci->outCond = RegCond(pcop); + if(pci->outCond & PCC_EXAMINE_PCOP) + pci->outCond |= RegCond(pcop); pci->pc.prev = pci->pc.next = NULL; return (pCode *)pci; @@ -2013,13 +2013,21 @@ pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space) pcop = Safe_calloc(1,sizeof(pCodeOpImmd) ); pcop->type = PO_IMMEDIATE; if(name) { + regs *r = dirregWithName(name); pcop->name = Safe_strdup(name); + PCOI(pcop)->r = r; + if(r) { + //fprintf(stderr, " newpCodeOpImmd reg %s exists\n",name); + PCOI(pcop)->rIdx = r->rIdx; + } else { + //fprintf(stderr, " newpCodeOpImmd reg %s doesn't exist\n",name); + PCOI(pcop)->rIdx = -1; + } //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset); } else { pcop->name = NULL; } - PCOI(pcop)->index = index; PCOI(pcop)->offset = offset; PCOI(pcop)->_const = code_space; @@ -3124,6 +3132,7 @@ static void AnalyzeRETURN(pCode *pc) /*-----------------------------------------------------------------*/ regs * getRegFromInstruction(pCode *pc) { + if(!pc || !isPCI(pc) || !PCI(pc)->pcop || @@ -3141,8 +3150,12 @@ regs * getRegFromInstruction(pCode *pc) return PCOR(PCI(pc)->pcop)->r; case PO_IMMEDIATE: + if(PCOI(PCI(pc)->pcop)->r) + return (PCOI(PCI(pc)->pcop)->r); + //fprintf(stderr, "getRegFromInstruction - immediate\n"); - return NULL; // PCOR(PCI(pc)->pcop)->r; + return dirregWithName(PCI(pc)->pcop->name); + //return NULL; // PCOR(PCI(pc)->pcop)->r; case PO_GPR_BIT: return PCOR(PCI(pc)->pcop)->r; @@ -4619,6 +4632,8 @@ void AnalyzeBanking(void) // for(pb = the_pFile->pbHead; pb; pb = pb->next) pCodeRegOptimizeRegUsage(); + OptimizepCode('*'); + /* for(pb = the_pFile->pbHead; pb; pb = pb->next) DumpFlow(pb); diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 7d896723..c6d1ec2b 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -310,9 +310,12 @@ typedef struct pCodeOpLit typedef struct pCodeOpImmd { pCodeOp pcop; - int offset; /* low,med, or high byte of immediat value */ - int index; /* add this to the immediate value */ - unsigned _const:1; /* is in code space */ + int offset; /* low,med, or high byte of immediat value */ + int index; /* add this to the immediate value */ + unsigned _const:1; /* is in code space */ + + int rIdx; /* If this immd points to a register */ + struct regs *r; /* then this is the reg. */ } pCodeOpImmd; diff --git a/src/pic/pcodeflow.h b/src/pic/pcodeflow.h index 6db2382c..c8b53199 100644 --- a/src/pic/pcodeflow.h +++ b/src/pic/pcodeflow.h @@ -56,6 +56,7 @@ #define PCC_REG_BANK1 (1<<7) #define PCC_REG_BANK2 (1<<8) #define PCC_REG_BANK3 (1<<9) +#define PCC_LITERAL (1<<10) /*------------------------------------------------------------*/ diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 96b334cb..3aeb99d9 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -660,13 +660,14 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) static void tokenizeLineNode(char *ln) { - + char *lnstart=ln; tokIdx = 0; // Starting off at the beginning tokArr[0].tt = PCT_NULL; // and assume invalid character for first token. if(!ln || !*ln) return; + while(*ln) { if(isspace(*ln)) { @@ -723,6 +724,11 @@ static void tokenizeLineNode(char *ln) tokArr[tokIdx].tok.s = Safe_strdup(buffer); tokArr[tokIdx++].tt = PCT_STRING; + } else { + fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n"); + fprintf(stderr, "Line: %s\n",lnstart); + fprintf(stderr, "Token: '%c'\n",*ln); + exit(1); } } @@ -1028,6 +1034,8 @@ void parseTokens(pCodeWildBlock *pcwb) state = PS_HAVE_COMMA; } else fprintf(stderr," unexpected comma\n"); + break; + } matching = 1; @@ -1227,7 +1235,7 @@ void peepRules2pCode(peepRule *rules) peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target); //DFPRINTF((stderr,"finished target, here it is in pcode form:\n")); - //printpBlock(stderr, curBlock); + //printpBlock(stderr, currentRule->target.pb); //DFPRINTF((stderr,"target with labels merged:\n")); //pBlockMergeLabels(curBlock); @@ -1356,7 +1364,7 @@ static void * DLL_append(_DLL *list, _DLL *next) /*-----------------------------------------------------------------*/ int pCodeSearchCondition(pCode *pc, unsigned int cond) { - + //fprintf(stderr,"Checking conditions %d\n",cond); while(pc) { /* If we reach a function end (presumably an end since we most @@ -1368,6 +1376,7 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond) if(pc->type == PC_OPCODE) { //fprintf(stderr," checking conditions of: "); //pc->print(stderr,pc); + //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond); if(PCI(pc)->inCond & cond) return 1; if(PCI(pc)->outCond & cond) @@ -1404,6 +1413,14 @@ int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) return 0; // different types } + if(pcops->type == PO_LITERAL) { + + if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit)) + return 1; + + return 0; + } + b[0]=0; get_op(pcops,b,50); @@ -1547,7 +1564,6 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(PCI(pcd)->pcop) { if (PCI(pcd)->pcop->type == PO_WILD) { index = PCOW(PCI(pcd)->pcop)->id; - //DFPRINTF((stderr,"destination is wild\n")); #ifdef DEBUG_PCODEPEEP if (index > peepBlock->nops) { @@ -1598,6 +1614,9 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) } } + } else if (PCI(pcd)->pcop->type == PO_LITERAL) { + return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop); + } /* FIXME - need an else to check the case when the destination * isn't a wild card */ @@ -1611,7 +1630,6 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) { - index = PCW(pcd)->id; #ifdef PCODE_DEBUG DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__)); @@ -1687,12 +1705,12 @@ void pCodePeepClrVars(pCodePeep *pcp) int i; if(!pcp) return; - +/* DFPRINTF((stderr," Clearing peep rule vars\n")); DFPRINTF((stderr," %d %d %d %d %d %d\n", pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes, pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes)); - +*/ for(i=0;itarget.nvars; i++) pcp->target.vars[i] = NULL; for(i=0;itarget.nops; i++) @@ -1934,11 +1952,8 @@ int pCodePeepMatchRule(pCode *pc) } } - if(matched) { + if(matched && pcin) { - //pCode *pcr = peepBlock->replace.pb->pcHead; - //if(pcr) pcr->print(stderr,pcr); - /* So far we matched the rule up to the point of the conditions . * In other words, all of the opcodes match. Now we need to see * if the post conditions are satisfied. @@ -1948,11 +1963,16 @@ int pCodePeepMatchRule(pCode *pc) * the `postFalseCond' as input then we abort the match */ DFPRINTF((stderr," matched rule so far, now checking conditions\n")); + //pcin->print(stderr,pcin); + if (pcin && peepBlock->postFalseCond && (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) ) matched = 0; - if(!matched) fprintf(stderr,"failed on conditions\n"); + //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond)); + + + //if(!matched) fprintf(stderr,"failed on conditions\n"); } if(matched) { @@ -1982,7 +2002,7 @@ int pCodePeepMatchRule(pCode *pc) pcin->prev = pc->prev; -#if 0 + //#if 0 { /* DEBUG */ /* Converted the deleted pCodes into comments */ @@ -2014,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 5a5ebbff..5b0b9d92 100644 --- a/src/pic/pcoderegs.c +++ b/src/pic/pcoderegs.c @@ -38,6 +38,7 @@ extern void pCodeInsertAfter(pCode *pc1, pCode *pc2); extern void dbg_dumpregusage(void); +extern pCode * findPrevInstruction(pCode *pci); void unlinkpCode(pCode *pc); int total_registers_saved=0; @@ -71,45 +72,47 @@ void dbg_regusage(set *fregs) for (reg = setFirstItem(fregs) ; reg ; reg = setNextItem(fregs)) { - - fprintf (stderr, "%s addr=0x%03x rIdx=0x%03x", - reg->name, - reg->address, - reg->rIdx); - - pcfl = setFirstItem(reg->reglives.usedpFlows); - if(pcfl) - fprintf(stderr, "\n used in seq"); - - while(pcfl) { - fprintf(stderr," 0x%03x",pcfl->seq); - pcfl = setNextItem(reg->reglives.usedpFlows); - } - pcfl = setFirstItem(reg->reglives.assignedpFlows); - if(pcfl) - fprintf(stderr, "\n assigned in seq"); + if(elementsInSet(reg->reglives.usedpCodes)) { + + fprintf (stderr, "%s addr=0x%03x rIdx=0x%03x", + reg->name, + reg->address, + reg->rIdx); - while(pcfl) { - fprintf(stderr," 0x%03x",pcfl->seq); - pcfl = setNextItem(reg->reglives.assignedpFlows); - } + pcfl = setFirstItem(reg->reglives.usedpFlows); + if(pcfl) + fprintf(stderr, "\n used in seq"); - pc = setFirstItem(reg->reglives.usedpCodes); - if(pc) - fprintf(stderr, "\n used in instructions "); + while(pcfl) { + fprintf(stderr," 0x%03x",pcfl->seq); + pcfl = setNextItem(reg->reglives.usedpFlows); + } - while(pc) { - pcfl = PCODE(PCI(pc)->pcflow); + pcfl = setFirstItem(reg->reglives.assignedpFlows); if(pcfl) - fprintf(stderr," 0x%03x:",pcfl->seq); - fprintf(stderr,"0x%03x",pc->seq); + fprintf(stderr, "\n assigned in seq"); - pc = setNextItem(reg->reglives.usedpCodes); - } + while(pcfl) { + fprintf(stderr," 0x%03x",pcfl->seq); + pcfl = setNextItem(reg->reglives.assignedpFlows); + } + + pc = setFirstItem(reg->reglives.usedpCodes); + if(pc) + fprintf(stderr, "\n used in instructions "); - fprintf(stderr, "\n"); + while(pc) { + pcfl = PCODE(PCI(pc)->pcflow); + if(pcfl) + fprintf(stderr," 0x%03x:",pcfl->seq); + fprintf(stderr,"0x%03x",pc->seq); + + pc = setNextItem(reg->reglives.usedpCodes); + } + fprintf(stderr, "\n"); + } } } @@ -167,7 +170,7 @@ void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) addSetIfnotP(& (PCFL(pcfl)->registers), reg); - if(PCC_REGISTER & PCI(pc)->inCond) + if((PCC_REGISTER | PCC_LITERAL) & PCI(pc)->inCond) addSetIfnotP(& (reg->reglives.usedpFlows), pcfl); if(PCC_REGISTER & PCI(pc)->outCond) @@ -217,7 +220,7 @@ void pCodeRegMapLiveRanges(pBlock *pb) } - //dbg_dumpregusage(); +// dbg_dumpregusage(); } @@ -306,16 +309,25 @@ void RemoveUnusedRegisters(void) *-----------------------------------------------------------------*/ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg) { + if(!reg) + return; + + if(pc1) { + deleteSetItem (&(reg->reglives.usedpCodes),pc1); + pc1->destruct(pc1); + } - deleteSetItem (&(reg->reglives.usedpCodes),pc1); - deleteSetItem (&(reg->reglives.usedpCodes),pc2); - deleteSetItem (&(PCFL(pcflow)->registers), reg); + if(pc2) { + deleteSetItem (&(reg->reglives.usedpCodes),pc2); + pc2->destruct(pc2); - pc1->destruct(pc1); - pc2->destruct(pc2); + deleteSetItem (&(PCFL(pcflow)->registers), reg); + + reg->isFree = 1; + reg->wasUsed = 0; + + } - reg->isFree = 1; - reg->wasUsed = 0; pCodeRegMapLiveRangesInFlow(PCFL(pcflow)); } @@ -353,6 +365,7 @@ void OptimizeRegUsage(set *fregs) while(fregs) { + 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 @@ -362,25 +375,28 @@ void OptimizeRegUsage(set *fregs) reg = fregs->item; fregs = fregs->next; - used = elementsInSet(reg->reglives.usedpCodes); + pcfl_used = setFirstItem(reg->reglives.usedpFlows); + pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows); + + used = elementsInSet(reg->reglives.usedpCodes); if(used == 2) { - pCode *pcfl_used, *pcfl_assigned; + /* + * In this section, all registers that are used in only in two + * instructions are examined. If possible, they're optimized out. + */ + pCode *pc1, *pc2; - pCode *t; + pCode *pct1, *pct2; /* two temporaries */ + regs *reg1, *reg2; - /* This register has only been used twice. Chances are we can - get rid of it */ /* fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x used=%d\n", reg->name, reg->address, reg->rIdx, used); */ - pcfl_used = setFirstItem(reg->reglives.usedpFlows); - pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows); - pc1 = setFirstItem(reg->reglives.usedpCodes); pc2 = setNextItem(reg->reglives.usedpCodes); @@ -390,39 +406,57 @@ void OptimizeRegUsage(set *fregs) expected case - the register has been assigned a value and is subsequently used */ + //fprintf(stderr," used only twice\n"); if(pcfl_used->seq == pcfl_assigned->seq) { //fprintf(stderr, " and used in same flow\n"); if(pc2->seq < pc1->seq) { - t = pc2; + pct1 = pc2; pc2 = pc1; - pc1 = t; + pc1 = pct1; } //pc1->print(stderr,pc1); //pc2->print(stderr,pc2); - /* ADHOC pattern checking */ + /* 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"); - t = findNextInstruction(pc2->next); + pct1 = findNextInstruction(pc2->next); //t->print(stderr,t); - if(PCI(t)->op == POC_MOVWF) { - newpc = newpCode(POC_CLRF, PCI(t)->pcop); + 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 = t->seq; - - pCodeInsertAfter(t, newpc); + newpc->seq = pc2->seq; - t->destruct(t); Remove2pcodes(pcfl_used, pc1, pc2, reg); total_registers_saved++; // debugging stats. @@ -432,21 +466,54 @@ void OptimizeRegUsage(set *fregs) Remove2pcodes(pcfl_used, pc1, pc2, reg); total_registers_saved++; // debugging stats. - } else if((PCI(pc1)->op == POC_MOVWF) && (PCI(pc2)->op == POC_MOVFW) ){ - //fprintf(stderr, " MOVWF/MOVFW. instruction after MOVFW is:\n"); - t = findNextInstruction(pc2->next); - // t->print(stderr,t); - - if(PCI(t)->op == POC_MOVWF) { - regs *nextreg = getRegFromInstruction(t); - if(nextreg && !regUsedinRange(pc1,pc2,nextreg)) { - t->seq = pc1->seq; - unlinkpCode(t); - pCodeInsertAfter(pc1,t); + } 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)) { + /* + 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. + } } + + } } else { @@ -461,52 +528,40 @@ void OptimizeRegUsage(set *fregs) /* register has been used twice without ever being assigned */ fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name); + } else { - fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); + //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); + Remove2pcodes(pcfl_assigned, pc1, pc2, reg); + total_registers_saved++; // debugging stats. } } else { - //if(used) fprintf (stderr, " over used OptimizeRegUsage: %s used=%d\n", reg->name, used); - - } - } + if(used && !pcfl_used && pcfl_assigned) { + pCode *pc; -#if 0 - pcfl = setFirstItem(reg->reglives.usedpFlows); - if(pcfl) - fprintf(stderr, "\n used in seq"); + //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name); - while(pcfl) { - fprintf(stderr," 0x%03x",pcfl->seq); - pcfl = setNextItem(reg->reglives.usedpFlows); - } + pc = setFirstItem(reg->reglives.usedpCodes); + while(pc) { + pcfl_assigned = PCI(pc)->pcflow; + deleteSetItem (&(PCFL(pcfl_assigned)->registers), reg); + deleteSetItem (&(reg->reglives.usedpCodes),pc); + pc->destruct(pc); - pcfl = setFirstItem(reg->reglives.assignedpFlows); - if(pcfl) - fprintf(stderr, "\n assigned in seq"); + pc = setNextItem(reg->reglives.usedpCodes); + } - while(pcfl) { - fprintf(stderr," 0x%03x",pcfl->seq); - pcfl = setNextItem(reg->reglives.assignedpFlows); - } - pc = setFirstItem(reg->reglives.usedpCodes); - if(pc) - fprintf(stderr, "\n used in instructions "); + reg->isFree = 1; + reg->wasUsed = 0; - while(pc) { - pcfl = PCODE(PCI(pc)->pcflow); - if(pcfl) - fprintf(stderr," 0x%03x:",pcfl->seq); - fprintf(stderr,"0x%03x",pc->seq); + total_registers_saved++; // debugging stats. + } - pc = setNextItem(reg->reglives.usedpCodes); } - fprintf(stderr, "\n"); - } -#endif + } /*-----------------------------------------------------------------* * void pCodeRegOptimeRegUsage(pBlock *pb) @@ -522,11 +577,22 @@ void pCodeRegOptimizeRegUsage(void) /* Identify registers used in one flow sequence */ OptimizeRegUsage(dynAllocRegs); + OptimizeRegUsage(dynStackRegs); + OptimizeRegUsage(dynDirectRegs); if(total_registers_saved != saved) fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved); } while( passes-- && (total_registers_saved != saved)); +/* + fprintf(stderr,"dynamically allocated regs:\n"); + dbg_regusage(dynAllocRegs); + fprintf(stderr,"stack regs:\n"); + dbg_regusage(dynStackRegs); + fprintf(stderr,"direct regs:\n"); + dbg_regusage(dynDirectRegs); +*/ + } diff --git a/src/pic/peeph.def b/src/pic/peeph.def index 09923399..be2cd557 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -199,3 +199,31 @@ replace restart { ; peep 6 - Removed redundant move movwf %1 } + +replace restart { + movlw 0 + iorwf %1,w +} by { + ; peep 7 - Removed redundant move + movf %1,w +} + +replace restart { + movf %1,w + movwf %2 + decf %2,f +} by { + ; peep 8 - Removed redundant move + decf %1,w + movwf %2 +} + +replace restart { + movwf %1 + movf %2,w + xorwf %1,w +} by { + ; peep 9 - Removed redundant move + movwf %1 + xorwf %2,w +} diff --git a/src/pic/ralloc.h b/src/pic/ralloc.h index 4e49651b..a330ece3 100644 --- a/src/pic/ralloc.h +++ b/src/pic/ralloc.h @@ -40,12 +40,20 @@ enum X12_IDX, CND_IDX }; - -#define REG_PTR 0x01 -#define REG_GPR 0x02 -#define REG_CND 0x04 -#define REG_SFR 0x08 -#define REG_STK 0x10 /* Use a register as a psuedo stack */ +enum { + REG_PTR=1, + REG_GPR, + REG_CND, + REG_SFR, + REG_STK, + REG_TMP +}; +//#define REG_PTR 0x01 +//#define REG_GPR 0x02 +//#define REG_CND 0x04 +//#define REG_SFR 0x08 +//#define REG_STK 0x10 /* Use a register as a psuedo stack */ +//#define REG_TMP 0x20 /* definition for the registers */ typedef struct regs diff --git a/src/regression/b.c b/src/regression/b.c index cf09e5c3..27cc34cb 100644 --- a/src/regression/b.c +++ b/src/regression/b.c @@ -1,5 +1,5 @@ -unsigned char success = 0; +unsigned char failures = 0; unsigned char dummy = 0; unsigned char uchar0=0; @@ -47,7 +47,7 @@ void main(void) //incptr(&uchar0); inc(uchar0); if(uchar0 !=2) - success++; + failures++; uchar0 = 2; uchar1 = 1; @@ -55,7 +55,7 @@ void main(void) nested_call(uchar2); if(uchar0 !=4) - success++; + failures++; done(); } diff --git a/src/regression/create_stc b/src/regression/create_stc index 95eca641..6684058f 100755 --- a/src/regression/create_stc +++ b/src/regression/create_stc @@ -12,5 +12,5 @@ fi echo "load s $1" > $2 echo "break e _done" >> $2 echo "run" >> $2 -echo "x _success" >> $2 +echo "x _failures" >> $2 echo "abort_gpsim_now" >> $2 diff --git a/src/regression/simulate b/src/regression/simulate index 548d3dbd..55c60bd5 100755 --- a/src/regression/simulate +++ b/src/regression/simulate @@ -13,9 +13,9 @@ LOGFILE=$2 touch $2 echo "Test $GPSIM_SCRIPT" >> $LOGFILE gpsim --cli -c $GPSIM_SCRIPT $2> test -grep "success " test | grep "= 0x0" +grep "failures " test | grep "= 0x0" if [ $? -eq 0 ] ; then echo "PASSED" >> $LOGFILE else echo "FAILED" >> $LOGFILE -fi \ No newline at end of file +fi -- 2.39.5