X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=23dece6272c69be3f1935b191d15d702d80e8058;hb=e3afb06568973e787cdd8790d2fa2577751337b6;hp=1f444374f4af883a9bd4fd54bf50da733f6b2c36;hpb=52e2daedcc037e356cfe151a7e037690c02cd3f9;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 1f444374..23dece62 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) @@ -302,11 +303,11 @@ DEFSETFUNC (findCheaperOp) *opp = IC_RESULT (cdp->diCode); if ((*opp) && - (isOperandLiteral(*opp) || - getSize(operandType(*opp)) == getSize(operandType(cop)) || - (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)) || @@ -789,6 +790,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 */ @@ -989,7 +991,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; @@ -1261,6 +1263,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 */ @@ -1304,7 +1355,8 @@ cseBBlock (eBBlock * ebb, int computeOnly, iCode *pdic; operand *pdop; iCode *defic; - + int checkSign ; + ic->eBBlockNum = ebb->bbnum; if (SKIP_IC2 (ic)) @@ -1357,7 +1409,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; } @@ -1439,12 +1491,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 */ @@ -1456,7 +1510,7 @@ 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)) @@ -1493,7 +1547,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;