}
- setToNull ((void **) &sset);
+ setToNull ((void *) &sset);
sym->blockSpil = 0;
return sym;
}
/* of all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next) {
+#if 1
+ int reg;
+
+ // update the registers in use at the start of this icode
+ for (reg=0; reg<mcs51_nRegs; reg++) {
+ if (regs8051[reg].isFree) {
+ ic->riu &= ~(1<<regs8051[reg].offset);
+ } else {
+ ic->riu |= (1<<regs8051[reg].offset);
+ }
+ }
+#endif
/* if this is an ipop that means some live
range will have to be assigned again */
}
}
- /* if it shares registers with operands make sure
- that they are in the same position */
- 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)));
- }
- /* 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)));
- }
+ if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
+ /* if it shares registers with operands make sure
+ that they are in the same position */
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->nRegs) {
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ 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)));
+ }
+ }
if (ptrRegSet) {
mcs51_ptrRegReq--;
static void fillGaps()
{
symbol *sym =NULL;
- int key =0;
+ int key =0;
+ int pass;
if (getenv("DISABLE_FILL_GAPS")) return;
continue ;
}
+ 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 ();
+ D(printf("%s ", sym->regs[i]->name));
}
+ D(printf("]\n"));
- /* for all its definitions check if the registers
+ /* 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 */
+ then give up.
+ We may need to perform the checks twice; once to
+ position the registers as needed, the second to
+ verify any register repositioning is still
+ compatible.
+ */
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)));
+ for (pass=0; pass<2; pass++) {
+ 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;
+ assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+ /* if left is assigned to registers */
+ if (IS_SYMOP(IC_LEFT(ic)))
+ {
+ D(printf(" left = "));
+ D(printOperand(IC_LEFT(ic),NULL));
+ }
+ if (IS_SYMOP(IC_LEFT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)))
+ {
+ D(printf(" right = "));
+ D(printOperand(IC_RIGHT(ic),NULL));
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+ }
+ D(printf(" pdone = %d\n", pdone));
+ if (pdone > 1) break;
}
- 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)));
+ D(printf(" checking uses\n"));
+ for (i = 0 ; i < sym->uses->size ; i++ ) {
+ if (bitVectBitValue(sym->uses,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ D(printf(" ic->seq = %d\n", ic->seq));
+ if (SKIP_IC(ic)) continue;
+ if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
+
+ /* if result is assigned to registers */
+ if (IS_SYMOP(IC_RESULT(ic)))
+ {
+ D(printf(" result = "));
+ D(printOperand(IC_RESULT(ic),NULL));
+ }
+ if (IS_SYMOP(IC_RESULT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+ pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+ }
+ D(printf(" pdone = %d\n", pdone));
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
}
- }
+ if (pdone == 0) break; /* second pass only if regs repositioned */
+ if (pdone > 1) break;
+ }
+ D(printf(" sym->regs = ["));
+ for (i=0; i < sym->nRegs ; i++ )
+ D(printf("%s ", sym->regs[i]->name));
+ D(printf("]\n"));
/* had to position more than once GIVE UP */
if (pdone > 1) {
/* UNDO all the changes we made to try this */
if (sym->ruonly || sym->accuse)
{
if (IS_AGGREGATE (sym->type) || sym->isptr)
- sym->type = aggrToPtr (sym->type, FALSE);
+ sym->type = aggrToPtr (sym->type, FALSE);
continue;
}
-#ifdef RANGEHUNT
- /* if this symbol has only one usage and that is an assignment
- to a ruonly, we don't need registers */
- // if this symbol has only one def
- if (bitVectnBitsOn (sym->defs)==1) {
- printf ("sym: %s has only one usage", sym->name);
- // find that usage
- if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
- if (ic->op==CALL) {
- printf (" for a call ");
- // if this is only assigned to a ruonly
- if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
- if (ic->op=='=') {
- if (OP_SYMBOL(IC_RESULT(ic))->ruonly) {
- printf("regTypeNum: %s assigned to %s\n", \
- sym->name, OP_SYMBOL(IC_RESULT(ic))->name);
- }
- }
- }
- }
- }
- }
-#endif
-
/* if the symbol has only one definition &
that definition is a get_pointer */
if (bitVectnBitsOn (sym->defs) == 1 &&
/* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
+ 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)
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;
getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
return NULL;
- /* if any three is a true symbol in far space */
- if (IC_RESULT (dic) &&
- IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- isOperandInFarSpace (IC_RESULT (dic)))
- return NULL;
+ if (dic->op == IFX)
+ {
+ if (IC_COND (dic) &&
+ IS_TRUE_SYMOP (IC_COND (dic)) &&
+ isOperandInFarSpace (IC_COND (dic)))
+ return NULL;
+ }
+ else if (dic->op == JUMPTABLE)
+ {
+ if (IC_JTCOND (dic) &&
+ IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
+ isOperandInFarSpace (IC_JTCOND (dic)))
+ return NULL;
+ }
+ else
+ {
+ /* if any three is a true symbol in far space */
+ if (IC_RESULT (dic) &&
+ IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ isOperandInFarSpace (IC_RESULT (dic)))
+ return NULL;
- if (IC_RIGHT (dic) &&
- IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
- isOperandInFarSpace (IC_RIGHT (dic)) &&
- !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
- return NULL;
+ if (IC_RIGHT (dic) &&
+ IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+ isOperandInFarSpace (IC_RIGHT (dic)) &&
+ !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+ return NULL;
- if (IC_LEFT (dic) &&
- IS_TRUE_SYMOP (IC_LEFT (dic)) &&
- isOperandInFarSpace (IC_LEFT (dic)) &&
- !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
- return NULL;
+ if (IC_LEFT (dic) &&
+ IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+ isOperandInFarSpace (IC_LEFT (dic)) &&
+ !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+ return NULL;
+ }
if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
{
we cannot */
for (dic = ic->prev; dic; dic = dic->prev)
{
+
+#if 0 /* jwk: This collides with 1.43 but I really see no need for
+ this anymore. It fixes bug #716790 and substantially improves
+ redundant register usage around function calls.
+ */
+
/* 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;
- if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- IS_OP_VOLATILE (IC_RESULT (dic)))
- {
- dic = NULL;
- break;
- }
+ if (dic->op == IFX)
+ {
+ if (IS_SYMOP (IC_COND (dic)) &&
+ (IC_COND (dic)->key == IC_RESULT (ic)->key ||
+ IC_COND (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
+ }
+ else
+ {
+ if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ IS_OP_VOLATILE (IC_RESULT (dic)))
+ {
+ dic = NULL;
+ break;
+ }
- if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- if (POINTER_SET (dic))
- dic = NULL;
+ if (IS_SYMOP (IC_RESULT (dic)) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ if (POINTER_SET (dic))
+ dic = NULL;
- break;
- }
+ break;
+ }
- if (IS_SYMOP (IC_RIGHT (dic)) &&
- (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
- IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ if (IS_SYMOP (IC_RIGHT (dic)) &&
+ (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+ IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
- if (IS_SYMOP (IC_LEFT (dic)) &&
- (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
- IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ if (IS_SYMOP (IC_LEFT (dic)) &&
+ (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+ IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
- if (POINTER_SET (dic) &&
- IC_RESULT (dic)->key == IC_RESULT (ic)->key)
- {
- dic = NULL;
- break;
+ if (POINTER_SET (dic) &&
+ IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+ {
+ dic = NULL;
+ break;
+ }
}
}
break; /* found where this temp was defined */
/* if we find an usage then we cannot delete it */
- if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
+
+ if (dic->op == IFX)
+ {
+ if (IC_COND (dic) && IC_COND (dic)->key == op->key)
+ return NULL;
+ }
+ else if (dic->op == JUMPTABLE)
+ {
+ if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
+ return NULL;
+ }
+ else
+ {
+ if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+ return NULL;
- if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
+ if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+ return NULL;
- if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
+ if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+ return NULL;
+ }
}
if (!dic)
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 ) {
+ OP_SYMBOL(IC_RIGHT(ic))->remat &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
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)) {
int i;
setToNull ((void *) &_G.funcrUsed);
+ setToNull ((void *) &_G.regAssigned);
setToNull ((void *) &_G.totRegAssigned);
mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
mcs51_nRegs = 8;
/* change assignments this will remove some
live ranges reducing some register pressure */
+
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);
serialRegAssign (ebbs, count);
freeAllRegs ();
+ //setToNull ((void *) &_G.regAssigned);
+ //setToNull ((void *) &_G.totRegAssigned);
fillGaps();
/* if stack was extended then tell the user */
createRegMask (ebbs, count);
/* redo that offsets for stacked automatic variables */
- redoStackOffsets ();
+ if (currFunc) {
+ redoStackOffsets ();
+ }
if (options.dump_rassgn)
{
/* 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 */
freeAllRegs ();