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 */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
}
- setToNull ((void **) &sset);
+ setToNull ((void *) &sset);
sym->blockSpil = 0;
return sym;
}
/* 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) {
(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 */
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 */
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) {
/* 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);
}
}
}
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
/*-----------------------------------------------------------------*/
/* packRegsForOneuse : - will reduce some registers for single Use */
/* 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;
}
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) */
/* 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;
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 */
redoStackOffsets ();
if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, 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;