X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2FSDCCcse.c;h=24bd57b5d2cc8ad88a582b06a7d54c48031baef3;hb=f3946e669d77d841b638d798c3e09429cd3338c6;hp=e9b2d87eb8be7fd9cd3f453d25077f3cdf388269;hpb=2cafd4e83b33d8f8e604bd37803dda0c3d7d4aff;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index e9b2d87e..24bd57b5 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -25,6 +25,7 @@ #include "common.h" #include "newalloc.h" + /*-----------------------------------------------------------------*/ /* newCseDef - new cseDef */ /*-----------------------------------------------------------------*/ @@ -39,10 +40,65 @@ newCseDef (operand * sym, iCode * ic) cdp->sym = sym; cdp->diCode = ic; cdp->key = sym->key; + cdp->ancestors = newBitVect(iCodeKey); + cdp->fromGlobal = 0; + if (ic->op!=IF && ic->op!=JUMPTABLE) + { + if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))) + { + bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key); + cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic)); + } + if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))) + { + bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key); + cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic)); + } + } + return cdp; } +void +updateCseDefAncestors(cseDef *cdp, set * cseSet) +{ + cseDef *loop; + set *sl; + iCode *ic = cdp->diCode; + + if (ic->op!=IF && ic->op!=JUMPTABLE) + { + if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))) + { + bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key); + for (sl = cseSet; sl; sl = sl->next) + { + loop = sl->item; + if (loop->sym->key == IC_LEFT (ic)->key) + { + cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors); + cdp->fromGlobal |= loop->fromGlobal; + break; + } + } + } + if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))) + { + bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key); + for (sl = cseSet; sl; sl = sl->next) + { + loop = sl->item; + if (loop->sym->key == IC_RIGHT (ic)->key) + { + cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors); + cdp->fromGlobal |= loop->fromGlobal; + break; + } + } + } + } +} /*-----------------------------------------------------------------*/ @@ -456,6 +512,16 @@ DEFSETFUNC (ifAssignedFromGlobal) return 0; } +/*-------------------------------------------------------------------*/ +/* ifFromGlobal - if definition is derived from global */ +/*-------------------------------------------------------------------*/ +DEFSETFUNC (ifFromGlobal) +{ + cseDef *cdp = item; + + return cdp->fromGlobal; +} + /*-----------------------------------------------------------------*/ /* ifDefGlobal - if definition is global */ /*-----------------------------------------------------------------*/ @@ -486,7 +552,9 @@ DEFSETFUNC (ifOperandsHave) cseDef *cdp = item; V_ARG (operand *, op); - + if (bitVectBitValue(cdp->ancestors, op->key)) + return 1; + if (IC_LEFT (cdp->diCode) && IS_SYMOP (IC_LEFT (cdp->diCode)) && IC_LEFT (cdp->diCode)->key == op->key) @@ -542,12 +610,17 @@ DEFSETFUNC (ifDefSymIsX) { cseDef *cdp = item; V_ARG (operand *, op); - + int match; + if (op && cdp->sym) - return cdp->sym->key == op->key; + match = cdp->sym->key == op->key; else - return (isOperandEqual (cdp->sym, op)); - + match = (isOperandEqual (cdp->sym, op)); + #if 0 + if (match) + printf("%s ",OP_SYMBOL(cdp->sym)->name); + #endif + return match; } @@ -735,13 +808,21 @@ algebraicOpts (iCode * ic, eBBlock * ebp) return; } /* if addition then check if one of them is a zero */ - /* if yes turn it into assignmnt */ + /* if yes turn it into assignmnt or cast */ if (IS_OP_LITERAL (IC_LEFT (ic)) && operandLitValue (IC_LEFT (ic)) == 0.0) { - - ic->op = '='; - IC_LEFT (ic) = NULL; + if (compareType (operandType (IC_RESULT (ic)), + operandType (IC_RIGHT (ic)))<0) + { + ic->op = CAST; + IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic))); + } + else + { + ic->op = '='; + IC_LEFT (ic) = NULL; + } SET_ISADDR (IC_RESULT (ic), 0); SET_ISADDR (IC_RIGHT (ic), 0); return; @@ -749,10 +830,19 @@ algebraicOpts (iCode * ic, eBBlock * ebp) if (IS_OP_LITERAL (IC_RIGHT (ic)) && operandLitValue (IC_RIGHT (ic)) == 0.0) { - - ic->op = '='; - IC_RIGHT (ic) = IC_LEFT (ic); - IC_LEFT (ic) = 0; + if (compareType (operandType (IC_RESULT (ic)), + operandType (IC_LEFT (ic)))<0) + { + ic->op = CAST; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic))); + } + else + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + } SET_ISADDR (IC_RIGHT (ic), 0); SET_ISADDR (IC_RESULT (ic), 0); return; @@ -1334,7 +1424,7 @@ ifxOptimize (iCode * ic, set * cseSet, /* the price */ computeControlFlow (ebbs, count, 1); if (!options.lessPedantic) { - werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW); } return; } @@ -1347,18 +1437,36 @@ ifxOptimize (iCode * ic, set * cseSet, isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count))) { - remiCodeFromeBBlock (ebb, ic); - computeControlFlow (ebbs, count, 1); if (!options.lessPedantic) { - werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW); } - return; + if (IS_OP_VOLATILE (IC_COND (ic))) + { + IC_RIGHT (ic) = IC_COND (ic); + IC_LEFT (ic) = NULL; + IC_RESULT (ic) = NULL; + ic->op = DUMMY_READ_VOLATILE; + } + else + { + remiCodeFromeBBlock (ebb, ic); + computeControlFlow (ebbs, count, 1); + return; + } } /* if it remains an IFX the update the use Set */ - OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key); - setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + if (ic->op == IFX) + { + OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key); + setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + } + else if (ic->op == DUMMY_READ_VOLATILE) + { + OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key); + setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + } return; } @@ -1467,50 +1575,52 @@ deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb) set *compItems = NULL; cseDef *cdp; operand *cop; + int changes; /* easy return */ if (!*cseSet && !*pss) return; - /* first find all items computed from this operand . + addSet (&compItems, op); + + /* Recursively find all items computed from this operand . This done fairly simply go thru the list and find - those that are computed by arthimetic with this - op */ - for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet)) + those that are computed by arthimetic with these + ops */ + /* Also check for those computed from our computed + list . This will take care of situations like + iTemp1 = iTemp0 + 8; + iTemp2 = iTemp1 + 8; */ + do { - if (IS_ARITHMETIC_OP (cdp->diCode)) + changes = 0; + for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet)) { - if (isOperandEqual (IC_LEFT (cdp->diCode), op) || - isOperandEqual (IC_RIGHT (cdp->diCode), op)) + if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode)) { - /* save it in our list of items */ - addSet (&compItems, IC_RESULT (cdp->diCode)); - } - /* also check for those computed from our computed - list . This will take care of situations like - iTemp1 = iTemp0 + 8; - iTemp2 = iTemp1 + 8; */ - if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), - (insetwithFunc)isOperandEqual) || - isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), - (insetwithFunc)isOperandEqual)) - { - addSet (&compItems, IC_RESULT (cdp->diCode)); + if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), + (insetwithFunc)isOperandEqual) || + isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), + (insetwithFunc)isOperandEqual)) + { + if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode), + (insetwithFunc)isOperandEqual)) + { + addSet (&compItems, IC_RESULT (cdp->diCode)); + changes++; + } + } } } } - - /* now delete all pointer gets with this op */ - deleteItemIf (cseSet, ifPointerGet, op); - deleteItemIf (pss, ifPointerSet, op); - - /* set the bit vector used by dataFlow computation later */ - ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key); + while (changes); + /* now for the computed items */ for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems)) { ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key); deleteItemIf (cseSet, ifPointerGet, cop); + deleteItemIf (cseSet, ifDefSymIsX, cop); deleteItemIf (pss, ifPointerSet, cop); } } @@ -1611,6 +1721,22 @@ static int isSignedOp (iCode *ic) } } +#if 0 +static void +dumpCseSet(set *cseSet) +{ + while (cseSet) + { + cseDef *item=cseSet->item; + printf("->"); + printOperand (item->sym, NULL); + printf(" "); + piCode (item->diCode, NULL); + cseSet = cseSet->next; + } +} +#endif + /*-----------------------------------------------------------------*/ /* cseBBlock - common subexpression elimination for basic blocks */ /* this is the hackiest kludgiest routine in the whole */ @@ -1626,6 +1752,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, int change = 0; int i; set *ptrSetSet = NULL; + cseDef *expr; /* if this block is not reachable */ if (ebb->noPath) @@ -1666,7 +1793,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, IS_PTR (operandType (IC_RESULT (ic)))) { ptrPostIncDecOpt (ic); - } + } /* clear the def & use chains for the operands involved */ /* in this operation . since it can change due to opts */ @@ -1686,13 +1813,16 @@ cseBBlock (eBBlock * ebb, int computeOnly, since they can be modified by the function call */ deleteItemIf (&cseSet, ifDefGlobal); - /* and also itemps assigned from globals */ - deleteItemIf (&cseSet, ifAssignedFromGlobal); + /* and also itemps derived from globals */ + deleteItemIf (&cseSet, ifFromGlobal); /* 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 */ deleteItemIf (&cseSet, ifAnyGetPointer); + + /* can't cache pointer set/get operations across a call */ + deleteSet (&ptrSetSet); } /* for pcall & ipush we need to add to the useSet */ @@ -1917,8 +2047,11 @@ cseBBlock (eBBlock * ebb, int computeOnly, } if (!(POINTER_SET (ic)) && IC_RESULT (ic)) { + cseDef *csed; deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic)); - addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic)); + csed = newCseDef (IC_RESULT (ic), ic); + updateCseDefAncestors (csed, cseSet); + addSetHead (&cseSet, csed); } defic = ic; @@ -2020,6 +2153,11 @@ cseBBlock (eBBlock * ebb, int computeOnly, } } + for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs)) + if (!isinSetWith (cseSet, expr, isCseDefEqual) && + !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) { + addSetHead (&ebb->killedExprs, expr); + } setToNull ((void *) &ebb->outExprs); ebb->outExprs = cseSet; ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);