From fce3c2dbaa1f926fd28eb6678c5727103f763897 Mon Sep 17 00:00:00 2001 From: sdattalo Date: Fri, 5 Jul 2002 05:43:35 +0000 Subject: [PATCH] Register Optimizer was ignoring volatility of SFRs git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2029 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/device.c | 4 +- src/pic/glue.c | 26 +------- src/pic/pcode.c | 20 ++++-- src/pic/pcoderegs.c | 101 ++++++++++++++++++++++------ src/pic/peeph.def | 14 +++- src/pic/ralloc.c | 159 +++++++++++++++++++++++--------------------- 6 files changed, 194 insertions(+), 130 deletions(-) diff --git a/src/pic/device.c b/src/pic/device.c index bdb3cf6a..eb9051d6 100644 --- a/src/pic/device.c +++ b/src/pic/device.c @@ -559,7 +559,7 @@ void mapRegister(regs *reg) do { - // fprintf(stdout,"mapping %s to address 0x%02x, reg size = %d\n",reg->name, (reg->address+alias+i),reg->size); + //fprintf(stdout,"mapping %s to address 0x%02x, reg size = %d\n",reg->name, (reg->address+alias+i),reg->size); finalMapping[reg->address + alias + i].reg = reg; finalMapping[reg->address + alias + i].instance = i; @@ -587,7 +587,7 @@ int assignRegister(regs *reg, int start_address) if(reg->isFixed) { if (validAddress(reg->address,reg->size)) { - + fprintf(stderr,"%s - %s address = 0x%03x\n",__FUNCTION__,reg->name, reg->address); mapRegister(reg); return reg->address; } diff --git a/src/pic/glue.c b/src/pic/glue.c index 90cc028a..45896e1e 100644 --- a/src/pic/glue.c +++ b/src/pic/glue.c @@ -64,7 +64,7 @@ extern void initialComments (FILE * afile); extern void printPublics (FILE * afile); extern void printChar (FILE * ofile, char *s, int plen); - +void pCodeInitRegisters(void); /*-----------------------------------------------------------------*/ /* aopLiteral - string from a literal value */ @@ -734,31 +734,9 @@ picglue () FILE *vFile; FILE *asmFile; FILE *ovrFile = tempfile(); - // int i; -#if 0 - set *s=NULL,*t=NULL; - char a=1,b=2,c=3; - - - addSet(&s,&a); - addSet(&s,&b); - addSet(&s,&c); - - DFPRINTF((stderr,"\n\n\n******************\n\n\n")); - for(t=s; t; t=t->next) { - if(t->item) - DFPRINTF((stderr,"Set item %d\n",*(char *)t->item)); - } - - s =reverseSet(s); - for(t=s; t; t=t->next) { - if(t->item) - DFPRINTF((stderr,"Set item %d\n",*(char *)t->item)); - } -#endif addSetHead(&tmpfileSet,ovrFile); - + pCodeInitRegisters(); if (mainf && IFFUNC_HASBODY(mainf->type)) { diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 6aad5703..8713b457 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -50,12 +50,12 @@ peepCommand peepCommands[] = { // Eventually this will go into device dependent files: -pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,NULL}; +pCodeOpReg pc_status = {{PO_STATUS, "_STATUS"}, -1, NULL,0,NULL}; pCodeOpReg pc_indf = {{PO_INDF, "INDF"}, -1, NULL,0,NULL}; pCodeOpReg pc_fsr = {{PO_FSR, "FSR"}, -1, NULL,0,NULL}; pCodeOpReg pc_intcon = {{PO_INTCON, ""}, -1, NULL,0,NULL}; pCodeOpReg pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,0,NULL}; -pCodeOpReg pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,0,NULL}; +pCodeOpReg pc_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL}; pCodeOpReg pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL}; pCodeOpReg pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL}; @@ -1206,13 +1206,18 @@ extern void init_pic(char *); void pCodeInitRegisters(void) { + static int initialized=0; + + if(initialized) + return; + initialized = 1; initStack(0xfff, 8); init_pic(port->processor); - pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80); + pc_status.r = allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80); pc_pcl.r = allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80); - pc_pclath.r = allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80); + pc_pclath.r = allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80); pc_fsr.r = allocProcessorRegister(IDX_FSR,"FSR", PO_FSR, 0x80); pc_indf.r = allocProcessorRegister(IDX_INDF,"INDF", PO_INDF, 0x80); pc_intcon.r = allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80); @@ -2779,13 +2784,16 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static pBranch * pBranchAppend(pBranch *h, pBranch *n) +pBranch * pBranchAppend(pBranch *h, pBranch *n) { pBranch *b; if(!h) return n; + if(h == n) + return n; + b = h; while(b->next) b = b->next; @@ -3600,7 +3608,7 @@ void LinkFlow(pBlock *pb) //pc->print(stderr,pc); if(!(pcol && isPCOLAB(pcol))) { - if((PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) { + if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) { pc->print(stderr,pc); fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__); } diff --git a/src/pic/pcoderegs.c b/src/pic/pcoderegs.c index 5b0b9d92..f536987f 100644 --- a/src/pic/pcoderegs.c +++ b/src/pic/pcoderegs.c @@ -39,6 +39,7 @@ extern void pCodeInsertAfter(pCode *pc1, pCode *pc2); extern void dbg_dumpregusage(void); extern pCode * findPrevInstruction(pCode *pci); +extern pBranch * pBranchAppend(pBranch *h, pBranch *n); void unlinkpCode(pCode *pc); int total_registers_saved=0; @@ -225,6 +226,46 @@ void pCodeRegMapLiveRanges(pBlock *pb) } +/*-----------------------------------------------------------------* + * + *-----------------------------------------------------------------*/ +static void Remove1pcode(pCode *pc, regs *reg) +{ + pCode *pcn=NULL; + + if(!reg || !pc) + return; + + deleteSetItem (&(reg->reglives.usedpCodes),pc); +/* + fprintf(stderr,"removing instruction:\n"); + pc->print(stderr,pc); +*/ + if(PCI(pc)->label) { + pcn = findNextInstruction(pc->next); + + if(pcn) + PCI(pcn)->label = pBranchAppend(PCI(pcn)->label,PCI(pc)->label); + } + + if(PCI(pc)->cline) { + if(!pcn) + pcn = findNextInstruction(pc->next); + + if(pcn) { + if(PCI(pcn)->cline) { + //fprintf(stderr, "source line has been optimized completely out\n"); + //pc->print(stderr,pc); + } else { + PCI(pcn)->cline = PCI(pc)->cline; + } + } + } + + pc->destruct(pc); + +} + /*-----------------------------------------------------------------* * void RemoveRegsFromSet(set *regset) * @@ -233,16 +274,20 @@ void RemoveRegsFromSet(set *regset) { regs *reg; int used; - for (reg = setFirstItem(regset) ; reg ; - reg = setNextItem(regset)) { + while(regset) { + reg = regset->item; + regset = regset->next; +/* + for (reg = setFirstItem(regset) ; reg ; + reg = setNextItem(regset)) { +*/ used = elementsInSet(reg->reglives.usedpCodes); if(used <= 1) { //fprintf(stderr," reg %s isfree=%d, wasused=%d\n",reg->name,reg->isFree,reg->wasUsed); - if(used == 0) { //fprintf(stderr," getting rid of reg %s\n",reg->name); reg->isFree = 1; @@ -252,6 +297,13 @@ void RemoveRegsFromSet(set *regset) pc = setFirstItem(reg->reglives.usedpCodes); + + if(reg->type == REG_SFR) { + //fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name); + continue; + } + + if(isPCI(pc)) { if(PCI(pc)->label) { pCode *pcn = findNextInstruction(pc->next); @@ -267,12 +319,18 @@ void RemoveRegsFromSet(set *regset) } - if(isPCI_SKIP(pc)) + if(isPCI_SKIP(pc)) { + regs *r = getRegFromInstruction(pc); fprintf(stderr, "WARNING, a skip instruction is being optimized out\n"); - + pc->print(stderr,pc); + fprintf(stderr,"reg %s, type =%d\n",r->name, r->type); + } //fprintf(stderr," removing reg %s because it is used only once\n",reg->name); - unlinkpCode(pc); - deleteSetItem (&(reg->reglives.usedpCodes),pc); + Remove1pcode(pc, reg); + /* + unlinkpCode(pc); + deleteSetItem (&(reg->reglives.usedpCodes),pc); + */ reg->isFree = 1; reg->wasUsed = 0; total_registers_saved++; // debugging stats. @@ -312,15 +370,11 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg) if(!reg) return; - if(pc1) { - deleteSetItem (&(reg->reglives.usedpCodes),pc1); - pc1->destruct(pc1); - } + if(pc1) + Remove1pcode(pc1, reg); if(pc2) { - deleteSetItem (&(reg->reglives.usedpCodes),pc2); - pc2->destruct(pc2); - + Remove1pcode(pc2, reg); deleteSetItem (&(PCFL(pcflow)->registers), reg); reg->isFree = 1; @@ -375,6 +429,10 @@ void OptimizeRegUsage(set *fregs) reg = fregs->item; fregs = fregs->next; + if(reg->type == REG_SFR) { + //fprintf(stderr,"skipping SFR: %s\n",reg->name); + continue; + } pcfl_used = setFirstItem(reg->reglives.usedpFlows); pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows); @@ -392,10 +450,10 @@ void OptimizeRegUsage(set *fregs) regs *reg1, *reg2; /* - fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x used=%d\n", + fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n", reg->name, reg->address, - reg->rIdx, used); + reg->rIdx, reg->type, used); */ pc1 = setFirstItem(reg->reglives.usedpCodes); pc2 = setNextItem(reg->reglives.usedpCodes); @@ -494,6 +552,7 @@ void OptimizeRegUsage(set *fregs) reg1 = getRegFromInstruction(pct1); if(reg1 && !regUsedinRange(pc1,pc2,reg1)) { + //fprintf(stderr, " MOVF/MOVFW. \n"); /* movf reg1,w movwf reg @@ -527,7 +586,7 @@ 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); + //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); @@ -543,11 +602,15 @@ void OptimizeRegUsage(set *fregs) pc = setFirstItem(reg->reglives.usedpCodes); while(pc) { - pcfl_assigned = PCI(pc)->pcflow; + + pcfl_assigned = PCODE(PCI(pc)->pcflow); + Remove1pcode(pc, reg); + deleteSetItem (&(PCFL(pcfl_assigned)->registers), reg); + /* deleteSetItem (&(reg->reglives.usedpCodes),pc); pc->destruct(pc); - + */ pc = setNextItem(reg->reglives.usedpCodes); } diff --git a/src/pic/peeph.def b/src/pic/peeph.def index be2cd557..1ffe50d8 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -164,7 +164,7 @@ replace restart { replace restart { decf %1,f movf %1,w - btfss status,z + btfss _STATUS,z goto %2 } by { ; peep 3 - decf/mov/skpz to decfsz @@ -223,7 +223,17 @@ replace restart { movf %2,w xorwf %1,w } by { - ; peep 9 - Removed redundant move + ; peep 9a - Removed redundant move movwf %1 xorwf %2,w } + +replace restart { + movwf %1 + movf %2,w + iorwf %1,w +} by { + ; peep 9b - Removed redundant move + movwf %1 + iorwf %2,w +} diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index e8394512..c9d8a5a6 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -407,10 +407,29 @@ debugLogRegType (short type) return "REG_CND"; } - sprintf (buffer, "unkown reg type %d", type); + sprintf (buffer, "unknown reg type %d", type); return buffer; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +static int regname2key(char const *name) +{ + int key = 0; + + if(!name) + return 0; + + while(*name) { + + key += (*name++) + 1; + + } + + return ( (key + (key >> 4) + (key>>8)) & 0x3f); + +} + /*-----------------------------------------------------------------*/ /* newReg - allocate and init memory for a new register */ /*-----------------------------------------------------------------*/ @@ -434,7 +453,11 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); dReg->isFree = 0; dReg->wasUsed = 1; - dReg->isFixed = 0; + if(type == REG_SFR) + dReg->isFixed = 1; + else + dReg->isFixed = 0; + dReg->isMapped = 0; dReg->isEmitted = 0; dReg->address = 0; @@ -444,6 +467,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->reglives.usedpFlows = newSet(); dReg->reglives.assignedpFlows = newSet(); + hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); + return dReg; } @@ -492,6 +517,8 @@ void initStack(int base_address, int size) int i; Gstack_base_addr = base_address; + //fprintf(stderr,"initStack"); + for(i = 0; iwasUsed = 0; return addSet(&dynInternalRegs,reg); @@ -522,30 +552,13 @@ allocReg (short type) { debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); + //fprintf(stderr,"allocReg\n"); return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); } -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ -static int regname2key(char const *name) -{ - int key = 0; - - if(!name) - return 0; - - while(*name) { - - key += (*name++) + 1; - - } - - return ( (key + (key >> 4) + (key>>8)) & 0x3f); - -} /*-----------------------------------------------------------------*/ /* dirregWithName - search for register by name */ @@ -632,7 +645,21 @@ allocDirReg (operand *op ) return NULL; /* First, search the hash table to see if there is a register with this name */ - reg = dirregWithName(name); + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) { + reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1); +/* + if(!reg) + fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n", + name, SPEC_ADDR ( OP_SYM_ETYPE(op))); + else + fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n", + name, SPEC_ADDR ( OP_SYM_ETYPE(op))); +*/ + } else { + //fprintf(stderr,"ralloc %s \n", name); + + reg = dirregWithName(name); + } if(!reg) { int address = 0; @@ -646,20 +673,24 @@ allocDirReg (operand *op ) * a new one and put it in the hash table AND in the * dynDirectRegNames set */ if(!IS_CONFIG_ADDRESS(address)) { + //fprintf(stderr,"allocating new reg %s\n",name); + reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 ); debugLog (" -- added %s to hash, size = %d\n", name,reg->size); -/* + + //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { - reg->isFixed = 1; - reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op)); - debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address); + + //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name); + reg->type = REG_SFR; } -*/ - hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + if (IS_BITVAR (OP_SYM_ETYPE(op))) addSet(&dynDirectBitRegs, reg); else addSet(&dynDirectRegs, reg); + } else { debugLog (" -- %s is declared at address 0x2007\n",name); @@ -689,8 +720,6 @@ allocRegByName (char *name, int size) exit(1); } - debugLog ("%s symbol name %s\n", __FUNCTION__,name); - /* First, search the hash table to see if there is a register with this name */ reg = dirregWithName(name); @@ -699,12 +728,12 @@ allocRegByName (char *name, int size) /* Register wasn't found in hash, so let's create * a new one and put it in the hash table AND in the * dynDirectRegNames set */ - + //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name); reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 ); debugLog (" -- added %s to hash, size = %d\n", name,reg->size); - hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); addSet(&dynDirectRegs, reg); } @@ -754,36 +783,6 @@ typeRegWithIdx (int idx, int type, int fixed) break; } -#if 0 - - if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) { - - debugLog ("Found a Dynamic Register!\n"); - return dReg; - } - - if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) { - debugLog ("Found a Stack Register!\n"); - return dReg; - } - - if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) { - debugLog ("Found a Direct Register!\n"); - return dReg; - } - - if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) { - debugLog ("Found a Processor Register!\n"); - return dReg; - } -#endif - - /* - if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) { - debugLog ("Found a bit Register!\n"); - return dReg; - } - */ return NULL; } @@ -857,7 +856,7 @@ pic14_findFreeReg(short type) case REG_GPR: if((dReg = regFindFree(dynAllocRegs)) != NULL) return dReg; - + //fprintf(stderr,"findfreereg\n"); return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); case REG_STK: @@ -924,7 +923,6 @@ nfreeRegsType (int type) return nFreeRegs (type); } -//<<<<<<< ralloc.c void writeSetUsedRegs(FILE *of, set *dRegs) { @@ -954,6 +952,7 @@ void packBits(set *bregs) int byte_no=-1; char buffer[20]; + for (regset = bregs ; regset ; regset = regset->next) { @@ -971,12 +970,12 @@ void packBits(set *bregs) if(!bitfield) { sprintf (buffer, "fbitfield%02x", breg->address); //fprintf(stderr,"new bit field\n"); - bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0); + bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0); bitfield->isBitField = 1; bitfield->isFixed = 1; bitfield->address = breg->address; addSet(&dynDirectRegs,bitfield); - hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield); + //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield); } else { //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address); ; @@ -993,7 +992,7 @@ void packBits(set *bregs) relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0); relocbitfield->isBitField = 1; addSet(&dynDirectRegs,relocbitfield); - hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield); + //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield); } @@ -1037,7 +1036,7 @@ void bitEQUs(FILE *of, set *bregs) } } -void aliasEQUs(FILE *of, set *fregs) +void aliasEQUs(FILE *of, set *fregs, int use_rIdx) { regs *reg; @@ -1045,10 +1044,16 @@ void aliasEQUs(FILE *of, set *fregs) for (reg = setFirstItem(fregs) ; reg ; reg = setNextItem(fregs)) { - if(!reg->isEmitted && reg->wasUsed) - fprintf (of, "%s\tEQU\t0x%03x\n", - reg->name, - reg->address); + if(!reg->isEmitted && reg->wasUsed) { + if(use_rIdx) + fprintf (of, "%s\tEQU\t0x%03x\n", + reg->name, + reg->rIdx); + else + fprintf (of, "%s\tEQU\t0x%03x\n", + reg->name, + reg->address); + } } } @@ -1070,9 +1075,10 @@ void writeUsedRegs(FILE *of) dump_cblock(of); bitEQUs(of,dynDirectBitRegs); - aliasEQUs(of,dynAllocRegs); - aliasEQUs(of,dynDirectRegs); - aliasEQUs(of,dynStackRegs); + aliasEQUs(of,dynAllocRegs,0); + aliasEQUs(of,dynDirectRegs,0); + aliasEQUs(of,dynStackRegs,0); + aliasEQUs(of,dynProcessorRegs,1); } @@ -1104,8 +1110,7 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq) return TRUE; } #endif -//======= -//>>>>>>> 1.28 + /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ /*-----------------------------------------------------------------*/ @@ -2376,7 +2381,7 @@ rematStr (symbol * sym) //s += strlen(s); //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; //continue ; - fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s); + //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s); return buffer; } -- 2.30.2