X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fralloc.c;h=9a952c357b65602bb3a410caa698dd50c7910e37;hb=4c527a8dc0a11d9bb33bebfe2fafa42e34b2895b;hp=b3b3392c7d258d37455f36ef22a68780bbb2b1fa;hpb=2fd915c3bc6488cd960572406ba8580a90b28b78;p=fw%2Fsdcc diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index b3b3392c..9a952c35 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -153,6 +153,7 @@ debugLog (char *fmt,...) vsprintf (buffer, fmt, ap); fprintf (debugF, "%s", buffer); + //fprintf (stderr, "%s", buffer); /* while (isspace((unsigned char)*bufferP)) bufferP++; @@ -321,6 +322,21 @@ pic16_decodeOp (unsigned int op) return buffer; } + +#if 0 +static char *decodeRegType(short type) +{ + switch(type) { + case REG_GPR: return "REG_GPR"; + case REG_PTR: return "REG_PTR"; + case REG_CND: return "REG_CNT"; + + default: + return ""; + } +} +#endif + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ static char * @@ -359,7 +375,7 @@ static int regname2key(char const *name) /*-----------------------------------------------------------------*/ /* newReg - allocate and init memory for a new register */ /*-----------------------------------------------------------------*/ -regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop) +regs* newReg(int type, short pc_type, int rIdx, char *name, unsigned size, int alias, operand *refop) { regs *dReg; @@ -371,7 +387,12 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia if(name) dReg->name = Safe_strdup(name); else { - sprintf(buffer,"r0x%02X", dReg->rIdx); + if(xinst && pc_type == PO_GPR_TEMP) { + sprintf(buffer,"0x%02x", dReg->rIdx); + } else { + sprintf(buffer,"r0x%02x", dReg->rIdx); + } + if(type == REG_STK) { *buffer = 's'; } @@ -404,7 +425,7 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia dReg->regop = refop; if(!(type == REG_SFR && alias == 0x80)) - hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); + hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg); return dReg; } @@ -417,12 +438,18 @@ regWithIdx (set *dRegs, int idx, unsigned fixed) { regs *dReg; +//#define D(text) text +#define D(text) + for (dReg = setFirstItem(dRegs) ; dReg ; dReg = setNextItem(dRegs)) { + D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed)); if(idx == dReg->rIdx && (fixed == dReg->isFixed)) { + D(fprintf(stderr, "found!\n")); return dReg; - } + } else + D(fprintf(stderr, "not found!\n")); } return NULL; @@ -443,6 +470,8 @@ regFindFree (set *dRegs) // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree); if(dReg->isFree) { +// fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx); + return dReg; } } @@ -528,11 +557,12 @@ allocReg (short type) { regs * reg=NULL; -#define MAX_P16_NREGS 6 +#define MAX_P16_NREGS 16 #if 0 if(dynrIdx > pic16_nRegs) + werror(W_POSSBUG2, __FILE__, __LINE__); return NULL; #endif @@ -540,28 +570,26 @@ allocReg (short type) reg = regFindFree( pic16_dynAllocRegs ); if(reg) { -// fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); +// fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx); } if(!reg) { reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL); -// fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); +// fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__, +// (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx); #if 1 - if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) { -// debugf("allocating more registers than available\n", 0); -// return (NULL); - } + if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) { + // debugf("allocating more registers than available\n", 0); + // return (NULL); + } + + addSet(&pic16_dynAllocRegs, reg); + hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg); +// fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs); #endif - -// addSet(&pic16_dynAllocRegs, reg); } - - addSet(&pic16_dynAllocRegs, reg); - hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg); - - reg->isFree=0; - + debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1); #if 0 @@ -569,6 +597,7 @@ allocReg (short type) __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); #endif if(reg) { + reg->isFree=0; reg->accessBank = 1; /* this is a temporary register alloc in accessBank */ reg->isLocal = 1; /* this is a local frame register */ // reg->wasUsed = 1; @@ -607,7 +636,7 @@ pic16_dirregWithName (char *name) while(reg) { if(STRCASECMP(reg->name, name) == 0) { -// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey); +// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey); return(reg); } @@ -634,7 +663,7 @@ pic16_allocregWithName (char *name) hkey = regname2key(name); -// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); + //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); reg = hTabFirstItemWK(dynAllocRegNames, hkey); @@ -985,7 +1014,7 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed) regs *dReg; debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx); -// fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx); +// fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type)); switch (type) { @@ -1000,6 +1029,11 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed) return dReg; } + if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) { + debugLog ("Found an Internal Register!\n"); + return dReg; + } + break; case REG_STK: if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) { @@ -1052,7 +1086,7 @@ regs * pic16_allocWithIdx (int idx) { - regs *dReg; + regs *dReg=NULL; debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx); // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx); @@ -1071,12 +1105,19 @@ pic16_allocWithIdx (int idx) debugLog ("Dynamic Register not found\n"); +#if 1 + dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL); + addSet(&pic16_dynAllocRegs, dReg); + hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg); +#endif + if(!dReg) { +// return (NULL); //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx); - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "regWithIdx not found"); - exit (1); - + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "allocWithIdx not found"); + exit (1); + } } dReg->wasUsed = 1; @@ -1096,7 +1137,8 @@ pic16_findFreeReg(short type) case REG_GPR: if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL) return dReg; - return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)); +// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); + return allocReg( REG_GPR ); case REG_STK: @@ -1123,7 +1165,8 @@ pic16_findFreeRegNext(short type, regs *creg) case REG_GPR: if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL) return dReg; - return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); +// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); + return (allocReg( REG_GPR ) ); case REG_STK: @@ -2860,6 +2903,7 @@ regTypeNum () static DEFSETFUNC (markRegFree) { ((regs *)item)->isFree = 1; +// ((regs *)item)->wasUsed = 0; return 0; } @@ -3137,12 +3181,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) * if it fits for pic16, but I leave it here just in case */ /* if assignment then check that right is not a bit */ - if (ASSIGNMENT (dic) && !POINTER_SET (dic)) { - sym_link *etype = operandType (IC_RIGHT (dic)); + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) { + sym_link *etype = operandType (IC_RESULT (dic)); if (IS_BITFIELD (etype)) { /* if result is a bit too then it's ok */ - etype = operandType (IC_RESULT (dic)); + etype = operandType (IC_RESULT (ic)); if (!IS_BITFIELD (etype)) { debugLog(" %d bitfields\n"); return 0; @@ -3386,6 +3430,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) bitVect *uses; iCode *dic, *sic; + return NULL; + debugLog ("%s\n", __FUNCTION__); /* if returning a literal then do nothing */ if (!IS_SYMOP (op)) @@ -3757,6 +3803,7 @@ static void packForPush (iCode * ic, eBBlock * ebp) { iCode *dic; + char *iLine; debugLog ("%s\n", __FUNCTION__); if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic))) @@ -3765,10 +3812,13 @@ packForPush (iCode * ic, eBBlock * ebp) #if 0 { int n1, n2; + char *iLine; n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic))); n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic))); + iLine = printILine(ic); debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic)); + dbuf_free(iLine); debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic))); } #endif @@ -3802,7 +3852,9 @@ packForPush (iCode * ic, eBBlock * ebp) and the that the definition is an assignment */ IC_LEFT (ic) = IC_RIGHT (dic); - debugf("remiCodeFromeBBlock: %s\n", printILine(dic)); + iLine = printILine(dic); + debugf("remiCodeFromeBBlock: %s\n", iLine); + dbuf_free(iLine); remiCodeFromeBBlock (ebp, dic); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); @@ -3814,7 +3866,7 @@ static void printSymType(char * str, sym_link *sl) if(!pic16_ralloc_debug)return; debugLog (" %s Symbol type: ",str); - printTypeChain( sl, debugF); + printTypeChain (sl, debugF); debugLog ("\n"); } @@ -4043,44 +4095,17 @@ pic16_packRegisters (eBBlock * ebp) #if 0 - /* if this is an arithmetic operation - * && result or left is not rematerializable (so it is a plain arithmetic op) - * && and left is not used after this iCode */ + /* try to optimize FSR0 usage when reading data memory pointers */ - if(getenv("OPTIMIZE_NEAR_POINTER_GET")) - - if (IS_ARITHMETIC_OP(ic) - && !IS_OP_LITERAL (IC_LEFT (ic)) - && !OP_SYMBOL (IC_RESULT(ic))->rematiCode - && !OP_SYMBOL (IC_LEFT(ic))->rematiCode - && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq) - ) { - iCode *dic = ic->prev; - - /* search backwards to find assignment from a remat pointer */ - while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) { - - /* is it a pointer_get? */ - if(POINTER_GET(dic) - && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) { - fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__, - OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq); - - /* so we can replace ic->left with dic->left, & remove assignment */ - ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) ); - - bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key); - bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key ); - -// dic->op = DUMMY_READ_VOLATILE; -#if 1 - remiCodeFromeBBlock(ebp, dic); - hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); -#endif - break; - } - dic = dic->prev; - } + if(getenv("OPTIMIZE_NEAR_POINTER_GET")) { + static int fsr0usage=0; + static iCode *usic; + + if(POINTER_GET(ic) /* this is a memory read */ + && ic->loop /* this is in a loop */ + ) { + fprintf(stderr, "might optimize FSR0 usage\n"); + } } #endif @@ -4368,6 +4393,9 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) printiCChain (ebbs[i]->sch, debugF); } } + +void dbg_dumpregusage(void); + /*-----------------------------------------------------------------*/ /* pic16_assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ @@ -4385,6 +4413,24 @@ pic16_assignRegisters (ebbIndex * ebbi) _inRegAllocator = 1; + pic16_freeAllRegs(); +#if 0 + dbg_dumpregusage(); + /* clear whats left over from peephole parser */ + pic16_dynAllocRegs= newSet(); //NULL; +// pic16_dynStackRegs= newSet(); //NULL; +// pic16_dynProcessorRegs=newSet(); //NULL; +// pic16_dynDirectRegs=newSet(); //NULL; +// pic16_dynDirectBitRegs=newSet(); //NULL; +// pic16_dynInternalRegs=newSet(); //NULL; +// pic16_dynAccessRegs=newSet(); //NULL; + +// dynDirectRegNames=NULL; + dynAllocRegNames=NULL; +// dynProcRegNames=NULL; +// dynAccessRegNames=NULL; +#endif + setToNull ((void *) &_G.funcrUsed); pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; @@ -4424,7 +4470,9 @@ pic16_assignRegisters (ebbIndex * ebbi) regTypeNum (); /* start counting function temporary registers from zero */ - dynrIdx = 0; + /* XXX: Resetting dynrIdx breaks register allocation, + * see #1489055, #1483693 (?), and #1445850! */ + //dynrIdx = 0; /* and serially allocate registers */ serialRegAssign (ebbs, count); @@ -4461,6 +4509,8 @@ pic16_assignRegisters (ebbIndex * ebbi) if (options.dump_rassgn) dumpEbbsToFileExt (DUMP_RASSGN, ebbi); +// dumpLR(ebbs, count); + /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));