X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=8e68739ec2487a728c631120b6c3dcb3bc686752;hb=3f966c0865df4d1f37576d9e7f93db5f0f749528;hp=51dc99775f283b7a5f0d043f5f108d10f22dcb9f;hpb=6d5732239ca066c1757ae16f69942fd4b320e612;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 51dc9977..8e68739e 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -42,6 +42,7 @@ newCseDef (operand * sym, iCode * ic) cdp->key = sym->key; cdp->ancestors = newBitVect(iCodeKey); cdp->fromGlobal = 0; + cdp->fromAddrTaken = 0; if (ic->op!=IF && ic->op!=JUMPTABLE) { @@ -49,11 +50,13 @@ newCseDef (operand * sym, iCode * ic) { bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key); cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic)); + cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken; } if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))) { bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key); cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic)); + cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken; } } @@ -79,6 +82,7 @@ updateCseDefAncestors(cseDef *cdp, set * cseSet) { cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors); cdp->fromGlobal |= loop->fromGlobal; + cdp->fromAddrTaken |= loop->fromAddrTaken; break; } } @@ -93,6 +97,7 @@ updateCseDefAncestors(cseDef *cdp, set * cseSet) { cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors); cdp->fromGlobal |= loop->fromGlobal; + cdp->fromAddrTaken |= loop->fromAddrTaken; break; } } @@ -487,7 +492,7 @@ DEFSETFUNC (findPrevIc) /* if iCodes are not the same */ /* see the operands maybe interchanged */ if (ic->op == cdp->diCode->op && - (ic->op == '+' || ic->op == '*') && + IS_ASSOCIATIVE(ic) && isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) && isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode))) { @@ -532,6 +537,18 @@ DEFSETFUNC (ifDefGlobal) return (isOperandGlobal (cdp->sym)); } +/*-------------------------------------------------------------------*/ +/* ifFromAddrTaken - if definition is derived from a symbol whose */ +/* address was taken */ +/*-------------------------------------------------------------------*/ +DEFSETFUNC (ifFromAddrTaken) +{ + cseDef *cdp = item; + + return cdp->fromAddrTaken; +} + + /*-----------------------------------------------------------------*/ /* ifAnyGetPointer - if get pointer icode */ /*-----------------------------------------------------------------*/ @@ -812,8 +829,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp) if (IS_OP_LITERAL (IC_LEFT (ic)) && operandLitValue (IC_LEFT (ic)) == 0.0) { - if (compareType (operandType (IC_RESULT (ic)), - operandType (IC_RIGHT (ic)))<0) + int typematch; + typematch = compareType (operandType (IC_RESULT (ic)), + operandType (IC_RIGHT (ic))); + if (typematch<0) { ic->op = CAST; IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic))); @@ -822,6 +841,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp) { ic->op = '='; IC_LEFT (ic) = NULL; + if (typematch==0) + { + /* for completely different types, preserve the source type */ + IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic)); + setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic))); + } } SET_ISADDR (IC_RESULT (ic), 0); SET_ISADDR (IC_RIGHT (ic), 0); @@ -830,8 +855,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp) if (IS_OP_LITERAL (IC_RIGHT (ic)) && operandLitValue (IC_RIGHT (ic)) == 0.0) { - if (compareType (operandType (IC_RESULT (ic)), - operandType (IC_LEFT (ic)))<0) + int typematch; + typematch = compareType (operandType (IC_RESULT (ic)), + operandType (IC_LEFT (ic))); + if (typematch<0) { ic->op = CAST; IC_RIGHT (ic) = IC_LEFT (ic); @@ -842,6 +869,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp) ic->op = '='; IC_RIGHT (ic) = IC_LEFT (ic); IC_LEFT (ic) = NULL; + if (typematch==0) + { + /* for completely different types, preserve the source type */ + IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic)); + setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic))); + } } SET_ISADDR (IC_RIGHT (ic), 0); SET_ISADDR (IC_RESULT (ic), 0); @@ -1376,7 +1409,7 @@ void ifxOptimize (iCode * ic, set * cseSet, int computeOnly, eBBlock * ebb, int *change, - eBBlock ** ebbs, int count) + ebbIndex * ebbi) { operand *pdop; symbol *label; @@ -1428,7 +1461,7 @@ ifxOptimize (iCode * ic, set * cseSet, /* this is very expensive but it does not happen */ /* too often, if it does happen then the user pays */ /* the price */ - computeControlFlow (ebbs, count, 1); + computeControlFlow (ebbi); if (!options.lessPedantic) { werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW); } @@ -1440,7 +1473,7 @@ ifxOptimize (iCode * ic, set * cseSet, we can remove this conditional statement */ label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic)); if (elementsInSet (ebb->succList) == 1 && - isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count))) + isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label))) { if (!options.lessPedantic) { @@ -1456,7 +1489,7 @@ ifxOptimize (iCode * ic, set * cseSet, else { remiCodeFromeBBlock (ebb, ic); - computeControlFlow (ebbs, count, 1); + computeControlFlow (ebbi); return; } } @@ -1518,7 +1551,7 @@ constFold (iCode * ic, set * cseSet) ic->op != '-') return 0; - /* this check is a hueristic to prevent live ranges + /* this check is a heuristic to prevent live ranges from becoming too long */ if (IS_PTR (operandType (IC_RESULT (ic)))) return 0; @@ -1528,7 +1561,7 @@ constFold (iCode * ic, set * cseSet) return 0; /* check if we can find a definition for the - right hand side */ + left hand side */ if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic))) return 0; @@ -1751,8 +1784,10 @@ dumpCseSet(set *cseSet) /*-----------------------------------------------------------------*/ int cseBBlock (eBBlock * ebb, int computeOnly, - eBBlock ** ebbs, int count) + ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; set *cseSet; iCode *ic; int change = 0; @@ -1819,8 +1854,12 @@ cseBBlock (eBBlock * ebb, int computeOnly, since they can be modified by the function call */ deleteItemIf (&cseSet, ifDefGlobal); - /* and also itemps derived from globals */ + /* and also iTemps derived from globals */ deleteItemIf (&cseSet, ifFromGlobal); + + /* Delete iTemps derived from symbols whose address */ + /* has been taken */ + deleteItemIf (&cseSet, ifFromAddrTaken); /* delete all getpointer iCodes from cseSet, this should be done only for global arrays & pointers but at this @@ -1936,7 +1975,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, { ifxOptimize (ic, cseSet, computeOnly, ebb, &change, - ebbs, count); + ebbi); continue; } @@ -1974,6 +2013,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* left operand */ /* and left is a symbol */ if (IS_SYMOP (IC_LEFT (ic)) && + !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) && !computeOnly && ic->op != ADDRESS_OF) { @@ -2035,7 +2075,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* if after all this it becomes an assignment to self then delete it and continue */ - if (ASSIGNMENT_TO_SELF (ic)) + if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE)) { remiCodeFromeBBlock (ebb, ic); continue; @@ -2203,15 +2243,17 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* cseAllBlocks - will sequentially go thru & do cse for all blocks */ /*-----------------------------------------------------------------*/ int -cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly) +cseAllBlocks (ebbIndex * ebbi, int computeOnly) { + eBBlock ** ebbs = ebbi->dfOrder; + int count = ebbi->count; int i; int change = 0; /* if optimization turned off */ for (i = 0; i < count; i++) - change += cseBBlock (ebbs[i], computeOnly, ebbs, count); + change += cseBBlock (ebbs[i], computeOnly, ebbi); return change; }