{
int j;
- /* if no registers assigned to it or
- spilt */
+ /* if no registers assigned to it or spilt */
/* if it does not overlap with this then
not need to spill it */
static void
serialRegAssign (eBBlock ** ebbs, int count)
{
- int i;
+ int i;
- /* for all blocks */
- for (i = 0; i < count; i++)
- {
+ /* for all blocks */
+ for (i = 0; i < count; i++) {
- iCode *ic;
+ iCode *ic;
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
- /* of all instructions do */
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
+ /* of all instructions do */
+ for (ic = ebbs[i]->sch; ic; ic = ic->next) {
- /* if this is an ipop that means some live
- range will have to be assigned again */
- if (ic->op == IPOP)
- reassignLR (IC_LEFT (ic));
-
- /* if result is present && is a true symbol */
- if (IC_RESULT (ic) && ic->op != IFX &&
- IS_TRUE_SYMOP (IC_RESULT (ic)))
- OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
-
- /* take away registers from live
- ranges that end at this instruction */
- deassignLRs (ic, ebbs[i]);
-
- /* some don't need registers */
- if (SKIP_IC2 (ic) ||
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- (IC_RESULT (ic) && POINTER_SET (ic)))
- continue;
+ /* if this is an ipop that means some live
+ range will have to be assigned again */
+ if (ic->op == IPOP)
+ reassignLR (IC_LEFT (ic));
- /* now we need to allocate registers
- only for the result */
- if (IC_RESULT (ic))
- {
- symbol *sym = OP_SYMBOL (IC_RESULT (ic));
- bitVect *spillable;
- int willCS;
- int j;
- int ptrRegSet = 0;
-
- /* if it does not need or is spilt
- or is already assigned to registers
- or will not live beyond this instructions */
- if (!sym->nRegs ||
- sym->isspilt ||
- bitVectBitValue (_G.regAssigned, sym->key) ||
- sym->liveTo <= ic->seq)
- continue;
+ /* if result is present && is a true symbol */
+ if (IC_RESULT (ic) && ic->op != IFX &&
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
- /* if some liverange has been spilt at the block level
- and this one live beyond this block then spil this
- to be safe */
- if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
- {
- spillThis (sym);
- continue;
- }
- /* if trying to allocate this will cause
- a spill and there is nothing to spill
- or this one is rematerializable then
- spill this one */
- willCS = willCauseSpill (sym->nRegs, sym->regType);
- spillable = computeSpillable (ic);
- if (sym->remat ||
- (willCS && bitVectIsZero (spillable)))
- {
+ /* take away registers from live
+ ranges that end at this instruction */
+ deassignLRs (ic, ebbs[i]);
- spillThis (sym);
- continue;
+ /* some don't need registers */
+ if (SKIP_IC2 (ic) ||
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ (IC_RESULT (ic) && POINTER_SET (ic)))
+ continue;
+ /* now we need to allocate registers
+ only for the result */
+ if (IC_RESULT (ic)) {
+ symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+ bitVect *spillable;
+ int willCS;
+ int j;
+ int ptrRegSet = 0;
+
+ /* if it does not need or is spilt
+ or is already assigned to registers
+ or will not live beyond this instructions */
+ if (!sym->nRegs ||
+ sym->isspilt ||
+ bitVectBitValue (_G.regAssigned, sym->key) ||
+ sym->liveTo <= ic->seq)
+ continue;
+
+ /* if some liverange has been spilt at the block level
+ and this one live beyond this block then spil this
+ to be safe */
+ if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
+ spillThis (sym);
+ continue;
+ }
+ /* if trying to allocate this will cause
+ a spill and there is nothing to spill
+ or this one is rematerializable then
+ spill this one */
+ willCS = willCauseSpill (sym->nRegs, sym->regType);
+ spillable = computeSpillable (ic);
+ if (sym->remat || (willCS && bitVectIsZero (spillable))) {
+ spillThis (sym);
+ continue;
}
- /* if it has a spillocation & is used less than
- all other live ranges then spill this */
- if (willCS && sym->usl.spillLoc)
- {
-
- symbol *leastUsed =
- leastUsedLR (liveRangesWith (spillable,
- allLRs,
- ebbs[i],
- ic));
- if (leastUsed &&
- leastUsed->used > sym->used)
- {
- spillThis (sym);
- continue;
+ /* if it has a spillocation & is used less than
+ all other live ranges then spill this */
+ if (willCS) {
+ if (sym->usl.spillLoc) {
+ symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+ allLRs, ebbs[i], ic));
+ if (leastUsed && leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ } else {
+ /* if none of the liveRanges have a spillLocation then better
+ to spill this one than anything else already assigned to registers */
+ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+ spillThis (sym);
+ continue;
+ }
}
}
-
- /* if we need ptr regs for the right side
- then mark it */
- if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
- && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
- <= PTRSIZE)
- {
- mcs51_ptrRegReq++;
- ptrRegSet = 1;
+ /* if we need ptr regs for the right side
+ then mark it */
+ if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
+ && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
+ mcs51_ptrRegReq++;
+ ptrRegSet = 1;
+ }
+ /* else we assign registers to it */
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+
+ for (j = 0; j < sym->nRegs; j++) {
+ if (sym->regType == REG_PTR)
+ sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+ else
+ sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+
+ /* if the allocation falied which means
+ this was spilt then break */
+ if (!sym->regs[j])
+ break;
}
- /* else we assign registers to it */
- _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
- for (j = 0; j < sym->nRegs; j++)
- {
- if (sym->regType == REG_PTR)
- sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
- else
- sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
- /* if the allocation falied which means
- this was spilt then break */
- if (!sym->regs[j])
- break;
+ /* 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)), ic->lineno);
}
- /* 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)), ic->lineno);
- /* 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)), ic->lineno);
-
- if (ptrRegSet)
- {
- mcs51_ptrRegReq--;
- ptrRegSet = 0;
+ /* 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)), ic->lineno);
+ }
+
+ if (ptrRegSet) {
+ mcs51_ptrRegReq--;
+ ptrRegSet = 0;
}
}
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
+ !sym->noSpilLoc &&
!IS_BITVAR (sym->etype))
{
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 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))
+ /* if there is a function call then don't pack it */
+ if ((dic->op == CALL || dic->op == PCALL))
{
dic = NULL;
break;
/* 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++;
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)
isBitwiseOptimizable (iCode * ic)
{
sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
+ sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
/* bitwise operations are considered optimizable
under the following conditions (Jean-Louis VERN)
+ x & lit
bit & bit
bit & x
bit ^ bit
bit ^ x
+ x ^ lit
+ x | lit
bit | bit
bit | x
- */
- if ((IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
+ */
+ if (IS_LITERAL(rtype) ||
+ (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
return TRUE;
else
return FALSE;
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 &&
if (bitVectBitValue(dbv,lic->key))
return ;
}
+ /* make sure they have the same type */
+ {
+ sym_link *itype=operandType(IC_LEFT(ic));
+ sym_link *ditype=operandType(IC_RIGHT(dic));
+
+ if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
+ SPEC_LONG(itype)!=SPEC_LONG(ditype))
+ return;
+ }
+ /* extend the live range of replaced operand if needed */
+ if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
+ OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
+ }
/* 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);
-
+
remiCodeFromeBBlock (ebp, dic);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
}
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)) &&
}
/* if the condition of an if instruction
- is defined in the previous instruction then
+ is defined in the previous instruction and
+ this is the only usage then
mark the itemp as a conditional */
if ((IS_CONDITIONAL (ic) ||
(IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
ic->next && ic->next->op == IFX &&
+ bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
{
}
/* reduce for support function calls */
-#if geniCodeLogicHasBeenFixed
if (ic->supportRtn || ic->op == '+' || ic->op == '-')
packRegsForSupport (ic, ebp);
-#endif
/* some cases the redundant moves can
can be eliminated for return statements */
if (dic)
{
if (IS_ARITHMETIC_OP (dic))
- {
+ {
IC_RESULT (dic) = IC_RESULT (ic);
remiCodeFromeBBlock (ebp, ic);
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
/* 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);
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 */