X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=a5ea44f393830ed470c338d37be4d7b054051f5a;hb=d7e7311293ec997e4d6cdf4d05bb91100458d460;hp=1b496915cac873388bbd02c700332f3221aebd8c;hpb=e38cbca7359a22dc69b88a286965b4d7ead3ce17;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 1b496915..a5ea44f3 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -240,6 +240,7 @@ DEFSETFUNC (findCheaperOp) cseDef *cdp = item; V_ARG (operand *, cop); V_ARG (operand **, opp); + V_ARG (int, checkSign); /* if we have already found it */ if (*opp) @@ -276,6 +277,7 @@ DEFSETFUNC (findCheaperOp) IS_ITEMP (IC_RESULT (cdp->diCode)) && IS_ITEMP (IC_RIGHT (cdp->diCode)) && !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind && + !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv && ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) && SPIL_LOC (IC_RESULT (cdp->diCode))) || (SPIL_LOC (IC_RESULT (cdp->diCode)) && @@ -301,10 +303,11 @@ DEFSETFUNC (findCheaperOp) *opp = IC_RESULT (cdp->diCode); if ((*opp) && - (isOperandLiteral(*opp) || - (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) && - (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))) - { + (isOperandLiteral(*opp) || !checkSign || + (checkSign && + (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) && + (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))))) + { if ((isGlobalInNearSpace (cop) && !isOperandLiteral (*opp)) || @@ -568,6 +571,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 */ /*-----------------------------------------------------------------*/ @@ -787,6 +804,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 */ @@ -892,6 +910,14 @@ updateSpillLocation (iCode * ic, int induction) 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)) && @@ -987,7 +1013,7 @@ ifxOptimize (iCode * ic, set * cseSet, if (!computeOnly) { pdop = NULL; - applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop); + applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0); if (pdop) { IC_COND (ic) = pdop; @@ -1105,7 +1131,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))) @@ -1259,6 +1285,55 @@ fixUpTypes (iCode * ic) } } +/*-----------------------------------------------------------------*/ +/* isSignedOp - will return 1 if sign is important to operation */ +/*-----------------------------------------------------------------*/ +static int isSignedOp (iCode *ic) +{ + switch (ic->op) { + case '!': + case '~': + case UNARYMINUS: + case IPUSH: + case IPOP: + case CALL: + case PCALL: + case RETURN: + case '+': + case '-': + case EQ_OP: + case AND_OP: + case OR_OP: + case '^': + case '|': + case BITWISEAND: + case INLINEASM: + case LEFT_OP: + case GET_VALUE_AT_ADDRESS: + case '=': + case IFX: + case RECEIVE: + case SEND: + return 0; + case '*': + case '/': + case '%': + case '>': + case '<': + case LE_OP: + case GE_OP: + case NE_OP: + case RRC: + case RLC: + case GETHBIT: + case RIGHT_OP: + case CAST: + case ARRAYINIT: + return 1; + default: + return 0; + } + } /*-----------------------------------------------------------------*/ /* cseBBlock - common subexpression elimination for basic blocks */ /* this is the hackiest kludgiest routine in the whole */ @@ -1302,7 +1377,8 @@ cseBBlock (eBBlock * ebb, int computeOnly, iCode *pdic; operand *pdop; iCode *defic; - + int checkSign ; + ic->eBBlockNum = ebb->bbnum; if (SKIP_IC2 (ic)) @@ -1355,7 +1431,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, if (!computeOnly) { pdop = NULL; - applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop); + applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0); if (pdop) IC_LEFT (ic) = pdop; } @@ -1437,12 +1513,14 @@ cseBBlock (eBBlock * ebb, int computeOnly, !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype))) { pdop = NULL; - applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop); + applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0); if (pdop && IS_ITEMP (pdop) && !computeOnly) IC_RESULT (ic) = pdop; } } + checkSign = isSignedOp(ic); + /* do the operand lookup i.e. for both the */ /* right & left operand : check the cseSet */ /* to see if they have been replaced if yes */ @@ -1454,13 +1532,17 @@ cseBBlock (eBBlock * ebb, int computeOnly, { pdop = NULL; - applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop); + applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign); if (pdop) { if (POINTER_GET (ic)) { if (IS_ITEMP (pdop) || IS_OP_LITERAL (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); IC_LEFT (ic) = pdop; change = 1; } @@ -1491,7 +1573,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, { pdop = NULL; - applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop); + applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign); if (pdop) { IC_RIGHT (ic) = pdop; @@ -1539,12 +1621,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)) {