X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=081250a1207687086c55b42ff20e7fb61156ad25;hb=ca80bc1e62f377e3151521c809b6b41df2b22857;hp=a3c8a027c5cd111a077f4a7678e79691ef40f4ad;hpb=24b38610695ad1df39fb34e5e63be583035e2e21;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index a3c8a027..081250a1 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -1,9 +1,3 @@ -//#define LIVERANGEHUNT -#ifdef LIVERANGEHUNT - #define LRH(x) x -#else - #define LRH(x) -#endif /*------------------------------------------------------------------------- SDCCcse.c - source file for Common Subexpressions and other utility @@ -89,9 +83,9 @@ pcseDef (void *item, va_list ap) 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; @@ -118,7 +112,6 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) { 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; @@ -156,7 +149,8 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) 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)) @@ -287,7 +281,7 @@ DEFSETFUNC (findCheaperOp) /* 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 */ @@ -334,6 +328,7 @@ DEFSETFUNC (findCheaperOp) 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))))))) { @@ -358,9 +353,28 @@ DEFSETFUNC (findCheaperOp) *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; } @@ -410,8 +424,7 @@ DEFSETFUNC (findPrevIc) 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; } @@ -422,7 +435,6 @@ DEFSETFUNC (findPrevIc) 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; } @@ -612,7 +624,7 @@ iCode *findBackwardDef(operand *op,iCode *ic) 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; @@ -800,9 +812,21 @@ algebraicOpts (iCode * ic) } 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; } } @@ -820,10 +844,27 @@ algebraicOpts (iCode * ic) 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; } } @@ -1389,7 +1430,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* if this block is not reachable */ if (ebb->noPath) - return change; + return 0; /* set of common subexpressions */ cseSet = setFromSet (ebb->inExprs); @@ -1509,9 +1550,11 @@ cseBBlock (eBBlock * ebb, int computeOnly, 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)))) @@ -1527,7 +1570,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, 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) { @@ -1539,18 +1582,19 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* 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); } } @@ -1617,13 +1661,13 @@ cseBBlock (eBBlock * ebb, int computeOnly, } /* 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)) { @@ -1785,7 +1829,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* 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; @@ -1793,7 +1837,7 @@ cseAllBlocks (eBBlock ** ebbs, int count) /* 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; }