-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
- #define LRH(x) x
-#else
- #define LRH(x)
-#endif
/*-------------------------------------------------------------------------
SDCCcse.c - source file for Common Subexpressions and other utility
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);
+ printf ("ReplaceOpWithCheaperOp %s with %s: ",
+ IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
+ IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
// if op is a register equivalent
if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
{
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;
continue;
}
- if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
+ if (IS_SYMOP(to) &&
+ IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
{
/* maintain du chains */
if (POINTER_SET (lic))
/* if the result is volatile then return result */
if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
*opp = IC_RESULT (cdp->diCode);
- else
+ else
/* if this is a straight assignment and
left is a temp then prefer the temporary to the
true symbol */
if ((*opp) &&
(isOperandLiteral(*opp) || !checkSign ||
(checkSign &&
+ IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
(SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
(SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
{
*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));
+
+ if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
+ SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
+ {
+ // special case: we can make an unsigned char literal
+ // into an int literal with no cost.
+ if (isOperandLiteral(*opp)
+ && SPEC_NOUN(operandType(*opp)) == V_CHAR
+ && SPEC_NOUN(operandType(cop)) == V_INT)
+ {
+ *opp = operandFromOperand (*opp);
+ SPEC_NOUN(operandType(*opp)) = V_INT;
+ }
+ else
+ {
+ // No clue...
+ *opp = NULL;
+ return 0;
+ }
+
+ }
+
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;
+ *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;
}
iCode *lic;
for (lic = ic; lic ; lic = lic->prev) {
- if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
+ if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
return lic;
}
return NULL;
}
if (operandLitValue (IC_LEFT (ic)) == 1.0)
{
- ic->op = '=';
- IC_LEFT (ic) = NULL;
- SET_RESULT_RIGHT (ic);
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_RIGHT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ ic->op = CAST;
+ IC_LEFT (ic)->type = TYPE;
+ setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+ }
return;
}
}
if (operandLitValue (IC_RIGHT (ic)) == 1.0)
{
- ic->op = '=';
- IC_RIGHT (ic) = IC_LEFT (ic);
- IC_LEFT (ic) = NULL;
- SET_RESULT_RIGHT (ic);
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_LEFT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ operand *op;
+
+ ic->op = CAST;
+ op = IC_RIGHT (ic);
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = op;
+ IC_LEFT (ic)->type = TYPE;
+ setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+ }
return;
}
}
/* if this block is not reachable */
if (ebb->noPath)
- return change;
+ return 0;
/* set of common subexpressions */
cseSet = setFromSet (ebb->inExprs);
if (SKIP_IC (ic))
continue;
- /* do some algebraic optimizations if possible */
- algebraicOpts (ic);
- while (constFold (ic, cseSet));
+ if (!computeOnly) {
+ /* do some algebraic optimizations if possible */
+ algebraicOpts (ic);
+ while (constFold (ic, cseSet));
+ }
/* small klugde */
if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
}
- /* if this is a condition statment then */
+ /* if this is a condition statement then */
/* check if the condition can be replaced */
if (ic->op == IFX)
{
/* if the assignment & result is a temp */
/* see if we can replace it */
- if (ic->op == '=')
+ if (!computeOnly && ic->op == '=')
{
/* update the spill location for this */
updateSpillLocation (ic,0);
- if (POINTER_SET (ic) &&
+ if (POINTER_SET (ic) &&
!(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
{
pdop = NULL;
applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
- if (pdop && IS_ITEMP (pdop) && !computeOnly)
+ if (pdop && !computeOnly &&
+ IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
}
}
}
/* if left or right changed then do algebraic */
- if (change)
+ if (!computeOnly && change)
{
algebraicOpts (ic);
while (constFold (ic, cseSet));
}
- /* if after all this it becomes a assignment to self
+ /* if after all this it becomes an assignment to self
then delete it and continue */
if (ASSIGNMENT_TO_SELF (ic))
{
/* cseAllBlocks - will sequentially go thru & do cse for all blocks */
/*-----------------------------------------------------------------*/
int
-cseAllBlocks (eBBlock ** ebbs, int count)
+cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
{
int i;
int change = 0;
/* if optimization turned off */
for (i = 0; i < count; i++)
- change += cseBBlock (ebbs[i], FALSE, ebbs, count);
+ change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
return change;
}