X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCcse.c;h=350e6bb92abe46548b6510e023843eeb539734ff;hb=9a62abdbae6dc14565e2d8b593f6716a90d08119;hp=dc51ea481d0603be56001d7fb85efdf63dfa0ce5;hpb=f531064b9bdf85c649dad884976b42acf0179dfc;p=fw%2Fsdcc diff --git a/src/SDCCcse.c b/src/SDCCcse.c index dc51ea48..350e6bb9 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -83,8 +83,8 @@ pcseDef (void *item, va_list ap) void ReplaceOpWithCheaperOp(operand **op, operand *cop) { #ifdef RANGEHUNT - printf ("ReplaceOpWithCheaperOp %s with %s: ", - IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM", + printf ("ReplaceOpWithCheaperOp %s with %s: ", + IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM", IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM"); // if op is a register equivalent if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) { @@ -107,7 +107,7 @@ void ReplaceOpWithCheaperOp(operand **op, operand *cop) { /* replaceAllSymBySym - replaces all operands by operand in an */ /* instruction chain */ /*-----------------------------------------------------------------*/ -void +void replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) { iCode *lic; @@ -325,8 +325,8 @@ DEFSETFUNC (findCheaperOp) IS_ITEMP (IC_RESULT (cdp->diCode))) *opp = IC_RESULT (cdp->diCode); - if ((*opp) && - (isOperandLiteral(*opp) || !checkSign || + if ((*opp) && + (isOperandLiteral(*opp) || !checkSign || (checkSign && IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) && (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) && @@ -353,11 +353,11 @@ DEFSETFUNC (findCheaperOp) *opp = operandFromOperand (*opp); (*opp)->isaddr = cop->isaddr; } - + if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) && SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp))) { - // special case: we can make an unsigned char literal + // special case: we can make an unsigned char literal // into an int literal with no cost. if (isOperandLiteral(*opp) && SPEC_NOUN(operandType(*opp)) == V_CHAR @@ -372,9 +372,9 @@ DEFSETFUNC (findCheaperOp) *opp = NULL; return 0; } - + } - + return 1; } @@ -517,7 +517,7 @@ DEFSETFUNC (ifOperandsHave) /*-----------------------------------------------------------------*/ /* ifDefSymIs - if a definition is found in the set */ /*-----------------------------------------------------------------*/ -int +int ifDefSymIs (set * cseSet, operand * sym) { cseDef *loop; @@ -554,7 +554,7 @@ DEFSETFUNC (ifDefSymIsX) /*-----------------------------------------------------------------*/ /* ifDiCodeIs - returns truw if diCode is same */ /*-----------------------------------------------------------------*/ -int +int ifDiCodeIs (set * cseSet, iCode * ic) { cseDef *loop; @@ -633,8 +633,8 @@ iCode *findBackwardDef(operand *op,iCode *ic) /*-----------------------------------------------------------------*/ /* algebraicOpts - does some algebraic optimizations */ /*-----------------------------------------------------------------*/ -void -algebraicOpts (iCode * ic) +static void +algebraicOpts (iCode * ic, eBBlock * ebp) { /* we don't deal with the following iCodes here */ @@ -825,8 +825,10 @@ algebraicOpts (iCode * ic) { ic->op = CAST; IC_LEFT (ic)->type = TYPE; + IC_LEFT (ic)->isLiteral = 0; setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic))); } + return; } } @@ -862,6 +864,7 @@ algebraicOpts (iCode * ic) IC_RIGHT (ic) = IC_LEFT (ic); IC_LEFT (ic) = op; IC_LEFT (ic)->type = TYPE; + IC_LEFT (ic)->isLiteral = 0; setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic))); } return; @@ -948,6 +951,201 @@ algebraicOpts (iCode * ic) IC_LEFT (ic) = NULL; SET_ISADDR (IC_RESULT (ic), 0); } + break; + case BITWISEAND: + /* if both operands are equal */ + /* if yes turn it into assignment */ + if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic))) + { + if (IS_OP_VOLATILE (IC_LEFT (ic))) + { + iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + } + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + /* swap literal to right ic */ + if (IS_OP_LITERAL (IC_LEFT (ic))) + { + operand *op; + + op = IC_LEFT (ic); + IC_LEFT (ic) = IC_RIGHT (ic); + IC_RIGHT (ic) = op; + } + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + /* if BITWISEAND then check if one of them is a zero */ + /* if yes turn it into 0 assignment */ + if (operandLitValue (IC_RIGHT (ic)) == 0.0) + { + if (IS_OP_VOLATILE (IC_LEFT (ic))) + { + iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + } + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + /* if BITWISEAND then check if one of them is 0xff... */ + /* if yes turn it into assignment */ + { + unsigned val; + + switch (getSize (operandType (IC_RIGHT (ic)))) + { + case 1: + val = 0xff; + break; + case 2: + val = 0xffff; + break; + case 4: + val = 0xffffffff; + break; + default: + return; + } + if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + } + } + break; + case '|': + /* if both operands are equal */ + /* if yes turn it into assignment */ + if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic))) + { + if (IS_OP_VOLATILE (IC_LEFT (ic))) + { + iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + } + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + /* swap literal to right ic */ + if (IS_OP_LITERAL (IC_LEFT (ic))) + { + operand *op; + + op = IC_LEFT (ic); + IC_LEFT (ic) = IC_RIGHT (ic); + IC_RIGHT (ic) = op; + } + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + /* if BITWISEOR then check if one of them is a zero */ + /* if yes turn it into assignment */ + if (operandLitValue (IC_RIGHT (ic)) == 0.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + /* if BITWISEOR then check if one of them is 0xff... */ + /* if yes turn it into 0xff... assignment */ + { + unsigned val; + + switch (getSize (operandType (IC_RIGHT (ic)))) + { + case 1: + val = 0xff; + break; + case 2: + val = 0xffff; + break; + case 4: + val = 0xffffffff; + break; + default: + return; + } + if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val) + { + if (IS_OP_VOLATILE (IC_LEFT (ic))) + { + iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + } + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + } + } + break; + case '^': + /* if both operands are equal */ + /* if yes turn it into 0 assignment */ + if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic))) + { + if (IS_OP_VOLATILE (IC_LEFT (ic))) + { + iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + + newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic)); + IC_RESULT (newic) = IC_LEFT (ic); + newic->lineno = ic->lineno; + addiCodeToeBBlock (ebp, newic, ic->next); + } + ic->op = '='; + IC_RIGHT (ic) = operandFromLit (0); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + /* swap literal to right ic */ + if (IS_OP_LITERAL (IC_LEFT (ic))) + { + operand *op; + + op = IC_LEFT (ic); + IC_LEFT (ic) = IC_RIGHT (ic); + IC_RIGHT (ic) = op; + } + /* if XOR then check if one of them is a zero */ + /* if yes turn it into assignment */ + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + if (operandLitValue (IC_RIGHT (ic)) == 0.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + } + break; } return; @@ -956,7 +1154,7 @@ algebraicOpts (iCode * ic) /*-----------------------------------------------------------------*/ /* updateSpillLocation - keeps track of register spill location */ /*-----------------------------------------------------------------*/ -void +void updateSpillLocation (iCode * ic, int induction) { sym_link *setype; @@ -1290,9 +1488,9 @@ deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb) list . This will take care of situations like iTemp1 = iTemp0 + 8; iTemp2 = iTemp1 + 8; */ - if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), + if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), (insetwithFunc)isOperandEqual) || - isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), + isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), (insetwithFunc)isOperandEqual)) { addSet (&compItems, IC_RESULT (cdp->diCode)); @@ -1340,7 +1538,7 @@ DEFSETFUNC (delGetPointerSucc) /*-----------------------------------------------------------------*/ /* fixUpTypes - KLUGE HACK fixup a lowering problem */ /*-----------------------------------------------------------------*/ -static void +static void fixUpTypes (iCode * ic) { sym_link *t1 = operandType (IC_LEFT (ic)), *t2; @@ -1417,7 +1615,7 @@ static int isSignedOp (iCode *ic) /* system. also the most important, since almost all */ /* data flow related information is computed by it */ /*-----------------------------------------------------------------*/ -int +int cseBBlock (eBBlock * ebb, int computeOnly, eBBlock ** ebbs, int count) { @@ -1435,12 +1633,12 @@ cseBBlock (eBBlock * ebb, int computeOnly, cseSet = setFromSet (ebb->inExprs); /* these will be computed by this routine */ - setToNull ((void **) &ebb->outDefs); - setToNull ((void **) &ebb->defSet); - setToNull ((void **) &ebb->usesDefs); - setToNull ((void **) &ebb->ptrsSet); - setToNull ((void **) &ebb->addrOf); - setToNull ((void **) &ebb->ldefs); + setToNull ((void *) &ebb->outDefs); + setToNull ((void *) &ebb->defSet); + setToNull ((void *) &ebb->usesDefs); + setToNull ((void *) &ebb->ptrsSet); + setToNull ((void *) &ebb->addrOf); + setToNull ((void *) &ebb->ldefs); ebb->outDefs = bitVectCopy (ebb->inDefs); bitVectDefault = iCodeKey; @@ -1539,10 +1737,13 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* if jumptable then mark the usage */ if (ic->op == JUMPTABLE) { - OP_USES(IC_JTCOND (ic))= - bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key); - setUsesDefs (IC_JTCOND (ic), ebb->defSet, - ebb->outDefs, &ebb->usesDefs); + if (IS_SYMOP (IC_JTCOND (ic))) + { + OP_USES(IC_JTCOND (ic)) = + bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key); + setUsesDefs (IC_JTCOND (ic), ebb->defSet, + ebb->outDefs, &ebb->usesDefs); + } continue; } @@ -1551,7 +1752,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, if (!computeOnly) { /* do some algebraic optimizations if possible */ - algebraicOpts (ic); + algebraicOpts (ic, ebb); while (constFold (ic, cseSet)); } @@ -1587,7 +1788,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /* update the spill location for this */ updateSpillLocation (ic,0); - if (POINTER_SET (ic) && + if (POINTER_SET (ic) && !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype))) { pdop = NULL; @@ -1658,11 +1859,11 @@ cseBBlock (eBBlock * ebb, int computeOnly, change = 1; } } - + /* if left or right changed then do algebraic */ if (!computeOnly && change) { - algebraicOpts (ic); + algebraicOpts (ic, ebb); while (constFold (ic, cseSet)); } @@ -1693,15 +1894,15 @@ cseBBlock (eBBlock * ebb, int computeOnly, if (pdic && compareType (operandType (IC_RESULT (pdic)), operandType (IC_RESULT (ic))) != 1) pdic = NULL; - if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) + if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) pdic = NULL; } /* 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 + /* 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 */ @@ -1709,7 +1910,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, IC_LEFT(ic) = NULL; IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic)); SET_ISADDR(IC_RESULT(ic),0); - SET_ISADDR(IC_RIGHT (ic),0); + SET_ISADDR(IC_RIGHT (ic),0); } } @@ -1817,7 +2018,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, } } - setToNull ((void **) &ebb->outExprs); + setToNull ((void *) &ebb->outExprs); ebb->outExprs = cseSet; ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet); ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet); @@ -1827,7 +2028,7 @@ cseBBlock (eBBlock * ebb, int computeOnly, /*-----------------------------------------------------------------*/ /* cseAllBlocks - will sequentially go thru & do cse for all blocks */ /*-----------------------------------------------------------------*/ -int +int cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly) { int i;