X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=8942590efaa793ca29e633f76590d7e36fadaa51;hb=717cf743781d6240414f10bc16b532bf54c9efd1;hp=435bff7507c8a0aee97c74322c076328e16512cd;hpb=a8b7c7b21460dade53cb694aa5abe998965b43a6;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 435bff75..8942590e 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -81,6 +81,28 @@ pcseDef (void *item, va_list ap) 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 */ @@ -102,7 +124,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) { bitVectUnSetBit (OP_USES (from), lic->key); - OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key); siaddr = IC_COND (lic)->isaddr; IC_COND (lic) = operandFromOperand (to); IC_COND (lic)->isaddr = siaddr; @@ -118,7 +140,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) { bitVectUnSetBit (OP_USES (from), lic->key); - OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key); siaddr = IC_COND (lic)->isaddr; IC_JTCOND (lic) = operandFromOperand (to); IC_JTCOND (lic)->isaddr = siaddr; @@ -127,13 +149,14 @@ 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)) { bitVectUnSetBit (OP_USES (from), lic->key); - OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key); /* also check if the "from" was in the non-dominating pointer sets and replace it with "to" in the bitVector */ @@ -147,7 +170,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) else { bitVectUnSetBit (OP_DEFS (from), lic->key); - OP_DEFS (to) = bitVectSetBit (OP_DEFS (to), lic->key); + OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key); } siaddr = IC_RESULT (lic)->isaddr; IC_RESULT (lic) = operandFromOperand (to); @@ -158,7 +181,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key) { bitVectUnSetBit (OP_USES (from), lic->key); - OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key); siaddr = IC_RIGHT (lic)->isaddr; IC_RIGHT (lic) = operandFromOperand (to); IC_RIGHT (lic)->isaddr = siaddr; @@ -168,7 +191,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) IC_LEFT (lic) && IC_LEFT (lic)->key == from->key) { bitVectUnSetBit (OP_USES (from), lic->key); - OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key); siaddr = IC_LEFT (lic)->isaddr; IC_LEFT (lic) = operandFromOperand (to); IC_LEFT (lic)->isaddr = siaddr; @@ -305,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))))))) { @@ -329,7 +353,28 @@ DEFSETFUNC (findCheaperOp) *opp = operandFromOperand (*opp); (*opp)->isaddr = cop->isaddr; } - + + 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; } @@ -379,7 +424,7 @@ DEFSETFUNC (findPrevIc) if (isiCodeEqual (ic, cdp->diCode) && isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode))) { - *icp = cdp->diCode; + *icp = cdp->diCode; return 1; } @@ -571,6 +616,20 @@ DEFSETFUNC (ifDiCodeIsX) } +/*-----------------------------------------------------------------*/ +/* findBackwardDef - scan backwards to find deinition of operand */ +/*-----------------------------------------------------------------*/ +iCode *findBackwardDef(operand *op,iCode *ic) +{ + iCode *lic; + + for (lic = ic; lic ; lic = lic->prev) { + if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic))) + return lic; + } + return NULL; +} + /*-----------------------------------------------------------------*/ /* algebraicOpts - does some algebraic optimizations */ /*-----------------------------------------------------------------*/ @@ -790,6 +849,7 @@ algebraicOpts (iCode * ic) IC_LEFT (ic) = NULL; IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); IC_RESULT (ic)->isaddr = 0; + break; } /* if this is a division then check if right */ /* is one then change it to an assignment */ @@ -871,7 +931,6 @@ algebraicOpts (iCode * ic) void updateSpillLocation (iCode * ic, int induction) { - sym_link *setype; if (POINTER_SET (ic)) @@ -890,11 +949,23 @@ updateSpillLocation (iCode * ic, int induction) !IS_VOLATILE (setype) && !IN_FARSPACE (SPEC_OCLS (setype)) && !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) - + { + wassert(IS_SYMOP(IC_RESULT (ic))); + wassert(IS_SYMOP(IC_RIGHT (ic))); SPIL_LOC (IC_RIGHT (ic)) = IC_RESULT (ic)->operand.symOperand; + } + } +#if 0 /* this needs furthur investigation can save a lot of code */ + if (ASSIGN_SYM_TO_ITEMP(ic) && + !SPIL_LOC(IC_RESULT(ic))) { + if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic)))) + SPIL_LOC (IC_RESULT (ic)) = + IC_RIGHT (ic)->operand.symOperand; + } +#endif if (ASSIGN_ITEMP_TO_ITEMP (ic)) { if (!SPIL_LOC (IC_RIGHT (ic)) && @@ -993,7 +1064,7 @@ ifxOptimize (iCode * ic, set * cseSet, applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0); if (pdop) { - IC_COND (ic) = pdop; + ReplaceOpWithCheaperOp(&IC_COND (ic), pdop); (*change)++; } } @@ -1058,7 +1129,7 @@ ifxOptimize (iCode * ic, set * cseSet, /* if it remains an IFX the update the use Set */ - OP_USES (IC_COND (ic)) = bitVectSetBit (OP_USES (IC_COND (ic)), ic->key); + OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key); setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); return; } @@ -1108,7 +1179,7 @@ constFold (iCode * ic, set * cseSet) /* this check is a hueristic to prevent live ranges from becoming too long */ if (IS_PTR (operandType (IC_RESULT (ic)))) - return 0; + return 0; /* check if operation with a literal */ if (!IS_OP_LITERAL (IC_RIGHT (ic))) @@ -1311,6 +1382,7 @@ static int isSignedOp (iCode *ic) return 0; } } + /*-----------------------------------------------------------------*/ /* cseBBlock - common subexpression elimination for basic blocks */ /* this is the hackiest kludgiest routine in the whole */ @@ -1329,7 +1401,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); @@ -1350,7 +1422,6 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* for all the instructions in this block do */ for (ic = ebb->sch; ic; ic = ic->next) { - iCode *pdic; operand *pdop; iCode *defic; @@ -1376,7 +1447,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) { /* add to defSet of the symbol */ - OP_DEFS (IC_RESULT (ic)) = + OP_DEFS(IC_RESULT (ic))= bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); /* add to the definition set of this block */ ebb->defSet = bitVectSetBit (ebb->defSet, ic->key); @@ -1410,12 +1481,12 @@ cseBBlock (eBBlock * ebb, int computeOnly, 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))) { - OP_USES (IC_LEFT (ic)) = + OP_USES(IC_LEFT (ic))= bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key); setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); @@ -1440,7 +1511,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* if jumptable then mark the usage */ if (ic->op == JUMPTABLE) { - OP_USES (IC_JTCOND (ic)) = + OP_USES(IC_JTCOND (ic))= bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key); setUsesDefs (IC_JTCOND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); @@ -1450,9 +1521,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)))) @@ -1468,7 +1541,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) { @@ -1480,7 +1553,7 @@ 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 */ @@ -1492,7 +1565,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, 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); } } @@ -1516,7 +1589,11 @@ cseBBlock (eBBlock * ebb, int computeOnly, { if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop)) { - IC_LEFT (ic) = pdop; + /* some non dominating block does POINTER_SET with + this variable .. unsafe to remove any POINTER_GETs */ + if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key)) + ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key); + ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop); change = 1; } /* check if there is a pointer set @@ -1528,14 +1605,14 @@ cseBBlock (eBBlock * ebb, int computeOnly, { 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; } } @@ -1547,21 +1624,20 @@ cseBBlock (eBBlock * ebb, int computeOnly, 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 (!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)) { @@ -1594,12 +1670,18 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* Alternate code */ if (pdic && IS_ITEMP(IC_RESULT(ic))) { + if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) { + /* Mmm, found an equivalent pointer get at a lower level. + This could be a loop however with the same pointer set + later on */ + } else { /* if previous definition found change this to an assignment */ ic->op = '='; IC_LEFT(ic) = NULL; IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic)); SET_ISADDR(IC_RESULT(ic),0); SET_ISADDR(IC_RIGHT (ic),0); + } } if (!(POINTER_SET (ic)) && IC_RESULT (ic)) { @@ -1651,7 +1733,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* add the left & right to the defUse set */ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))) { - OP_USES (IC_LEFT (ic)) = + OP_USES(IC_LEFT (ic))= bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key); setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); @@ -1659,7 +1741,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))) { - OP_USES (IC_RIGHT (ic)) = + OP_USES(IC_RIGHT (ic))= bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key); setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); @@ -1669,7 +1751,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* in the defuseSet if it a pointer or array access */ if (POINTER_SET (defic)) { - OP_USES (IC_RESULT (ic)) = + OP_USES(IC_RESULT (ic))= bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic)); @@ -1688,7 +1770,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, else /* add the result to defintion set */ if (IC_RESULT (ic)) { - OP_DEFS (IC_RESULT (ic)) = + OP_DEFS(IC_RESULT (ic))= bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); ebb->defSet = bitVectSetBit (ebb->defSet, ic->key); ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic))); @@ -1717,7 +1799,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; @@ -1725,7 +1807,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; }