X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fralloc.c;h=1319ff89e97ba01cb0ae31a4c2cc8463879e9117;hb=3062f96ccb55d1d05caf9c8782f4961f87b341ce;hp=032029018a5063f812e4f538a0d07978806a2ef2;hpb=ec58d965706980b34d054c87c6359e7800bfe725;p=fw%2Fsdcc diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 03202901..1319ff89 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -31,12 +31,6 @@ #include "gen.h" #include "device.h" -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #ifndef debugf #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) #endif @@ -153,8 +147,9 @@ debugLog (char *fmt,...) vsprintf (buffer, fmt, ap); fprintf (debugF, "%s", buffer); + //fprintf (stderr, "%s", buffer); /* - while (isspace(*bufferP)) bufferP++; + while (isspace((unsigned char)*bufferP)) bufferP++; if (bufferP && *bufferP) lineCurr = (lineCurr ? @@ -170,10 +165,10 @@ debugLog (char *fmt,...) static void debugNewLine (void) { - if(!pic16_ralloc_debug)return; - - if (debugF) - fputc ('\n', debugF); + if(!pic16_ralloc_debug)return; + + if (debugF) + fputc ('\n', debugF); } /*-----------------------------------------------------------------*/ /* debugLogClose - closes the debug log file (if opened) */ @@ -181,10 +176,10 @@ debugNewLine (void) static void debugLogClose (void) { - if (debugF) { - fclose (debugF); - debugF = NULL; - } + if (debugF) { + fclose (debugF); + debugF = NULL; + } } #define AOP(op) op->aop @@ -275,7 +270,6 @@ pic16_decodeOp (unsigned int op) case STRUCT: return "STRUCT"; case UNION: return "UNION"; case ENUM: return "ENUM"; - case ELIPSIS: return "ELIPSIS"; case RANGE: return "RANGE"; case FAR: return "FAR"; case CASE: return "CASE"; @@ -302,6 +296,7 @@ pic16_decodeOp (unsigned int op) case IPUSH: return "IPUSH"; case IPOP: return "IPOP"; case PCALL: return "PCALL"; + case FUNCTION: return "FUNCTION"; case ENDFUNCTION: return "ENDFUNCTION"; case JUMPTABLE: return "JUMPTABLE"; case RRC: return "RRC"; @@ -314,11 +309,27 @@ pic16_decodeOp (unsigned int op) case LABEL: return "LABEL"; case RECEIVE: return "RECEIVE"; case SEND: return "SEND"; + case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE"; } sprintf (buffer, "unkown op %d %c", op, op & 0xff); 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 * @@ -357,7 +368,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; @@ -369,10 +380,16 @@ 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(type == REG_STK) - *buffer = 's'; - dReg->name = Safe_strdup(buffer); + 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'; + } + dReg->name = Safe_strdup(buffer); } @@ -391,7 +408,7 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia } #if NEWREG_DEBUG - fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop); + fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop); #endif dReg->size = size; dReg->alias = alias; @@ -401,7 +418,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; } @@ -414,12 +431,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; @@ -440,12 +463,34 @@ 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; } } return NULL; } + +static regs * +regFindFreeNext(set *dRegs, regs *creg) +{ + regs *dReg; + + if(creg) { + /* position at current register */ + for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs)); + } + + for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) { + if(dReg->isFree) { + return dReg; + } + } + + return NULL; +} + /*-----------------------------------------------------------------*/ /* pic16_initStack - allocate registers for a pseudo stack */ /*-----------------------------------------------------------------*/ @@ -505,11 +550,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 @@ -517,28 +563,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 @@ -546,6 +590,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; @@ -584,7 +629,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); } @@ -611,7 +656,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); @@ -737,7 +782,7 @@ pic16_allocDirReg (operand *op ) if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { -#if 1 +#if 0 if(pic16_debug_verbose) { fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, @@ -906,8 +951,8 @@ pic16_allocDirReg (operand *op ) reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op)); /* work around for user defined registers in access bank */ - if((reg->address>= 0x00 && reg->address < 0x80) - || (reg->address >= 0xf80 && reg->address <= 0xfff)) + if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs) + || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff)) reg->accessBank = 1; debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address); @@ -939,7 +984,7 @@ pic16_allocRegByName (char *name, int size, operand *op) * a new one and put it in the hash table AND in the * dynDirectRegNames set */ - fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op); + //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op); reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op); @@ -962,7 +1007,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) { @@ -977,6 +1022,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 ) { @@ -1029,7 +1079,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); @@ -1048,12 +1098,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; @@ -1073,7 +1130,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: @@ -1089,6 +1147,34 @@ pic16_findFreeReg(short type) return NULL; } } + +regs * +pic16_findFreeRegNext(short type, regs *creg) +{ + // int i; + regs* dReg; + + switch (type) { + 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 (allocReg( REG_GPR ) ); + + case REG_STK: + + if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL) + return dReg; + + return NULL; + + case REG_PTR: + case REG_CND: + case REG_SFR: + default: + return NULL; + } +} /*-----------------------------------------------------------------*/ /* freeReg - frees a register */ /*-----------------------------------------------------------------*/ @@ -1238,52 +1324,40 @@ static void packBits(set *bregs) void pic16_writeUsedRegs(FILE *of) { - packBits(pic16_dynDirectBitRegs); - -// fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynAllocRegs); - -// fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynInternalRegs); - -// fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynStackRegs); - -// fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynDirectRegs); - -// fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynDirectBitRegs); - -// fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynProcessorRegs); - -// fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynAccessRegs); + packBits(pic16_dynDirectBitRegs); + + pic16_groupRegistersInSection(pic16_dynAllocRegs); + pic16_groupRegistersInSection(pic16_dynInternalRegs); + pic16_groupRegistersInSection(pic16_dynStackRegs); + pic16_groupRegistersInSection(pic16_dynDirectRegs); + pic16_groupRegistersInSection(pic16_dynDirectBitRegs); + pic16_groupRegistersInSection(pic16_dynProcessorRegs); + pic16_groupRegistersInSection(pic16_dynAccessRegs); - /* dump equates */ - pic16_dump_equates(of, pic16_equ_data); + /* dump equates */ + pic16_dump_equates(of, pic16_equ_data); // pic16_dump_esection(of, pic16_rel_eedata, 0); // pic16_dump_esection(of, pic16_fix_eedata, 0); - /* dump access bank symbols */ - pic16_dump_access(of, pic16_acs_udata); + /* dump access bank symbols */ + pic16_dump_access(of, pic16_acs_udata); - /* dump initialised data */ - pic16_dump_isection(of, rel_idataSymSet, 0); - pic16_dump_isection(of, fix_idataSymSet, 1); + /* dump initialised data */ + pic16_dump_isection(of, rel_idataSymSet, 0); + pic16_dump_isection(of, fix_idataSymSet, 1); - /* dump internal registers */ - pic16_dump_int_registers(of, pic16_int_regs); + if(!xinst) { + /* dump internal registers */ + pic16_dump_int_registers(of, pic16_int_regs); + } - /* dump generic section variables */ - pic16_dump_gsection(of, sectNames); + /* dump generic section variables */ + pic16_dump_gsection(of, sectNames); - /* dump other variables */ - pic16_dump_usection(of, pic16_rel_udata, 0); - pic16_dump_usection(of, pic16_fix_udata, 1); - + /* dump other variables */ + pic16_dump_usection(of, pic16_rel_udata, 0); + pic16_dump_usection(of, pic16_fix_udata, 1); } @@ -2057,15 +2131,20 @@ deassignLRs (iCode * ic, eBBlock * ebp) sym->nRegs) >= result->nRegs) ) { + - for (i = 0; i < max (sym->nRegs, result->nRegs); i++) +// for (i = 0; i < max (sym->nRegs, result->nRegs); i++) + /* the above does not free the unsued registers in sym, + * leaving them marked as used, and increasing register usage + * until the end of the function - VR 23/11/05 */ + + for (i = 0; i < result->nRegs; i++) if (i < sym->nRegs) result->regs[i] = sym->regs[i]; else result->regs[i] = getRegGpr (ic, ebp, result); _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); - } /* free the remaining */ @@ -2304,6 +2383,10 @@ serialRegAssign (eBBlock ** ebbs, int count) or this one is rematerializable then spill this one */ willCS = willCauseSpill (sym->nRegs, sym->regType); + + /* explicit turn off register spilling */ + willCS = 0; + spillable = computeSpillable (ic); if (sym->remat || (willCS && bitVectIsZero (spillable))) @@ -2319,12 +2402,13 @@ serialRegAssign (eBBlock ** ebbs, int count) have been allocated after sym->liveFrom but freed before ic->seq. This is complicated, so spill this symbol instead and let fillGaps handle the allocation. */ +#if 0 if (sym->liveFrom < ic->seq) { spillThis (sym); continue; } - +#endif /* if it has a spillocation & is used less than all other live ranges then spill this */ if (willCS) { @@ -2742,6 +2826,7 @@ regTypeNum () !IS_BITVAR (sym->etype) && (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) { +// continue; /* FIXME -- VR */ if (ptrPseudoSymSafe (sym, ic)) { symbol *psym; @@ -2811,6 +2896,7 @@ regTypeNum () static DEFSETFUNC (markRegFree) { ((regs *)item)->isFree = 1; +// ((regs *)item)->wasUsed = 0; return 0; } @@ -2927,13 +3013,32 @@ farSpacePackable (iCode * ic) return NULL; } +#if 0 +static int packRegsForPointerGet(iCode *ic, eBBlock *ebp) +{ + iCode *dic, *sic; + + debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); + debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) ); + debugAopGet (" result:", IC_RESULT (ic)); + debugAopGet (" left:", IC_LEFT (ic)); + debugAopGet (" right:", IC_RIGHT (ic)); + + dic = ic->prev; + if((dic->op == '=') + && ( +} +#endif + + +void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst); + /*-----------------------------------------------------------------*/ /* packRegsForAssign - register reduction for assignment */ /*-----------------------------------------------------------------*/ static int packRegsForAssign (iCode * ic, eBBlock * ebp) { - iCode *dic, *sic; debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); @@ -3069,12 +3174,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; @@ -3106,34 +3211,35 @@ pack: /* found the definition */ /* replace the result with the result of */ /* this assignment and remove this assignment */ - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); - IC_RESULT (dic) = IC_RESULT (ic); - - if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) - { - OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; - } - /* delete from liverange table also - delete from all the points inbetween and the new - one */ - for (sic = dic; sic != ic; sic = sic->next) - { - bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); - if (IS_ITEMP (IC_RESULT (dic))) - bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); - } - remiCodeFromeBBlock (ebp, ic); - bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); + IC_RESULT (dic) = IC_RESULT (ic); - debugLog(" %d\n", __LINE__ ); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); - return 1; + if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) + { + OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq; + } + /* delete from liverange table also + delete from all the points inbetween and the new + one */ + for (sic = dic; sic != ic; sic = sic->next) + { + bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key); + if (IS_ITEMP (IC_RESULT (dic))) + bitVectSetBit (sic->rlive, IC_RESULT (dic)->key); + } + remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + debugLog(" %d\n", __LINE__ ); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + return 1; } + #if 1 #define NO_packRegsForAccUse @@ -3317,16 +3423,24 @@ 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)) return NULL; + if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) + return NULL; + /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */ - ic->op != RETURN && - ic->op != SEND) + if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1) + && ic->op != RETURN + && ic->op != SEND + && !POINTER_SET(ic) + && !POINTER_GET(ic) + ) return NULL; /* this routine will mark the a symbol as used in one @@ -3335,10 +3449,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) that definition is either a return value from a function or does not contain any variables in far space */ + +#if 0 uses = bitVectCopy (OP_USES (op)); bitVectUnSetBit (uses, ic->key); /* take away this iCode */ if (!bitVectIsZero (uses)) /* has other uses */ return NULL; +#endif + +#if 1 + if (bitVectnBitsOn (OP_USES (op)) > 1) + return NULL; +#endif /* if it has only one defintion */ if (bitVectnBitsOn (OP_DEFS (op)) > 1) @@ -3367,6 +3489,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) } dic = dic->next; } + else + { /* otherwise check that the definition does @@ -3388,6 +3512,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) if (POINTER_GET (dic) && !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) return NULL; + } sic = dic; @@ -3418,7 +3543,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) operation is a '*','/' or '%' then 'b' may cause a problem */ if ((dic->op == '%' || dic->op == '/' || dic->op == '*') && - getSize (operandType (op)) >= 3) + getSize (operandType (op)) >= 2) return NULL; /* if left or right or result is in far space */ @@ -3671,6 +3796,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))) @@ -3679,10 +3805,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 @@ -3716,7 +3845,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); @@ -3728,7 +3859,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"); } @@ -3955,13 +4086,31 @@ pic16_packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; } + +#if 0 + /* try to optimize FSR0 usage when reading data memory pointers */ + + 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 + /* mark the pointer usages */ if (POINTER_SET (ic)) { OP_SYMBOL (IC_RESULT (ic))->uptr = 1; debugLog (" marking as a pointer (set) =>"); debugAopGet (" result:", IC_RESULT (ic)); + } + if (POINTER_GET (ic)) { if(IS_SYMOP(IC_LEFT(ic))) { @@ -3969,6 +4118,32 @@ pic16_packRegisters (eBBlock * ebp) debugLog (" marking as a pointer (get) =>"); debugAopGet (" left:", IC_LEFT (ic)); } + + if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) { + if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) { + iCode *dic = ic->prev; + + fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__); + + if(dic && dic->op == '=' + && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) { + + fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__); + + + /* replace prev->left with ic->left */ + IC_LEFT(ic) = IC_RIGHT(dic); + IC_RIGHT(ic->prev) = NULL; + + /* remove ic->prev iCode (assignment) */ + remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key); + + + hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); + } + } + } } //debugLog(" %d %s\n", __LINE__, __FUNCTION__); @@ -4211,12 +4386,17 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) printiCChain (ebbs[i]->sch, debugF); } } + +void dbg_dumpregusage(void); + /*-----------------------------------------------------------------*/ /* pic16_assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ void -pic16_assignRegisters (eBBlock ** ebbs, int count) +pic16_assignRegisters (ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; iCode *ic; int i; @@ -4226,6 +4406,24 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) _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; @@ -4235,19 +4433,21 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) for (i = 0; i < count; i++) pic16_packRegisters (ebbs[i]); + { regs *reg; int hkey; - int i=0; debugLog("dir registers allocated so far:\n"); reg = hTabFirstItem(dynDirectRegNames, &hkey); +#if 0 while(reg) { debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); reg = hTabNextItem(dynDirectRegNames, &hkey); } +#endif } @@ -4256,14 +4456,16 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) recomputeLiveRanges (ebbs, count); if (options.dump_pack) - dumpEbbsToFileExt (DUMP_PACK, ebbs, count); + dumpEbbsToFileExt (DUMP_PACK, ebbi); /* first determine for each live range the number of registers & the type of registers required for each */ 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); @@ -4298,7 +4500,9 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) redoStackOffsets (); if (options.dump_rassgn) - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); + +// dumpLR(ebbs, count); /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); @@ -4306,6 +4510,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) debugLog ("ebbs after optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 0; genpic16Code (ic);