X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=7f439dc7eba174f70f03c277cd66e9f0a3c01141;hb=f87507e38020bef82c102ae3bec67fed8796dcda;hp=126addff5460ee3e38c235980e49104b3c936d0b;hpb=a0ec02948ec1ca4ce6df37ff88080140e3130ccd;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 126addff..7f439dc7 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -34,7 +34,7 @@ newCseDef (operand * sym, iCode * ic) cseDef *cdp; assert (sym); - cdp = Safe_calloc (1, sizeof (cseDef)); + cdp = Safe_alloc (sizeof (cseDef)); cdp->sym = sym; cdp->diCode = ic; @@ -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)) && @@ -300,8 +302,12 @@ DEFSETFUNC (findCheaperOp) IS_ITEMP (IC_RESULT (cdp->diCode))) *opp = IC_RESULT (cdp->diCode); - if (*opp) - { + if ((*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)) || @@ -327,7 +333,7 @@ DEFSETFUNC (findCheaperOp) return 1; } - + *opp=NULL; return 0; } @@ -373,7 +379,7 @@ DEFSETFUNC (findPrevIc) if (isiCodeEqual (ic, cdp->diCode) && isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode))) { - *icp = cdp->diCode; + *icp = cdp->diCode; return 1; } @@ -391,6 +397,20 @@ DEFSETFUNC (findPrevIc) return 0; } +/*-------------------------------------------------------------------*/ +/* ifAssignedFromGlobal - if definition is an assignment from global */ +/*-------------------------------------------------------------------*/ +DEFSETFUNC (ifAssignedFromGlobal) +{ + cseDef *cdp = item; + iCode *dic=cdp->diCode; + + if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) { + return 1; + } + return 0; +} + /*-----------------------------------------------------------------*/ /* ifDefGlobal - if definition is global */ /*-----------------------------------------------------------------*/ @@ -551,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 */ /*-----------------------------------------------------------------*/ @@ -770,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 */ @@ -808,25 +843,28 @@ algebraicOpts (iCode * ic) } break; case CAST: - /* if this is a cast of a literal value */ - if (IS_OP_LITERAL (IC_RIGHT (ic))) - { - ic->op = '='; - IC_RIGHT (ic) = - operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)), - operandLitValue (IC_RIGHT (ic)))); - IC_LEFT (ic) = NULL; - SET_ISADDR (IC_RESULT (ic), 0); - } - /* if casting to the same */ - if (checkType (operandType (IC_RESULT (ic)), - operandType (IC_RIGHT (ic))) == 1) - { - ic->op = '='; - IC_LEFT (ic) = NULL; - SET_ISADDR (IC_RESULT (ic), 0); - } - break; + { + sym_link *otype = operandType(IC_RIGHT(ic)); + sym_link *ctype = operandType(IC_LEFT(ic)); + /* if this is a cast of a literal value */ + if (IS_OP_LITERAL (IC_RIGHT (ic)) && + !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) { + ic->op = '='; + IC_RIGHT (ic) = + operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)), + operandLitValue (IC_RIGHT (ic)))); + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + } + /* if casting to the same */ + if (compareType (operandType (IC_RESULT (ic)), + operandType (IC_RIGHT (ic))) == 1) { + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + } + } + break; case '!': if (IS_OP_LITERAL (IC_LEFT (ic))) { @@ -846,51 +884,65 @@ algebraicOpts (iCode * ic) /* updateSpillLocation - keeps track of register spill location */ /*-----------------------------------------------------------------*/ void -updateSpillLocation (iCode * ic) +updateSpillLocation (iCode * ic, int induction) { - sym_link *setype; + sym_link *setype; - if (POINTER_SET (ic)) - return; + if (POINTER_SET (ic)) + return; - if (ic->nosupdate) - return; + if (ic->nosupdate) + return; - /* for the form true_symbol := iTempNN */ - if (ASSIGN_ITEMP_TO_SYM (ic) - && !SPIL_LOC (IC_RIGHT (ic))) - { + /* for the form true_symbol := iTempNN */ + if (ASSIGN_ITEMP_TO_SYM (ic) && + !SPIL_LOC (IC_RIGHT (ic))) { - setype = getSpec (operandType (IC_RESULT (ic))); + setype = getSpec (operandType (IC_RESULT (ic))); - if (!IC_RIGHT (ic)->noSpilLoc && - !IS_VOLATILE (setype) && - !IN_FARSPACE (SPEC_OCLS (setype)) && - !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) + if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc && + !IS_VOLATILE (setype) && + !IN_FARSPACE (SPEC_OCLS (setype)) && + !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) - SPIL_LOC (IC_RIGHT (ic)) = - IC_RESULT (ic)->operand.symOperand; - } - - if (ASSIGN_ITEMP_TO_ITEMP (ic) && - !SPIL_LOC (IC_RIGHT (ic)) && - !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) && - OP_SYMBOL (IC_RESULT (ic))->isreqv) - { - - setype = getSpec (operandType (IC_RESULT (ic))); - - if (!IC_RIGHT (ic)->noSpilLoc && - !IS_VOLATILE (setype) && - !IN_FARSPACE (SPEC_OCLS (setype)) && - !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) + SPIL_LOC (IC_RIGHT (ic)) = + IC_RESULT (ic)->operand.symOperand; + } - SPIL_LOC (IC_RIGHT (ic)) = - SPIL_LOC (IC_RESULT (ic)); - } +#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)) && + !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) && + OP_SYMBOL (IC_RESULT (ic))->isreqv) { + + setype = getSpec (operandType (IC_RESULT (ic))); + + if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc && + !IS_VOLATILE (setype) && + !IN_FARSPACE (SPEC_OCLS (setype)) && + !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) + + SPIL_LOC (IC_RIGHT (ic)) = + SPIL_LOC (IC_RESULT (ic)); + } + /* special case for inductions */ + if (induction && + OP_SYMBOL(IC_RIGHT(ic))->isreqv && + !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc && + !SPIL_LOC(IC_RESULT(ic))) { + SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic)); + } + } } - /*-----------------------------------------------------------------*/ /* setUsesDef - sets the uses def bitvector for a given operand */ /*-----------------------------------------------------------------*/ @@ -961,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; @@ -1005,7 +1057,9 @@ ifxOptimize (iCode * ic, set * cseSet, /* too often, if it does happen then the user pays */ /* the price */ computeControlFlow (ebbs, count, 1); - werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + if (!options.lessPedantic) { + werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + } return; } @@ -1019,7 +1073,9 @@ ifxOptimize (iCode * ic, set * cseSet, remiCodeFromeBBlock (ebb, ic); computeControlFlow (ebbs, count, 1); - werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + if (!options.lessPedantic) { + werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + } return; } @@ -1075,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))) @@ -1117,7 +1173,7 @@ constFold (iCode * ic, set * cseSet) if (IS_ITEMP (IC_RESULT (ic))) { SPIL_LOC (IC_RESULT (ic)) = NULL; - IC_RESULT (ic)->noSpilLoc = 1; + OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1; } @@ -1159,9 +1215,9 @@ deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb) iTemp1 = iTemp0 + 8; iTemp2 = iTemp1 + 8; */ if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), - (void*)isOperandEqual) || + (insetwithFunc)isOperandEqual) || isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), - (void*)isOperandEqual)) + (insetwithFunc)isOperandEqual)) { addSet (&compItems, IC_RESULT (cdp->diCode)); } @@ -1213,7 +1269,8 @@ fixUpTypes (iCode * ic) { sym_link *t1 = operandType (IC_LEFT (ic)), *t2; - if (TARGET_IS_DS390) + /* if (TARGET_IS_DS390) */ + if (options.model == MODEL_FLAT24) { /* hack-o-matic! */ return; @@ -1222,12 +1279,61 @@ fixUpTypes (iCode * ic) /* for pointer_gets if the types of result & left r the same then change it type of result to next */ if (IS_PTR (t1) && - checkType (t2 = operandType (IC_RESULT (ic)), t1) == 1) + compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1) { setOperandType (IC_RESULT (ic), t2->next); } } +/*-----------------------------------------------------------------*/ +/* 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 */ @@ -1271,6 +1377,9 @@ cseBBlock (eBBlock * ebb, int computeOnly, iCode *pdic; operand *pdop; iCode *defic; + int checkSign ; + + ic->eBBlockNum = ebb->bbnum; if (SKIP_IC2 (ic)) continue; @@ -1300,6 +1409,10 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* delete global variables from the cseSet since they can be modified by the function call */ deleteItemIf (&cseSet, ifDefGlobal); + + /* and also itemps assigned from globals */ + deleteItemIf (&cseSet, ifAssignedFromGlobal); + /* delete all getpointer iCodes from cseSet, this should be done only for global arrays & pointers but at this point we don't know if globals, so to be safe do all */ @@ -1318,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; } @@ -1394,18 +1507,20 @@ cseBBlock (eBBlock * ebb, int computeOnly, { /* update the spill location for this */ - updateSpillLocation (ic); + updateSpillLocation (ic,0); if (POINTER_SET (ic) && !(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 */ @@ -1417,7 +1532,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)) @@ -1454,10 +1569,9 @@ 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; change = 1; } @@ -1493,69 +1607,29 @@ cseBBlock (eBBlock * ebb, int computeOnly, IS_ITEMP (IC_RESULT (ic)) && !computeOnly) { - applyToSet (cseSet, findPrevIc, ic, &pdic); - if (pdic && checkType (operandType (IC_RESULT (pdic)), + applyToSet (cseSet, findPrevIc, ic, &pdic); + if (pdic && compareType (operandType (IC_RESULT (pdic)), operandType (IC_RESULT (ic))) != 1) pdic = NULL; + if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) + pdic = NULL; } - /* if found then eliminate this and add to */ - /* to cseSet an element containing result */ - /* of this with previous opcode */ - if (pdic) - { - - if (IS_ITEMP (IC_RESULT (ic))) - { - - /* replace in the remaining of this block */ - replaceAllSymBySym (ic->next, IC_RESULT (ic), IC_RESULT (pdic), &ebb->ndompset); - /* remove this iCode from inexpressions of all - its successors, it cannot be in the in expressions - of any of the predecessors */ - for (i = 0; i < count; ebbs[i++]->visited = 0); - applyToSet (ebb->succList, removeFromInExprs, ic, IC_RESULT (ic), - IC_RESULT (pdic), ebb); - - /* if this was moved from another block */ - /* then replace in those blocks too */ - if (ic->movedFrom) - { - eBBlock *owner; - for (owner = setFirstItem (ic->movedFrom); owner; - owner = setNextItem (ic->movedFrom)) - replaceAllSymBySym (owner->sch, IC_RESULT (ic), IC_RESULT (pdic), &owner->ndompset); - } - pdic->movedFrom = unionSets (pdic->movedFrom, ic->movedFrom, THROW_NONE); - } - else - addSetHead (&cseSet, newCseDef (IC_RESULT (ic), pdic)); - - if (!computeOnly) - /* eliminate this */ - remiCodeFromeBBlock (ebb, ic); - - defic = pdic; - change++; - - if (IS_ITEMP (IC_RESULT (ic))) - continue; - - } - else - { - - /* just add this as a previous expression except in */ - /* case of a pointer access in which case this is a */ - /* usage not a definition */ - if (!(POINTER_SET (ic)) && IC_RESULT (ic)) - { - deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic)); - addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic)); - } - defic = ic; + /* Alternate code */ + if (pdic && IS_ITEMP(IC_RESULT(ic))) { + /* 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)) { + deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic)); + addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic)); + } + defic = ic; /* if assignment to a parameter which is not mine and type is a pointer then delete