X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=ec01a64642e23b935a55a847a41fa9527828b4a5;hb=0892d3692ded8c67ab4df6b26f603bb8d243e39d;hp=c81c2158f936d2bedde3858c3a8e060df9f9ac66;hpb=cd81e1479c7ce38b89e5622cfc1101cef3e07ebd;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index c81c2158..ec01a646 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -121,6 +121,23 @@ allocReg (short type) return NULL; } +/*-----------------------------------------------------------------*/ +/* allocThisReg - allocates a particular register (if free) */ +/*-----------------------------------------------------------------*/ +static regs * +allocThisReg (regs * reg) +{ + if (!reg->isFree) + return NULL; + + reg->isFree = 0; + if (currFunc) + currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx); + + return reg; +} + + /*-----------------------------------------------------------------*/ /* mcs51_regWithIdx - returns pointer to register wit index number */ /*-----------------------------------------------------------------*/ @@ -964,6 +981,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */ result->liveTo > ic->seq && /* and will live beyond this */ result->liveTo <= ebp->lSeq && /* does not go beyond this block */ + result->liveFrom == ic->seq && /* does not start before here */ result->regType == sym->regType && /* same register types */ result->nRegs && /* which needs registers */ !result->isspilt && /* and does not already have them */ @@ -1162,7 +1180,6 @@ serialRegAssign (eBBlock ** ebbs, int count) } } #endif - /* if this is an ipop that means some live range will have to be assigned again */ if (ic->op == IPOP) @@ -1221,6 +1238,16 @@ serialRegAssign (eBBlock ** ebbs, int count) spillThis (sym); continue; } + + /* If the live range preceeds the point of definition + then ideally we must take into account registers that + 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 (sym->liveFrom < ic->seq) { + spillThis (sym); + continue; + } /* if it has a spillocation & is used less than all other live ranges then spill this */ @@ -1267,18 +1294,32 @@ serialRegAssign (eBBlock ** ebbs, int count) _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); for (j = 0; j < sym->nRegs; j++) { + sym->regs[j] = NULL; if (sym->regType == REG_PTR) sym->regs[j] = getRegPtr (ic, ebbs[i], sym); else - sym->regs[j] = getRegGpr (ic, ebbs[i], sym); + { + if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); + + if (right->regs[j]) + sym->regs[j] = allocThisReg (right->regs[j]); + } + if (!sym->regs[j]) + sym->regs[j] = getRegGpr (ic, ebbs[i], sym); + } /* if the allocation failed which means this was spilt then break */ - if (!sym->regs[j]) { - break; - } + if (!sym->regs[j]) + { + for (i=0; i < sym->nRegs ; i++ ) + sym->regs[i] = NULL; + break; + } } - + if (!POINTER_SET(ic) && !POINTER_GET(ic)) { /* if it shares registers with operands make sure that they are in the same position */ @@ -1346,6 +1387,7 @@ static void fillGaps() symbol *sym =NULL; int key =0; int pass; + iCode *ic = NULL; if (getenv("DISABLE_FILL_GAPS")) return; @@ -1368,9 +1410,9 @@ static void fillGaps() bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ continue ; - clr = hTabItemWithKey(liveRanges,i); + clr = hTabItemWithKey(liveRanges,i); assert(clr); - + /* mark these registers as used */ for (k = 0 ; k < clr->nRegs ; k++ ) useReg(clr->regs[k]); @@ -1382,13 +1424,36 @@ static void fillGaps() continue ; } + ic = NULL; + for (i = 0 ; i < sym->defs->size ; i++ ) + { + if (bitVectBitValue(sym->defs,i)) + { + if (!(ic = hTabItemWithKey(iCodehTab,i))) + continue; + if (ic->op == CAST) + break; + } + } + D(printf("Atemping fillGaps on %s: [",sym->name)); /* THERE IS HOPE !!!! */ for (i=0; i < sym->nRegs ; i++ ) { if (sym->regType == REG_PTR) sym->regs[i] = getRegPtrNoSpil (); else - sym->regs[i] = getRegGprNoSpil (); + { + sym->regs[i] = NULL; + if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); + + if (right->regs[i]) + sym->regs[i] = allocThisReg (right->regs[i]); + } + if (!sym->regs[i]) + sym->regs[i] = getRegGprNoSpil (); + } D(printf("%s ", sym->regs[i]->name)); } D(printf("]\n")); @@ -1407,7 +1472,6 @@ static void fillGaps() D(printf(" checking definitions\n")); for (i = 0 ; i < sym->defs->size ; i++ ) { if (bitVectBitValue(sym->defs,i)) { - iCode *ic; if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; D(printf(" ic->seq = %d\n", ic->seq)); if (SKIP_IC(ic)) continue; @@ -1477,6 +1541,7 @@ static void fillGaps() 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--; @@ -1708,35 +1773,13 @@ regTypeNum (eBBlock *ebbs) (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) && POINTER_GET (ic) && - !sym->noSpilLoc && - !IS_BITVAR (sym->etype)) + !IS_BITVAR (sym->etype) && + (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) { - - /* and that pointer is remat in data space */ - if (IS_SYMOP (IC_LEFT (ic)) && - OP_SYMBOL (IC_LEFT (ic))->remat && - !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) && - DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER) + if (ptrPseudoSymSafe (sym, ic)) { - /* create a psuedo symbol & force a spil */ - symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); - psym->type = sym->type; - psym->etype = sym->etype; - - 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='='; - ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic)); - IC_LEFT(ic)=NULL; -#endif + ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic)))); continue; }