X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fralloc.c;h=5fa12896432b93910d0a3eac2bcd074ac268af39;hb=195ee3f3ee25ce2c5f2a59fbd2779c4cb80527c3;hp=d06ecc89a4e980de5e9a7f86ac21a9dcd5aff5b8;hpb=cef02d0dae9b2c3d273d09f5026aef204ac39809;p=fw%2Fsdcc diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index d06ecc89..5fa12896 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -37,6 +37,12 @@ #define STRCASECMP strcasecmp #endif +#ifndef debugf +#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) +#endif +void _debugf(char *f, int l, char *frm, ...); + +#define NEWREG_DEBUG 0 //#define USE_ONSTACK @@ -103,7 +109,9 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that * are used to pass and return parameters */ - +int _inRegAllocator=0; /* flag that marks whther allocReg happens while + * inside the register allocator function */ + static void spillThis (symbol *); int pic16_ralloc_debug = 0; @@ -146,7 +154,7 @@ debugLog (char *fmt,...) fprintf (debugF, "%s", buffer); /* - while (isspace(*bufferP)) bufferP++; + while (isspace((unsigned char)*bufferP)) bufferP++; if (bufferP && *bufferP) lineCurr = (lineCurr ? @@ -195,8 +203,8 @@ debugAopGet (char *str, operand * op) return NULL; } -static char * -decodeOp (unsigned int op) +char * +pic16_decodeOp (unsigned int op) { if (op < 128 && op > ' ') { buffer[0] = (op & 0xff); @@ -306,6 +314,7 @@ 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); @@ -382,8 +391,9 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia dReg->accessBank = 0; } -// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop); - +#if NEWREG_DEBUG + fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop); +#endif dReg->size = size; dReg->alias = alias; dReg->reg_alias = NULL; @@ -437,6 +447,26 @@ regFindFree (set *dRegs) 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 */ /*-----------------------------------------------------------------*/ @@ -486,6 +516,8 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) return NULL; } + + /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ /*-----------------------------------------------------------------*/ @@ -494,6 +526,9 @@ allocReg (short type) { regs * reg=NULL; +#define MAX_P16_NREGS 6 + + #if 0 if(dynrIdx > pic16_nRegs) return NULL; @@ -503,11 +538,20 @@ allocReg (short type) reg = regFindFree( pic16_dynAllocRegs ); if(reg) { -// fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name); +// fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", 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); + +#if 1 + if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) { +// debugf("allocating more registers than available\n", 0); +// return (NULL); + } +#endif + // addSet(&pic16_dynAllocRegs, reg); } @@ -516,11 +560,12 @@ allocReg (short type) reg->isFree=0; -// debugLog ("%s of type %s for register rIdx: %d\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1); - -// fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n", -// __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); + debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1); +#if 0 + fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n", + __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); +#endif if(reg) { reg->accessBank = 1; /* this is a temporary register alloc in accessBank */ reg->isLocal = 1; /* this is a local frame register */ @@ -713,7 +758,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__, @@ -752,9 +797,14 @@ pic16_allocDirReg (operand *op ) return NULL; } - + if(IS_ITEMP(op))return NULL; + +// if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL; + + if(IN_STACK(OP_SYM_ETYPE(op)))return NULL; + debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name); -// fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name); +// fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op))); { if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) { @@ -803,10 +853,12 @@ pic16_allocDirReg (operand *op ) } +#if 0 if(OP_SYMBOL(op)->onStack) { fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__, OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack); } +#endif if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) { @@ -856,7 +908,12 @@ pic16_allocDirReg (operand *op ) // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name); // addSet(&pic16_dynDirectRegs, reg); - checkAddReg(&pic16_dynDirectRegs, reg); +#if 1 + if(!(IS_STATIC(OP_SYM_ETYPE(op)) + && OP_SYMBOL(op)->ival + )) +#endif + checkAddReg(&pic16_dynDirectRegs, reg); } } else { @@ -870,8 +927,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); @@ -903,7 +960,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); @@ -1053,6 +1110,33 @@ 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))); + + 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 */ /*-----------------------------------------------------------------*/ @@ -1734,7 +1818,9 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* check if there are any live ranges that not used in the remainder of the block */ - if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) + if (!_G.blockSpil && + !isiCodeInFunctionCall (ic) && + (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) { sym = leastUsedLR (selectS); if (!sym->remat) @@ -2178,14 +2264,12 @@ static void serialRegAssign (eBBlock ** ebbs, int count) { int i; - + iCode *ic; + debugLog ("%s\n", __FUNCTION__); /* for all blocks */ for (i = 0; i < count; i++) { - - iCode *ic; - if (ebbs[i]->noPath && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel)) @@ -2195,7 +2279,7 @@ serialRegAssign (eBBlock ** ebbs, int count) for (ic = ebbs[i]->sch; ic; ic = ic->next) { - debugLog (" op: %s\n", decodeOp (ic->op)); + debugLog (" op: %s\n", pic16_decodeOp (ic->op)); if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic))) pic16_allocDirReg(IC_RESULT(ic)); @@ -2239,6 +2323,13 @@ serialRegAssign (eBBlock ** ebbs, int count) int j; int ptrRegSet = 0; + /* Make sure any spill location is definately allocated */ + if (sym->isspilt && !sym->remat && sym->usl.spillLoc && + !sym->usl.spillLoc->allocreq) + { + sym->usl.spillLoc->allocreq++; + } + /* if it does not need or is spilt or is already assigned to registers or will not live beyond this instructions */ @@ -2261,6 +2352,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))) @@ -2276,12 +2371,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) { @@ -2308,9 +2404,22 @@ serialRegAssign (eBBlock ** ebbs, int count) if (ic->op == RECEIVE) debugLog ("When I get clever, I'll optimize the receive logic\n"); + if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic)))) + && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1) + && (ic->next->op == IFX) + && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) { + + /* skip register allocation since none will be used */ + for(j=0;jnRegs;j++) + sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL); +// OP_SYMBOL(IC_RESULT(ic))->nRegs = 0; + + continue; + } + /* if we need ptr regs for the right side then mark it */ - if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) + if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned) PTRSIZE) { pic16_ptrRegReq++; @@ -2319,7 +2428,6 @@ serialRegAssign (eBBlock ** ebbs, int count) /* else we assign registers to it */ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); - debugLog (" %d - nRegs: %d\n", __LINE__, sym->nRegs); if(debugF) bitVectDebugOn(_G.regAssigned, debugF); @@ -2672,7 +2780,6 @@ regTypeNum () if (IS_AGGREGATE (sym->type) || sym->isptr) sym->type = aggrToPtr (sym->type, FALSE); debugLog (" %d - no reg needed - used as a return\n", __LINE__); - continue; } @@ -2750,6 +2857,7 @@ regTypeNum () /* registers for true symbols we will */ /* see how things go */ sym->nRegs = 0; + } } @@ -2872,17 +2980,36 @@ 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__); - debugLog ("ic->op = %s\n", decodeOp( ic->op ) ); + debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) ); debugAopGet (" result:", IC_RESULT (ic)); debugAopGet (" left:", IC_LEFT (ic)); debugAopGet (" right:", IC_RIGHT (ic)); @@ -2896,10 +3023,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) debugLog (" %d - result is not temp\n", __LINE__); } +// if(IS_VALOP(IC_RIGHT(ic)))return 0; /* See BUGLOG0001 - VR */ #if 1 - if (!IS_ITEMP (IC_RIGHT (ic))) { + if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) { debugLog (" %d - not packing - right is not temp\n", __LINE__); pic16_allocDirReg(IC_RIGHT (ic)); return 0; @@ -3050,34 +3178,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 @@ -3266,11 +3395,17 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) 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 @@ -3279,10 +3414,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) @@ -3311,6 +3454,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) } dic = dic->next; } + else + { /* otherwise check that the definition does @@ -3332,6 +3477,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; @@ -3362,7 +3508,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 */ @@ -3594,20 +3740,16 @@ packForReceive (iCode * ic, eBBlock * ebp) for (dic = ic->next; dic; dic = dic->next) { - - - if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) - debugLog (" used on left\n"); + debugLog (" used on left\n"); if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key) - debugLog (" used on right\n"); + debugLog (" used on right\n"); if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key) - debugLog (" used on result\n"); + debugLog (" used on result\n"); if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) || - (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)) + (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)) return; - } debugLog (" hey we can remove this unnecessary assign\n"); @@ -3619,11 +3761,22 @@ static void packForPush (iCode * ic, eBBlock * ebp) { iCode *dic; - + debugLog ("%s\n", __FUNCTION__); if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic))) return; +#if 0 + { + int n1, n2; + + n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic))); + n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic))); + debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic)); + debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic))); + } +#endif + /* must have only definition & one usage */ if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 || bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1) @@ -3634,12 +3787,26 @@ packForPush (iCode * ic, eBBlock * ebp) bitVectFirstBit (OP_DEFS (IC_LEFT (ic)))))) return; + /* if definition is not assignment, + * or is not pointer (because pointer might have changed) */ if (dic->op != '=' || POINTER_SET (dic)) return; + /* we must ensure that we can use the delete the assignment, + * because the source might have been modified in between. + * Until I know how to fix this, I'll use the adhoc fix + * to check the liveranges */ + if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0)) + return; +// debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic))); + + + /* we now we know that it has one & only one def & use and the that the definition is an assignment */ IC_LEFT (ic) = IC_RIGHT (dic); + + debugf("remiCodeFromeBBlock: %s\n", printILine(dic)); remiCodeFromeBBlock (ebp, dic); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); @@ -3664,33 +3831,32 @@ static void isData(sym_link *sl) { FILE *of = stderr; - if(!pic16_ralloc_debug)return; - - if(!sl)return; - - if(debugF) - of = debugF; - - for ( ; sl; sl=sl->next) { - if(!IS_DECL(sl) ) { - switch (SPEC_SCLS(sl)) { - case S_DATA: fprintf (of, "data "); break; - case S_XDATA: fprintf (of, "xdata "); break; - case S_SFR: fprintf (of, "sfr "); break; - case S_SBIT: fprintf (of, "sbit "); break; - case S_CODE: fprintf (of, "code "); break; - case S_IDATA: fprintf (of, "idata "); break; - case S_PDATA: fprintf (of, "pdata "); break; - case S_LITERAL: fprintf (of, "literal "); break; - case S_STACK: fprintf (of, "stack "); break; - case S_XSTACK: fprintf (of, "xstack "); break; - case S_BIT: fprintf (of, "bit "); break; - case S_EEPROM: fprintf (of, "eeprom "); break; - default: break; - } - - } - } + if(!pic16_ralloc_debug)return; + + if(!sl)return; + + if(debugF) + of = debugF; + + for ( ; sl; sl=sl->next) { + if(!IS_DECL(sl) ) { + switch (SPEC_SCLS(sl)) { + case S_DATA: fprintf (of, "data "); break; + case S_XDATA: fprintf (of, "xdata "); break; + case S_SFR: fprintf (of, "sfr "); break; + case S_SBIT: fprintf (of, "sbit "); break; + case S_CODE: fprintf (of, "code "); break; + case S_IDATA: fprintf (of, "idata "); break; + case S_PDATA: fprintf (of, "pdata "); break; + case S_LITERAL: fprintf (of, "literal "); break; + case S_STACK: fprintf (of, "stack "); break; + case S_XSTACK: fprintf (of, "xstack "); break; + case S_BIT: fprintf (of, "bit "); break; + case S_EEPROM: fprintf (of, "eeprom "); break; + default: break; + } + } + } } @@ -3719,8 +3885,6 @@ pic16_packRegisters (eBBlock * ebp) { // debugLog("%d\n", __LINE__); /* find assignment of the form TrueSym := iTempNN:1 */ - /* see BUGLOG0001 for workaround with the CAST - VR */ -// if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11 change += packRegsForAssign (ic, ebp); /* debug stuff */ @@ -3792,9 +3956,45 @@ pic16_packRegisters (eBBlock * ebp) if (POINTER_SET (ic)) - debugLog (" %d - Pointer set\n", __LINE__); - + debugLog (" %d - Pointer set\n", __LINE__); + + /* Look for two subsequent iCodes with */ + /* iTemp := _c; */ + /* _c = iTemp & op; */ + /* and replace them by */ + /* iTemp := _c; */ + /* _c = _c & op; */ + if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') + && ic->prev + && ic->prev->op == '=' + && IS_ITEMP (IC_LEFT (ic)) + && IC_LEFT (ic) == IC_RESULT (ic->prev) + && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev))) + { + iCode* ic_prev = ic->prev; + symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev)); + + ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic)); + if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) { + bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key); + if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */ + prev_result_sym->liveTo == ic->seq) + { + prev_result_sym->liveTo = ic_prev->seq; + } + } + bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); + + bitVectSetBit (ic->rlive, IC_RESULT (ic)->key); + if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) { + bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key); + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key); + remiCodeFromeBBlock (ebp, ic_prev); + hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL); + } + } + /* if this is an itemp & result of a address of a true sym then mark this as rematerialisable */ if (ic->op == ADDRESS_OF && @@ -3845,18 +4045,91 @@ pic16_packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; } + +#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 */ + + 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; + } + } +#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)) { - OP_SYMBOL (IC_LEFT (ic))->uptr = 1; - debugLog (" marking as a pointer (get) =>"); - debugAopGet (" left:", IC_LEFT (ic)); + if(IS_SYMOP(IC_LEFT(ic))) { + OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + 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__); @@ -4013,6 +4286,12 @@ pic16_packRegisters (eBBlock * ebp) } } #endif + +#if 1 + /* there are some problems with packing variables + * it seems that the live range estimator doesn't + * estimate correctly the liveranges of some symbols */ + /* pack for PUSH iTempNN := (some variable in farspace) V1 push iTempNN ; @@ -4023,7 +4302,7 @@ pic16_packRegisters (eBBlock * ebp) { packForPush (ic, ebp); } - +#endif #ifndef NO_packRegsForAccUse /* pack registers for accumulator use, when the @@ -4097,8 +4376,10 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) /* 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; @@ -4106,6 +4387,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) debugLog ("\nebbs before optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 1; + setToNull ((void *) &_G.funcrUsed); pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; @@ -4136,18 +4419,22 @@ 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; + /* and serially allocate registers */ serialRegAssign (ebbs, count); -// debugLog ("ebbs after serialRegAssign:\n"); -// dumpEbbsToDebug (ebbs, count); - +#if 0 + debugLog ("ebbs after serialRegAssign:\n"); + dumpEbbsToDebug (ebbs, count); +#endif //pic16_freeAllRegs(); @@ -4174,7 +4461,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) redoStackOffsets (); if (options.dump_rassgn) - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); @@ -4182,6 +4469,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) debugLog ("ebbs after optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 0; genpic16Code (ic); @@ -4193,6 +4481,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* mark all registers as free */ pic16_freeAllRegs (); + debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n"); debugLogClose (); return;