X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=b6ee9a423ff44a25472ca89049bbde0e5687f6c3;hb=74cc47c04fa325773b214f28ff1d0ecfe4d5205d;hp=1bc23245e1277e97f4a46c536dd9528ebcce87b6;hpb=cb05bc2dfa7f8217c5b99e1ecd369e331927057e;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 1bc23245..b6ee9a42 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -37,6 +37,7 @@ /*-----------------------------------------------------------------*/ extern void gen51Code (iCode *); +#define D(x) /* Global data */ static struct @@ -44,6 +45,7 @@ static struct bitVect *spiltSet; set *stackSpil; bitVect *regAssigned; + bitVect *totRegAssigned; /* final set of LRs that got into registers */ short blockSpil; int slocNum; bitVect *funcrUsed; /* registers used in a function */ @@ -76,6 +78,7 @@ regs regs8051[] = }; int mcs51_nRegs = 13; static void spillThis (symbol *); +static void freeAllRegs (); /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ @@ -179,6 +182,14 @@ nfreeRegsType (int type) return nFreeRegs (type); } +/*-----------------------------------------------------------------*/ +/* useReg - marks a register as used */ +/*-----------------------------------------------------------------*/ +static void +useReg (regs * reg) +{ + reg->isFree = 0; +} /*-----------------------------------------------------------------*/ /* allDefsOutOfRange - all definitions are out of a range */ @@ -393,11 +404,7 @@ noOverLap (set * itmpStack, symbol * fsym) for (sym = setFirstItem (itmpStack); sym; sym = setNextItem (itmpStack)) { - if (sym->liveFrom < fsym->liveTo && - sym->liveTo > fsym->liveTo) return 0; - - if (sym->liveFrom < fsym->liveFrom && - sym->liveTo > fsym->liveFrom) return 0; + if (bitVectBitValue(sym->clashes,fsym->key)) return 0; } return 1; @@ -517,6 +524,8 @@ createStackSpil (symbol * sym) sloc->etype = getSpec (sloc->type); SPEC_SCLS (sloc->etype) = S_DATA; SPEC_EXTR (sloc->etype) = 0; + SPEC_STAT (sloc->etype) = 0; + SPEC_VOLATILE(sloc->etype) = 0; /* we don't allow it to be allocated` onto the external stack since : so we @@ -600,10 +609,11 @@ spillThis (symbol * sym) /* mark it has spilt & put it in the spilt set */ - sym->isspilt = 1; + sym->isspilt = sym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key); bitVectUnSetBit (_G.regAssigned, sym->key); + bitVectUnSetBit (_G.totRegAssigned, sym->key); for (i = 0; i < sym->nRegs; i++) @@ -623,7 +633,7 @@ spillThis (symbol * sym) } if (sym->usl.spillLoc && !sym->remat) - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return; } @@ -657,7 +667,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym->usl.spillLoc->name)); sym->spildir = 1; /* mark it as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -702,7 +712,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym = leastUsedLR (selectS); /* mark this as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -711,7 +721,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) { sym = leastUsedLR (selectS); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -723,7 +733,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* return a created spil location */ sym = createStackSpil (leastUsedLR (selectS)); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -747,12 +757,13 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) ssym = selectSpil (ic, ebp, forSym); /* mark it as spilt */ - ssym->isspilt = 1; + ssym->isspilt = ssym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key); /* mark it as not register assigned & take it away from the set */ bitVectUnSetBit (_G.regAssigned, ssym->key); + bitVectUnSetBit (_G.totRegAssigned, ssym->key); /* mark the registers as free */ for (i = 0; i < ssym->nRegs; i++) @@ -853,6 +864,41 @@ tryAgain: goto tryAgain; } +/*-----------------------------------------------------------------*/ +/* getRegPtrNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegPtrNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_PTR))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); +} + +/*-----------------------------------------------------------------*/ +/* getRegGprNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegGprNoSpil() +{ + + regs *reg; + if ((reg = allocReg (REG_GPR))) + return reg; + + if (!mcs51_ptrRegReq) + if ((reg = allocReg (REG_PTR))) + return reg; + + assert(0); +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -952,6 +998,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) result->regs[i] = getRegGpr (ic, ebp, result); _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key); } @@ -981,10 +1028,11 @@ reassignLR (operand * op) int i; /* not spilt any more */ - sym->isspilt = sym->blockSpil = sym->remainSpil = 0; + sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0; bitVectUnSetBit (_G.spiltSet, sym->key); _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); _G.blockSpil--; @@ -1034,15 +1082,16 @@ willCauseSpill (int nr, int rt) /* ult and operand, if this happens make sure they are in the same */ /* position as the operand otherwise chaos results */ /*-----------------------------------------------------------------*/ -static void -positionRegs (symbol * result, symbol * opsym, int lineno) +static int +positionRegs (symbol * result, symbol * opsym) { int count = min (result->nRegs, opsym->nRegs); int i, j = 0, shared = 0; + int change = 0; /* if the result has been spilt then cannot share */ if (opsym->isspilt) - return; + return 0; again: shared = 0; /* first make sure that they actually share */ @@ -1063,8 +1112,10 @@ xchgPositions: regs *tmp = result->regs[i]; result->regs[i] = result->regs[j]; result->regs[j] = tmp; + change ++; goto again; } + return change; } /*-----------------------------------------------------------------*/ @@ -1096,7 +1147,7 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if result is present && is a true symbol */ if (IC_RESULT (ic) && ic->op != IFX && IS_TRUE_SYMOP (IC_RESULT (ic))) - OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; + OP_SYMBOL (IC_RESULT (ic))->allocreq++; /* take away registers from live ranges that end at this instruction */ @@ -1161,8 +1212,11 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if none of the liveRanges have a spillLocation then better to spill this one than anything else already assigned to registers */ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) { - spillThis (sym); - continue; + /* if this is local to this block then we might find a block spil */ + if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) { + spillThis (sym); + continue; + } } } } @@ -1175,6 +1229,7 @@ serialRegAssign (eBBlock ** ebbs, int count) } /* else we assign registers to it */ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); for (j = 0; j < sym->nRegs; j++) { if (sym->regType == REG_PTR) @@ -1182,10 +1237,15 @@ serialRegAssign (eBBlock ** ebbs, int count) else sym->regs[j] = getRegGpr (ic, ebbs[i], sym); - /* if the allocation falied which means + /* if the allocation failed which means this was spilt then break */ - if (!sym->regs[j]) - break; + if (!sym->regs[j]) { + if (j) { + fprintf (stderr, "%d reg(s) lost in %s:%d\n", + j, __FILE__,__LINE__); + } + break; + } } /* if it shares registers with operands make sure @@ -1193,13 +1253,13 @@ serialRegAssign (eBBlock ** ebbs, int count) if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') { positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_LEFT (ic)), ic->lineno); + OP_SYMBOL (IC_LEFT (ic))); } /* do the same for the right operand */ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->nRegs) { positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_RIGHT (ic)), ic->lineno); + OP_SYMBOL (IC_RIGHT (ic))); } if (ptrRegSet) { @@ -1212,11 +1272,118 @@ serialRegAssign (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* fillGaps - Try to fill in the Gaps left by Pass1 */ +/*-----------------------------------------------------------------*/ +static void fillGaps() +{ + symbol *sym =NULL; + int key =0; + + if (getenv("DISABLE_FILL_GAPS")) return; + + /* look for livernages that was spilt by the allocator */ + for (sym = hTabFirstItem(liveRanges,&key) ; sym ; + sym = hTabNextItem(liveRanges,&key)) { + + int i; + int pdone = 0; + + if (!sym->spillA || !sym->clashes || sym->remat) continue ; + + /* find the liveRanges this one clashes with, that are + still assigned to registers & mark the registers as used*/ + for ( i = 0 ; i < sym->clashes->size ; i ++) { + int k; + symbol *clr; + + if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ + bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ + continue ; + + assert (clr = hTabItemWithKey(liveRanges,i)); + + /* mark these registers as used */ + for (k = 0 ; k < clr->nRegs ; k++ ) + useReg(clr->regs[k]); + } + + if (willCauseSpill(sym->nRegs,sym->regType)) { + /* NOPE :( clear all registers & and continue */ + freeAllRegs(); + continue ; + } + + /* THERE IS HOPE !!!! */ + for (i=0; i < sym->nRegs ; i++ ) { + if (sym->regType == REG_PTR) + sym->regs[i] = getRegPtrNoSpil (); + else + sym->regs[i] = getRegGprNoSpil (); + } + + /* for all its definitions check if the registers + allocated needs positioning NOTE: we can position + only ONCE if more than One positioning required + then give up */ + sym->isspilt = 0; + for (i = 0 ; i < sym->defs->size ; i++ ) { + if (bitVectBitValue(sym->defs,i)) { + iCode *ic; + if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; + if (SKIP_IC(ic)) continue; + assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */ + /* if left is assigned to registers */ + if (IS_SYMOP(IC_LEFT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) { + pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic))); + } + if (IS_SYMOP(IC_RIGHT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { + pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic))); + } + if (pdone > 1) break; + } + } + for (i = 0 ; i < sym->uses->size ; i++ ) { + if (bitVectBitValue(sym->uses,i)) { + iCode *ic; + if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; + if (SKIP_IC(ic)) continue; + if (!IS_ASSIGN_ICODE(ic)) continue ; + + /* if result is assigned to registers */ + if (IS_SYMOP(IC_RESULT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) { + pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic))); + } + if (pdone > 1) break; + } + } + /* had to position more than once GIVE UP */ + if (pdone > 1) { + /* UNDO all the changes we made to try this */ + sym->isspilt = 1; + for (i=0; i < sym->nRegs ; i++ ) { + sym->regs[i] = NULL; + } + freeAllRegs(); + D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); + continue ; + } + D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); + _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); + sym->isspilt = sym->spillA = 0 ; + sym->usl.spillLoc->allocreq--; + freeAllRegs(); + } +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ -static bitVect * -rUmaskForOp (operand * op) +bitVect * +mcs51_rUmaskForOp (operand * op) { bitVect *rumask; symbol *sym; @@ -1256,7 +1423,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == IFX) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_COND (ic))); + mcs51_rUmaskForOp (IC_COND (ic))); goto ret; } @@ -1264,7 +1431,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == JUMPTABLE) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_JTCOND (ic))); + mcs51_rUmaskForOp (IC_JTCOND (ic))); goto ret; } @@ -1272,16 +1439,16 @@ regsUsedIniCode (iCode * ic) /* of all other cases */ if (IC_LEFT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_LEFT (ic))); + mcs51_rUmaskForOp (IC_LEFT (ic))); if (IC_RIGHT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RIGHT (ic))); + mcs51_rUmaskForOp (IC_RIGHT (ic))); if (IC_RESULT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RESULT (ic))); + mcs51_rUmaskForOp (IC_RESULT (ic))); ret: return rmask; @@ -1378,6 +1545,11 @@ rematStr (symbol * sym) continue; } + /* cast then continue */ + if (IS_CAST_ICODE(ic)) { + ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode; + continue; + } /* we reached the end */ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname); break; @@ -1390,7 +1562,7 @@ rematStr (symbol * sym) /* regTypeNum - computes the type & number of registers required */ /*-----------------------------------------------------------------*/ static void -regTypeNum () +regTypeNum (eBBlock *ebbs) { symbol *sym; int k; @@ -1432,15 +1604,16 @@ regTypeNum () (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) && POINTER_GET (ic) && + !sym->noSpilLoc && !IS_BITVAR (sym->etype)) { /* if remat in data space */ if (OP_SYMBOL (IC_LEFT (ic))->remat && + !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) && DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) { - /* create a psuedo symbol & force a spil */ symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); psym->type = sym->type; @@ -1448,6 +1621,16 @@ regTypeNum () strcpy (psym->rname, psym->name); sym->isspilt = 1; sym->usl.spillLoc = psym; +#if 0 // an alternative fix for bug #480076 + /* now this is a useless assignment to itself */ + remiCodeFromeBBlock (ebbs, ic); +#else + /* now this really is an assignment to itself, make it so; + it will be optimized out later */ + ic->op='='; + IC_RIGHT(ic)=IC_RESULT(ic); + IC_LEFT(ic)=NULL; +#endif continue; } @@ -1583,55 +1766,33 @@ static int packRegsForAssign (iCode * ic, eBBlock * ebp) { iCode *dic, *sic; - sym_link *etype = operandType (IC_RIGHT (ic)); + //sym_link *etype = operandType (IC_RIGHT (ic)); if (!IS_ITEMP (IC_RIGHT (ic)) || OP_SYMBOL (IC_RIGHT (ic))->isind || - OP_LIVETO (IC_RIGHT (ic)) > ic->seq || - IS_BITFIELD (etype)) + OP_LIVETO (IC_RIGHT (ic)) > ic->seq + /* why? || IS_BITFIELD (etype) */ ) { return 0; } /* if the true symbol is defined in far space or on stack then we should not since this will increase register pressure */ -#if 0 - if (isOperandInFarSpace (IC_RESULT (ic))) - { - if ((dic = farSpacePackable (ic))) - goto pack; - else - return 0; - } -#else if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) { return 0; } -#endif /* find the definition of iTempNN scanning backwards if we find a a use of the true symbol in before we find the definition then we cannot */ for (dic = ic->prev; dic; dic = dic->prev) { -#if 0 // jwk 20010410 - /* if there is a function call and this is - a parameter & not my parameter then don't pack it */ - if ((dic->op == CALL || dic->op == PCALL) && - (OP_SYMBOL (IC_RESULT (ic))->_isparm && - !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) - { - dic = NULL; - break; - } -#else /* if there is a function call then don't pack it */ if ((dic->op == CALL || dic->op == PCALL)) { dic = NULL; break; } -#endif if (SKIP_IC2 (dic)) continue; @@ -1708,6 +1869,7 @@ 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) @@ -1725,6 +1887,7 @@ pack: } remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; @@ -1754,9 +1917,9 @@ findAssignToSym (operand * op, iCode * ic) /* or in stack space in case of + & - */ /* if assigned to a non-symbol then return - true */ + FALSE */ if (!IS_SYMOP (IC_RIGHT (dic))) - break; + return NULL; /* if the symbol is in far space then we should not */ @@ -1815,6 +1978,8 @@ static int packRegsForSupport (iCode * ic, eBBlock * ebp) { int change = 0; + iCode *dic, *sic; + /* for the left & right operand :- look to see if the left was assigned a true symbol in far space in that case replace them */ @@ -1822,21 +1987,23 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) if (IS_ITEMP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq) { - iCode *dic = findAssignToSym (IC_LEFT (ic), ic); - iCode *sic; + dic = findAssignToSym (IC_LEFT (ic), ic); if (!dic) goto right; /* found it we need to remove it from the block */ - for (sic = dic; sic != ic; sic = sic->next) + for (sic = dic; sic != ic; sic = sic->next) { bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key); + sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key); + } - IC_LEFT (ic)->operand.symOperand = - IC_RIGHT (dic)->operand.symOperand; - IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; + OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic)); + OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq; + IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key; remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; } @@ -1863,14 +2030,18 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) } /* found it we need to remove it from the block */ - for (sic = dic; sic != ic; sic = sic->next) + for (sic = dic; sic != ic; sic = sic->next) { bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key); + sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key); + } IC_RIGHT (ic)->operand.symOperand = IC_RIGHT (dic)->operand.symOperand; + OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq; IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; } @@ -1896,13 +2067,15 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) && - ic->op != RETURN && + if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2)) + return NULL; + + if (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 instruction use only && if the defintion is local (ie. within the basic block) && has only one definition && @@ -1924,6 +2097,16 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) bitVectFirstBit (OP_DEFS (op))))) return NULL; + /* if that only usage is a cast */ + if (dic->op == CAST) { + /* to a bigger type */ + if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > + getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) { + /* than we can not, since we cannot predict the usage of b & acc */ + return NULL; + } + } + /* found the definition now check if it is local */ if (dic->seq < ebp->fSeq || dic->seq > ebp->lSeq) @@ -1933,7 +2116,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) a function call */ if (dic->op == CALL || dic->op == PCALL) { - if (ic->op != SEND && ic->op != RETURN) + if (ic->op != SEND && ic->op != RETURN && + !POINTER_SET(ic) && !POINTER_GET(ic)) { OP_SYMBOL (op)->ruonly = 1; return dic; @@ -2054,6 +2238,11 @@ packRegsForAccUse (iCode * ic) { iCode *uic; + /* if this is an aggregate, e.g. a one byte char array */ + if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) { + return; + } + /* if + or - then it has to be one byte result */ if ((ic->op == '+' || ic->op == '-') && getSize (operandType (IC_RESULT (ic))) > 1) @@ -2129,9 +2318,14 @@ packRegsForAccUse (iCode * ic) /* make sure that the result of this icode is not on the stack, since acc is used to compute stack offset */ +#if 0 if (IS_TRUE_SYMOP (IC_RESULT (uic)) && OP_SYMBOL (IC_RESULT (uic))->onStack) return; +#else + if (isOperandOnStack(IC_RESULT(uic))) + return; +#endif /* if either one of them in far space then we cannot */ if ((IS_TRUE_SYMOP (IC_LEFT (uic)) && @@ -2151,6 +2345,10 @@ packRegsForAccUse (iCode * ic) IC_LEFT (uic)->key != IC_RESULT (ic)->key) return; +#if 0 + // this is too dangerous and need further restrictions + // see bug #447547 + /* if one of them is a literal then we can */ if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) || (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) @@ -2158,6 +2356,7 @@ packRegsForAccUse (iCode * ic) OP_SYMBOL (IC_RESULT (ic))->accuse = 1; return; } +#endif /* if the other one is not on stack then we can */ if (IC_LEFT (uic)->key == IC_RESULT (ic)->key && @@ -2230,6 +2429,7 @@ packForPush (iCode * ic, eBBlock * ebp) IC_LEFT (ic) = IC_RIGHT (dic); remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); } @@ -2286,6 +2486,7 @@ packRegisters (eBBlock * ebp) !POINTER_SET (ic) && IS_SYMOP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->remat && + !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) && bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) { @@ -2295,22 +2496,34 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RIGHT (ic))->rematiCode; } + /* if cast to a generic pointer & the pointer being + cast is remat, then we can remat this cast as well */ + if (ic->op == CAST && + IS_SYMOP(IC_RIGHT(ic)) && + OP_SYMBOL(IC_RIGHT(ic))->remat ) { + sym_link *to_type = operandType(IC_LEFT(ic)); + sym_link *from_type = operandType(IC_RIGHT(ic)); + if (IS_GENPTR(to_type) && IS_PTR(from_type)) { + OP_SYMBOL (IC_RESULT (ic))->remat = 1; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + } + } + /* if this is a +/- operation with a rematerizable then mark this as rematerializable as well */ -#if 0 - // jwk 20010716: temporary disabled because of bug #441448 if ((ic->op == '+' || ic->op == '-') && (IS_SYMOP (IC_LEFT (ic)) && IS_ITEMP (IC_RESULT (ic)) && + IS_OP_LITERAL (IC_RIGHT (ic))) && OP_SYMBOL (IC_LEFT (ic))->remat && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - IS_OP_LITERAL (IC_RIGHT (ic)))) + (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) { OP_SYMBOL (IC_RESULT (ic))->remat = 1; OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; } -#endif /* mark the pointer usages */ if (POINTER_SET (ic)) @@ -2343,20 +2556,6 @@ packRegisters (eBBlock * ebp) } } -#if 0 - /* if the condition of an if instruction - is defined in the previous instruction then - mark the itemp as a conditional */ - if ((IS_CONDITIONAL (ic) || - (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) && - ic->next && ic->next->op == IFX && - isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && - OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) - { - OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; - continue; - } -#else /* if the condition of an if instruction is defined in the previous instruction and this is the only usage then @@ -2371,7 +2570,6 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; continue; } -#endif /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') @@ -2430,8 +2628,10 @@ packRegisters (eBBlock * ebp) { if (IS_ARITHMETIC_OP (dic)) { + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); ic = ic->prev; @@ -2451,8 +2651,10 @@ packRegisters (eBBlock * ebp) iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); if (dic) { + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); ic = ic->prev; @@ -2482,8 +2684,9 @@ packRegisters (eBBlock * ebp) we can leave the result of this operation in acc:b combination */ if ((IS_ARITHMETIC_OP (ic) + || IS_CONDITIONAL(ic) || IS_BITWISE_OP (ic) - || ic->op == LEFT_OP || ic->op == RIGHT_OP + || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic))) ) && IS_ITEMP (IC_RESULT (ic)) && @@ -2503,6 +2706,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) int i; setToNull ((void *) &_G.funcrUsed); + setToNull ((void *) &_G.totRegAssigned); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; mcs51_nRegs = 8; @@ -2516,11 +2720,14 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) /* first determine for each live range the number of registers & the type of registers required for each */ - regTypeNum (); + regTypeNum (*ebbs); /* and serially allocate registers */ serialRegAssign (ebbs, count); + freeAllRegs (); + fillGaps(); + /* if stack was extended then tell the user */ if (_G.stackExtend) {