else
sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
- /* if the allocation falied which means
+ /* if the allocation failed which means
this was spilt then break */
- if (!sym->regs[j])
- break;
+ if (!sym->regs[j]) {
+ if (j) {
+ fprintf (stderr, "%d reg(s) lost in %s:%d\n",
+ j, __FILE__,__LINE__);
+ }
+ break;
+ }
}
/* if it shares registers with operands make sure
/*-----------------------------------------------------------------*/
/* rUmaskForOp :- returns register mask for an operand */
/*-----------------------------------------------------------------*/
-static bitVect *
-rUmaskForOp (operand * op)
+bitVect *
+mcs51_rUmaskForOp (operand * op)
{
bitVect *rumask;
symbol *sym;
if (ic->op == IFX)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_COND (ic)));
+ mcs51_rUmaskForOp (IC_COND (ic)));
goto ret;
}
if (ic->op == JUMPTABLE)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_JTCOND (ic)));
+ mcs51_rUmaskForOp (IC_JTCOND (ic)));
goto ret;
}
/* of all other cases */
if (IC_LEFT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_LEFT (ic)));
+ mcs51_rUmaskForOp (IC_LEFT (ic)));
if (IC_RIGHT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RIGHT (ic)));
+ mcs51_rUmaskForOp (IC_RIGHT (ic)));
if (IC_RESULT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RESULT (ic)));
+ mcs51_rUmaskForOp (IC_RESULT (ic)));
ret:
return rmask;
continue;
}
+ /* cast then continue */
+ if (IS_CAST_ICODE(ic)) {
+ ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ continue;
+ }
/* we reached the end */
sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
break;
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
+ !sym->noSpilLoc &&
!IS_BITVAR (sym->etype))
{
/* if remat in data space */
if (OP_SYMBOL (IC_LEFT (ic))->remat &&
+ !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
{
packRegsForAssign (iCode * ic, eBBlock * ebp)
{
iCode *dic, *sic;
- sym_link *etype = operandType (IC_RIGHT (ic));
+ //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 ||
- IS_BITFIELD (etype))
+ OP_LIVETO (IC_RIGHT (ic)) > ic->seq
+ /* why? || IS_BITFIELD (etype) */ )
{
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 0
- if (isOperandInFarSpace (IC_RESULT (ic)))
- {
- if ((dic = farSpacePackable (ic)))
- goto pack;
- else
- return 0;
- }
-#else
if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
return 0;
}
-#endif
/* find the definition of iTempNN scanning backwards if we find a
a use of the true symbol in before we find the definition then
we cannot */
for (dic = ic->prev; dic; dic = dic->prev)
{
-#if 0 // jwk 20010410
- /* if there is a function call and this is
- a parameter & not my parameter then don't pack it */
- if ((dic->op == CALL || dic->op == PCALL) &&
- (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
- !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
- {
- dic = NULL;
- break;
- }
-#else
/* 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;
/* or in stack space in case of + & - */
/* if assigned to a non-symbol then return
- true */
+ FALSE */
if (!IS_SYMOP (IC_RIGHT (dic)))
- break;
+ return NULL;
/* if the symbol is in far space then
we should not */
packRegsForSupport (iCode * ic, eBBlock * ebp)
{
int change = 0;
+ iCode *dic, *sic;
+
/* for the left & right operand :- look to see if the
left was assigned a true symbol in far space in that
case replace them */
if (IS_ITEMP (IC_LEFT (ic)) &&
OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
{
- iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
- iCode *sic;
+ dic = findAssignToSym (IC_LEFT (ic), ic);
if (!dic)
goto right;
for (sic = dic; sic != ic; sic = sic->next)
bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
- IC_LEFT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
- IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+ OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
+ IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
remiCodeFromeBBlock (ebp, dic);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
change++;
/* only upto 2 bytes since we cannot predict
the usage of b, & acc */
- if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) &&
- ic->op != RETURN &&
+ if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
+ return NULL;
+
+ if (ic->op != RETURN &&
ic->op != SEND &&
!POINTER_SET (ic) &&
!POINTER_GET (ic))
return NULL;
-
+
/* this routine will mark the a symbol as used in one
instruction use only && if the defintion is local
(ie. within the basic block) && has only one definition &&
bitVectFirstBit (OP_DEFS (op)))))
return NULL;
+ /* if that only usage is a cast */
+ if (dic->op == CAST) {
+ /* to a bigger type */
+ if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
+ getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
+ /* than we can not, since we cannot predict the usage of b & acc */
+ return NULL;
+ }
+ }
+
/* found the definition now check if it is local */
if (dic->seq < ebp->fSeq ||
dic->seq > ebp->lSeq)
IC_LEFT (uic)->key != IC_RESULT (ic)->key)
return;
+#if 0
+ // this is too dangerous and need further restrictions
+ // see bug #447547
+
/* if one of them is a literal then we can */
if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
(IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
return;
}
+#endif
/* if the other one is not on stack then we can */
if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
/*-----------------------------------------------------------------*/
/* packForPush - hueristics to reduce iCode for pushing */
/*-----------------------------------------------------------------*/
-catchMe() {}
-
static void
packForPush (iCode * ic, eBBlock * ebp)
{
sym_link *ditype=operandType(IC_RIGHT(dic));
if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
- SPEC_SHORT(itype)!=SPEC_SHORT(ditype) ||
- SPEC_USIGN(itype)!=SPEC_USIGN(ditype))
+ SPEC_LONG(itype)!=SPEC_LONG(ditype))
return;
}
/* extend the live range of replaced operand if needed */
for (ic = ebp->sch; ic; ic = ic->next)
{
- /* if this is an itemp & result of a address of a true sym
+ /* if this is an itemp & result of an address of a true sym
then mark this as rematerialisable */
if (ic->op == ADDRESS_OF &&
IS_ITEMP (IC_RESULT (ic)) &&
!POINTER_SET (ic) &&
IS_SYMOP (IC_RIGHT (ic)) &&
OP_SYMBOL (IC_RIGHT (ic))->remat &&
+ !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
{
OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
}
+ /* if cast to a generic pointer & the pointer being
+ 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 ) {
+ 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)) {
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
+ }
+
/* if this is a +/- operation with a rematerizable
then mark this as rematerializable as well */
if ((ic->op == '+' || ic->op == '-') &&
(IS_SYMOP (IC_LEFT (ic)) &&
IS_ITEMP (IC_RESULT (ic)) &&
+ IS_OP_LITERAL (IC_RIGHT (ic))) &&
OP_SYMBOL (IC_LEFT (ic))->remat &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- IS_OP_LITERAL (IC_RIGHT (ic))))
+ (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
{
OP_SYMBOL (IC_RESULT (ic))->remat = 1;
OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
}
}
-#if 0
- /* if the condition of an if instruction
- is defined in the previous instruction then
- mark the itemp as a conditional */
- if ((IS_CONDITIONAL (ic) ||
- (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
- ic->next && ic->next->op == IFX &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
- {
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
- }
-#else
/* if the condition of an if instruction
is defined in the previous instruction and
this is the only usage then
OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
continue;
}
-#endif
/* reduce for support function calls */
if (ic->supportRtn || ic->op == '+' || ic->op == '-')
/* if the type from and type to are the same
then if this is the only use then packit */
- if (checkType (operandType (IC_RIGHT (ic)),
+ if (compareType (operandType (IC_RIGHT (ic)),
operandType (IC_LEFT (ic))) == 1)
{
iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
we can leave the result of this operation in acc:b
combination */
if ((IS_ARITHMETIC_OP (ic)
+ || IS_CONDITIONAL(ic)
|| IS_BITWISE_OP (ic)
|| ic->op == LEFT_OP || ic->op == RIGHT_OP
|| (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
setToNull ((void *) &_G.funcrUsed);
mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
- /* if not register extentions then reduce number
- of registers */
- if (options.regExtend)
- mcs51_nRegs = 13;
- else
- mcs51_nRegs = 8;
+ mcs51_nRegs = 8;
/* change assignments this will remove some
live ranges reducing some register pressure */
packRegisters (ebbs[i]);
if (options.dump_pack)
- dumpEbbsToFileExt (".dumppack", ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
/* first determine for each live range the number of
registers & the type of registers required for each */
if (options.dump_rassgn)
{
- dumpEbbsToFileExt (".dumprassgn", ebbs, count);
- dumpLiveRanges (".dumplrange", liveRanges);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
/* do the overlaysegment stuff SDCCmem.c */
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
-
gen51Code (ic);
/* free up any _G.stackSpil locations allocated */