+//#define LIVERANGEHUNT
+#ifdef LIVERANGEHUNT
+ #define LRH(x) x
+#else
+ #define LRH(x)
+#endif
/*-------------------------------------------------------------------------
SDCCcse.c - source file for Common Subexpressions and other utility
return 1;
}
+void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
+#ifdef RANGEHUNT
+ printf ("ReplaceOpWithCheaperOp (%s:%d with %s:%d): ",
+ OP_SYMBOL((*op))->name, OP_SYMBOL((*op))->isreqv,
+ OP_SYMBOL(cop)->name, OP_SYMBOL(cop)->isreqv);
+ // if op is a register equivalent
+ if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+ operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
+ if (isOperandEqual(*rop, *op)) {
+ printf ("true");
+ *rop=cop;
+ OP_SYMBOL((*op))->isreqv=0;
+ OP_SYMBOL(cop)->isreqv=1;
+ } else {
+ printf ("false");
+ }
+ }
+ printf ("\n");
+#endif
+ *op=cop;
+}
+
/*-----------------------------------------------------------------*/
/* replaceAllSymBySym - replaces all operands by operand in an */
/* instruction chain */
{
iCode *lic;
+ LRH(printf ("replaceAllSymBySym: from %s to %s\n", OP_SYMBOL(from)->name, OP_SYMBOL(to)->name));
for (lic = ic; lic; lic = lic->next)
{
int siaddr;
*opp = operandFromOperand (*opp);
(*opp)->isaddr = cop->isaddr;
}
-
+ LRH(printf ("findCheaperOp: %s < %s\n",\
+ IS_SYMOP((*opp)) ? OP_SYMBOL((*opp))->name : "!SYM",\
+ OP_SYMBOL(cop)->name));
return 1;
}
if (isiCodeEqual (ic, cdp->diCode) &&
isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
{
+ LRH(printf ("findPrevIc same: %d %d\n", ic->key, cdp->diCode->key));
*icp = cdp->diCode;
return 1;
}
isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
{
+ LRH(printf ("findPrevIc inter: %d %d\n", ic->key, cdp->diCode->key));
*icp = cdp->diCode;
return 1;
}
void
updateSpillLocation (iCode * ic, int induction)
{
-
sym_link *setype;
if (POINTER_SET (ic))
applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
if (pdop)
{
- IC_COND (ic) = pdop;
+ ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
(*change)++;
}
}
return 0;
}
}
+
/*-----------------------------------------------------------------*/
/* cseBBlock - common subexpression elimination for basic blocks */
/* this is the hackiest kludgiest routine in the whole */
pdop = NULL;
applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
if (pdop)
- IC_LEFT (ic) = pdop;
+ ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
}
/* the lookup could have changed it */
if (IS_SYMOP (IC_LEFT (ic)))
pdop = NULL;
applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
if (pdop && IS_ITEMP (pdop) && !computeOnly)
- IC_RESULT (ic) = pdop;
+ ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
}
}
this variable .. unsafe to remove any POINTER_GETs */
if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
- IC_LEFT (ic) = pdop;
+ ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
change = 1;
}
/* check if there is a pointer set
{
ic->op = '=';
IC_LEFT (ic) = NULL;
- IC_RIGHT (ic) = pdop;
+ ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
SET_ISADDR (IC_RESULT (ic), 0);
}
}
else
{
- IC_LEFT (ic) = pdop;
+ ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
change = 1;
}
}
pdop = NULL;
applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
- if (pdop)
- {
- IC_RIGHT (ic) = pdop;
- change = 1;
- }
+ if (pdop) {
+ ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+ change = 1;
+ }
}
-
+
/* if left or right changed then do algebraic */
if (change)
{
/* if after all this it becomes a assignment to self
then delete it and continue */
- if (ASSIGNMENT_TO_SELF (ic) && !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))))
+ if (ASSIGNMENT_TO_SELF (ic))
{
remiCodeFromeBBlock (ebb, ic);
continue;
"%s%s", port->fun_prefix, sym->name);
/* add it to the operandKey reset */
- addSet (&operKeyReset, sym);
+ if (!isinSet (operKeyReset, sym)) {
+ addSet(&operKeyReset, sym);
+ }
/* if this is a literal e.g. enumerated type */
/* put it in the data segment & do nothing */
addSym (SymbolTab, lval->sym, lval->sym->name,
lval->sym->level, lval->sym->block, 1);
lval->sym->_isparm = 1;
- addSet (&operKeyReset, lval->sym);
+ if (!isinSet (operKeyReset, lval->sym)) {
+ addSet(&operKeyReset, lval->sym);
+ }
}
}
if (!sym->allocreq && sym->reqv)
{
int i;
+ if (!OP_SYMBOL(sym->reqv)->nRegs) {
+ printf ("*** warning: %s -> %s\n", sym->name,
+ OP_SYMBOL(sym->reqv)->name);
+ }
sym = OP_SYMBOL (sym->reqv);
fprintf (of, "registers ");
for (i = 0; i < 4 && sym->regs[i]; i++)
+//#define LIVERANGEHUNT
+#ifdef LIVERANGEHUNT
+ #define LRH(x) x
+#else
+ #define LRH(x)
+#endif
/*------------------------------------------------------------------------
SDCCralloc.c - source file for register allocation. (8051) specific
if (!(sym->remat || sym->usl.spillLoc))
createStackSpil (sym);
-
+ LRH(printf("spillThis: %s\n", sym->name));
/* mark it has spilt & put it in the spilt set */
sym->isspilt = sym->spillA = 1;
_G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
/* get something we can spil */
ssym = selectSpil (ic, ebp, forSym);
+ LRH(printf("spilSomething: spilled %s for %s\n", ssym->name, forSym->name));
/* mark it as spilt */
ssym->isspilt = ssym->spillA = 1;
continue;
}
+ if (strcmp(sym->name,"iTemp121")==0) {
+ printf ("Oops\n");
+ }
/* if it has a spillocation & is used less than
all other live ranges then spill this */
if (willCS) {
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 &&
/* 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);
+ ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
IC_LEFT(ic)=NULL;
#endif
continue;
/* registers for true symbols we will */
/* see how things go */
sym->nRegs = 0;
- }
+ }
}
packRegsForAssign (iCode * ic, eBBlock * ebp)
{
iCode *dic, *sic;
- //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
- /* why? || IS_BITFIELD (etype) */ )
+ OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
{
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 (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
/* 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);
+ ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
{
OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
}
+ // jwk: and the otherway around?
+
/* delete from liverange table also
delete from all the points inbetween and the new
one */
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
return 1;
-
}
/*------------------------------------------------------------------*/
if (!dic)
return NULL; /* didn't find any assignment to op */
+ LRH(printf ("findAssignToSym: %s\n", OP_SYMBOL(IC_RESULT(dic))->name));
/* we are interested only if defined in far space */
/* or in stack space in case of + & - */
bitVectFirstBit (OP_DEFS (op)))))
return NULL;
+ LRH(printf ("packRegsForOneUse: %s\n", OP_SYMBOL(op)->name));
/* if that only usage is a cast */
if (dic->op == CAST) {
/* to a bigger type */
OP_SYMBOL (op)->ruonly = 1;
return sic;
-
}
/*-----------------------------------------------------------------*/
/* we now we know that it has one & only one def & use
and the that the definition is an assignment */
- IC_LEFT (ic) = IC_RIGHT (dic);
+ ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
remiCodeFromeBBlock (ebp, dic);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
}
if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
!isOperandInFarSpace (IC_LEFT (ic)) &&
options.model == MODEL_SMALL) {
- if (0 && options.stackAuto) {
- /* we should check here if acc will be clobbered for stack
- offset calculations */
- } else {
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
- }
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
}
/* if pointer set & left has a size more than
!OP_SYMBOL (IC_RESULT (ic))->remat &&
!IS_OP_RUONLY (IC_RIGHT (ic)) &&
getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
packRegsForOneuse (ic, IC_RESULT (ic), ebp);
/* if pointer get */
!OP_SYMBOL (IC_LEFT (ic))->remat &&
!IS_OP_RUONLY (IC_RESULT (ic)) &&
getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
if (IS_ARITHMETIC_OP (dic))
{
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
+ ReplaceOpWithCheaperOp(&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);
if (dic)
{
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
+ ReplaceOpWithCheaperOp(&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);