X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Favr%2Fralloc.c;h=512edc4fdf7f068101e6c1677cfac87a316ef301;hb=039830aac4fa9f1baeab120d07fadebc8a5b1b6c;hp=b3d2a81f7e5296e2a382333759fd79c1016a9447;hpb=9388b031d56edbb7a48626d6fb573d3a411f61fd;p=fw%2Fsdcc diff --git a/src/avr/ralloc.c b/src/avr/ralloc.c index b3d2a81f..512edc4f 100644 --- a/src/avr/ralloc.c +++ b/src/avr/ralloc.c @@ -56,37 +56,37 @@ int avr_ptrRegReq; /* pointer register required */ /* AVR registers */ regs regsAVR[] = { {REG_GPR|REG_PAIR, R0_IDX, REG_GPR|REG_PAIR, "r0", "r0", "", 0, 0, 0}, /* scratch */ - {REG_GPR, R1_IDX, REG_GPR , "r1", "r1", "", 0, 0, 0}, /* scratch */ + {REG_GPR, R1_IDX, REG_GPR , "r1", "r1", "", 0, 0, 0}, /* scratch */ {REG_GPR|REG_PAIR, R2_IDX, REG_GPR|REG_PAIR, "r2", "r2", "", 0, 1, 1}, /* gpr */ - {REG_GPR, R3_IDX, REG_GPR , "r3", "r3", "", 0, 1, 1}, /* gpr */ + {REG_GPR, R3_IDX, REG_GPR , "r3", "r3", "", 0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R4_IDX, REG_GPR|REG_PAIR, "r4", "r4", "", 0, 1, 1}, /* gpr */ - {REG_GPR, R5_IDX, REG_GPR , "r5", "r5", "", 0, 1, 1}, /* gpr */ + {REG_GPR, R5_IDX, REG_GPR , "r5", "r5", "", 0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R6_IDX, REG_GPR|REG_PAIR, "r6", "r6", "", 0, 1, 1}, /* gpr */ - {REG_GPR, R7_IDX, REG_GPR , "r7", "r7", "", 0, 1, 1}, /* gpr */ + {REG_GPR, R7_IDX, REG_GPR , "r7", "r7", "", 0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R8_IDX, REG_GPR|REG_PAIR, "r8", "r8", "", 0, 1, 1}, /* gpr */ - {REG_GPR, R9_IDX, REG_GPR , "r9", "r9", "", 0, 1, 1}, /* gpr */ + {REG_GPR, R9_IDX, REG_GPR , "r9", "r9", "", 0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R10_IDX,REG_GPR|REG_PAIR, "r10", "r10","",0, 1, 1}, /* gpr */ - {REG_GPR, R11_IDX,REG_GPR , "r11", "r11","",0, 1, 1}, /* gpr */ + {REG_GPR, R11_IDX,REG_GPR , "r11", "r11","",0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R12_IDX,REG_GPR|REG_PAIR, "r12", "r12","",0, 1, 1}, /* gpr */ - {REG_GPR, R13_IDX,REG_GPR , "r13", "r13","",0, 1, 1}, /* gpr */ + {REG_GPR, R13_IDX,REG_GPR , "r13", "r13","",0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R14_IDX,REG_GPR|REG_PAIR, "r14", "r14","",0, 1, 1}, /* gpr */ - {REG_GPR, R15_IDX,REG_GPR , "r15", "r15","",0, 1, 1}, /* gpr */ + {REG_GPR, R15_IDX,REG_GPR , "r15", "r15","",0, 1, 1}, /* gpr */ {REG_GPR|REG_PAIR, R16_IDX,REG_GPR|REG_PAIR, "r16", "r16","",0, 1, 0}, /* parm/gpr */ - {REG_GPR, R17_IDX,REG_GPR , "r17", "r17","",0, 1, 0}, /* parm/gpr */ + {REG_GPR, R17_IDX,REG_GPR , "r17", "r17","",0, 1, 0}, /* parm/gpr */ {REG_GPR|REG_PAIR, R18_IDX,REG_GPR|REG_PAIR, "r18", "r18","",0, 1, 0}, /* parm/gpr */ - {REG_GPR, R19_IDX,REG_GPR , "r19", "r19","",0, 1, 0}, /* parm/gpr */ + {REG_GPR, R19_IDX,REG_GPR , "r19", "r19","",0, 1, 0}, /* parm/gpr */ {REG_GPR|REG_PAIR, R20_IDX,REG_GPR|REG_PAIR, "r20", "r20","",0, 1, 0}, /* parm/gpr */ - {REG_GPR, R21_IDX,REG_GPR , "r21", "r21","",0, 1, 0}, /* parm/gpr */ + {REG_GPR, R21_IDX,REG_GPR , "r21", "r21","",0, 1, 0}, /* parm/gpr */ {REG_GPR|REG_PAIR, R22_IDX,REG_GPR|REG_PAIR, "r22", "r22","",0, 1, 0}, /* parm/gpr */ - {REG_GPR, R23_IDX,REG_GPR , "r23", "r23","",0, 1, 0}, /* parm/gpr */ + {REG_GPR, R23_IDX,REG_GPR , "r23", "r23","",0, 1, 0}, /* parm/gpr */ {REG_GPR|REG_PAIR, R24_IDX,REG_GPR|REG_PAIR, "r24", "r24","",0, 0, 0}, /* scratch */ - {REG_GPR, R25_IDX,REG_GPR , "r25", "r25","",0, 0, 0}, /* scratch */ + {REG_GPR, R25_IDX,REG_GPR , "r25", "r25","",0, 0, 0}, /* scratch */ {REG_GPR|REG_PAIR, R26_IDX,REG_GPR|REG_PAIR, "r26", "r26","",0, 1, 1}, /* used as pointer reg X */ - {REG_GPR, R27_IDX,REG_GPR , "r27", "r27","",0, 1, 1}, /* used as pointer reg X */ + {REG_GPR, R27_IDX,REG_GPR , "r27", "r27","",0, 1, 1}, /* used as pointer reg X */ {REG_GPR|REG_PAIR, R28_IDX,REG_GPR|REG_PAIR, "r28", "r28","",0, 1, 0}, /* stack frame Y */ - {REG_GPR, R29_IDX,REG_GPR , "r29", "r29","",0, 1, 0}, /* stack frame Y */ + {REG_GPR, R29_IDX,REG_GPR , "r29", "r29","",0, 1, 0}, /* stack frame Y */ {REG_GPR|REG_PAIR, R30_IDX,REG_GPR|REG_PAIR, "r30", "r30","",0, 1, 1}, /* used as pointer reg Z */ - {REG_GPR, R31_IDX,REG_GPR , "r31", "r31","",0, 1, 1}, /* used as pointer reg Z */ + {REG_GPR, R31_IDX,REG_GPR , "r31", "r31","",0, 1, 1}, /* used as pointer reg Z */ {REG_PTR, X_IDX, REG_PTR, "X", "X", "", 0, 1, 0}, {REG_PTR, Z_IDX, REG_PTR, "Z", "Z", "", 0, 1, 0}, }; @@ -549,31 +549,6 @@ nfreeRegsType (int type) return nFreeRegs (type); } - -/*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ -/*-----------------------------------------------------------------*/ -static bool -allDefsOutOfRange (bitVect * defs, int fseq, int toseq) -{ - int i; - - if (!defs) - return TRUE; - - for (i = 0; i < defs->size; i++) { - iCode *ic; - - if (bitVectBitValue (defs, i) && - (ic = hTabItemWithKey (iCodehTab, i)) && - (ic->seq >= fseq && ic->seq <= toseq)) - - return FALSE; - } - - return TRUE; -} - /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ /*-----------------------------------------------------------------*/ @@ -635,16 +610,6 @@ rematable (symbol * sym, eBBlock * ebp, iCode * ic) return sym->remat; } -/*-----------------------------------------------------------------*/ -/* notUsedInBlock - not used in this block */ -/*-----------------------------------------------------------------*/ -static int -notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic) -{ - return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) && - allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq)); -} - /*-----------------------------------------------------------------*/ /* notUsedInRemaining - not used or defined in remain of the block */ /*-----------------------------------------------------------------*/ @@ -727,7 +692,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } @@ -936,7 +901,8 @@ 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 = + !isiCodeInFunctionCall (ic) && + (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) { sym = leastUsedLR (selectS); if (sym != forSym) { @@ -1198,6 +1164,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 */ @@ -1339,10 +1306,10 @@ static int needsPair (iCode *ic) int ikey = bitVectFirstBit(uses_defs); iCode *uic = hTabItemWithKey(iCodehTab,ikey); sym_link *otype = NULL; + bitVectUnSetBit(uses_defs,ikey); if (!uic) continue; otype = (IC_RIGHT(uic) ? operandType(IC_RIGHT(uic)) : NULL); if (otype && IS_LITERAL(otype)) return 1; - bitVectUnSetBit(uses_defs,ikey); } return 0; } @@ -1398,6 +1365,12 @@ serialRegAssign (eBBlock ** ebbs, int count) int willCS; int j=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 */ @@ -1428,6 +1401,17 @@ serialRegAssign (eBBlock ** ebbs, int count) 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 */ if (willCS) { @@ -1617,11 +1601,12 @@ createRegMask (eBBlock ** ebbs, int count) /* for all the registers allocated to it */ for (k = 0; k < sym->nRegs; k++) { if (sym->regs[k]) { - ic->rMask = bitVectSetBit (ic-> rMask, sym->regs[k]->rIdx); + int rIdx = sym->regs[k]->rIdx; + ic->rMask = bitVectSetBit (ic-> rMask,rIdx); /* special case for X & Z registers */ - if (k == R26_IDX || k == R27_IDX) + if (rIdx == R26_IDX || rIdx == R27_IDX) ic->rMask = bitVectSetBit (ic->rMask, X_IDX); - if (k == R30_IDX || k == R31_IDX) + if (rIdx == R30_IDX || rIdx == R31_IDX) ic->rMask = bitVectSetBit (ic->rMask, Z_IDX); } } @@ -1844,8 +1829,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } -#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) - /*-----------------------------------------------------------------*/ /* packRegsForOneuse : - will reduce some registers for single Use */ @@ -1891,7 +1874,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* now check if it is the return from 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; } @@ -2073,8 +2057,11 @@ packRegisters (eBBlock * ebp) if (POINTER_SET (ic)) OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - if (POINTER_GET (ic)) + if (POINTER_GET (ic)) { OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + if (OP_SYMBOL (IC_LEFT(ic))->remat) + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + } /* if the condition of an if instruction is defined in the previous instruction then @@ -2218,8 +2205,8 @@ setDefaultRegs (eBBlock ** ebbs, int count) else { regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_PTR; regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_PTR; - regsAVR[R28_IDX].type = (regsAVR[R28_IDX].type & ~REG_MASK) | REG_PTR; - regsAVR[R29_IDX].type = (regsAVR[R29_IDX].type & ~REG_MASK) | REG_PTR; + regsAVR[R30_IDX].type = (regsAVR[R30_IDX].type & ~REG_MASK) | REG_PTR; + regsAVR[R31_IDX].type = (regsAVR[R31_IDX].type & ~REG_MASK) | REG_PTR; } /* registers 0-1 / 24-25 used as scratch */ @@ -2236,7 +2223,7 @@ setDefaultRegs (eBBlock ** ebbs, int count) regsAVR[i].type = (regsAVR[i].type & ~REG_MASK) | REG_SCR; regsAVR[i].isFree = 1; } - if (!currFunc->hasFcall) { + if (!IFFUNC_HASFCALL(currFunc->type)) { preAssignParms (ebbs[0]->sch); } /* Y - is not allocated (it is the stack frame) */ @@ -2247,8 +2234,10 @@ setDefaultRegs (eBBlock ** ebbs, int count) /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ void -avr_assignRegisters (eBBlock ** ebbs, int count) +avr_assignRegisters (ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; iCode *ic; int i; @@ -2260,8 +2249,12 @@ avr_assignRegisters (eBBlock ** ebbs, int count) for (i = 0; i < count; i++) packRegisters (ebbs[i]); + /* liveranges probably changed by register packing + so we compute them again */ + 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 */ @@ -2294,7 +2287,7 @@ avr_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)); @@ -2306,8 +2299,8 @@ avr_assignRegisters (eBBlock ** ebbs, int count) /* free up any _G.stackSpil locations allocated */ applyToSet (_G.stackSpil, deallocStackSpil); _G.slocNum = 0; - setToNull ((void **) &_G.stackSpil); - setToNull ((void **) &_G.spiltSet); + setToNull ((void *) &_G.stackSpil); + setToNull ((void *) &_G.spiltSet); /* mark all registers as free */ return;