-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
- #define LRH(x) x
-#else
- #define LRH(x)
-#endif
/*-------------------------------------------------------------------------
SDCCcse.c - source file for Common Subexpressions and other utility
#include "common.h"
#include "newalloc.h"
+
/*-----------------------------------------------------------------*/
/* newCseDef - new cseDef */
/*-----------------------------------------------------------------*/
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;
+ }
+ }
+ }
+ }
+}
/*-----------------------------------------------------------------*/
void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
#ifdef RANGEHUNT
- printf ("ReplaceOpWithCheaperOp (%s:%d with %s:%d): ",
- OP_SYMBOL((*op))->name, OP_SYMBOL((*op))->isreqv,
- OP_SYMBOL(cop)->name, OP_SYMBOL(cop)->isreqv);
+ 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) {
operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
/* replaceAllSymBySym - replaces all operands by operand in an */
/* instruction chain */
/*-----------------------------------------------------------------*/
-void
+void
replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
{
iCode *lic;
- LRH(printf ("replaceAllSymBySym: from %s to %s\n", OP_SYMBOL(from)->name, OP_SYMBOL(to)->name));
for (lic = ic; lic; lic = lic->next)
{
int siaddr;
continue;
}
- if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
+ if (IS_SYMOP(to) &&
+ IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
{
/* maintain du chains */
if (POINTER_SET (lic))
/* if the result is volatile then return result */
if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
*opp = IC_RESULT (cdp->diCode);
- else
+ else
/* if this is a straight assignment and
left is a temp then prefer the temporary to the
true symbol */
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)) &&
(SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
{
*opp = operandFromOperand (*opp);
(*opp)->isaddr = cop->isaddr;
}
- LRH(printf ("findCheaperOp: %s < %s\n",\
- IS_SYMOP((*opp)) ? OP_SYMBOL((*opp))->name : "!SYM",\
- OP_SYMBOL(cop)->name));
+
+ 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
+ // into an int literal with no cost.
+ if (isOperandLiteral(*opp)
+ && SPEC_NOUN(operandType(*opp)) == V_CHAR
+ && SPEC_NOUN(operandType(cop)) == V_INT)
+ {
+ *opp = operandFromOperand (*opp);
+ SPEC_NOUN(operandType(*opp)) = V_INT;
+ }
+ else
+ {
+ // No clue...
+ *opp = NULL;
+ return 0;
+ }
+
+ }
+
return 1;
}
if (isiCodeEqual (ic, cdp->diCode) &&
isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
{
- LRH(printf ("findPrevIc same: %d %d\n", ic->key, cdp->diCode->key));
- *icp = cdp->diCode;
+ *icp = cdp->diCode;
return 1;
}
isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
{
- LRH(printf ("findPrevIc inter: %d %d\n", ic->key, cdp->diCode->key));
*icp = cdp->diCode;
return 1;
}
return 0;
}
+/*-------------------------------------------------------------------*/
+/* ifFromGlobal - if definition is derived from global */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifFromGlobal)
+{
+ cseDef *cdp = item;
+
+ return cdp->fromGlobal;
+}
+
/*-----------------------------------------------------------------*/
/* ifDefGlobal - if definition is global */
/*-----------------------------------------------------------------*/
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)
/*-----------------------------------------------------------------*/
/* ifDefSymIs - if a definition is found in the set */
/*-----------------------------------------------------------------*/
-int
+int
ifDefSymIs (set * cseSet, operand * sym)
{
cseDef *loop;
{
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;
}
/*-----------------------------------------------------------------*/
/* ifDiCodeIs - returns truw if diCode is same */
/*-----------------------------------------------------------------*/
-int
+int
ifDiCodeIs (set * cseSet, iCode * ic)
{
cseDef *loop;
iCode *lic;
for (lic = ic; lic ; lic = lic->prev) {
- if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
+ if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
return lic;
}
return NULL;
/*-----------------------------------------------------------------*/
/* 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 */
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;
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;
}
if (operandLitValue (IC_LEFT (ic)) == 1.0)
{
- ic->op = '=';
- IC_LEFT (ic) = NULL;
- SET_RESULT_RIGHT (ic);
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_RIGHT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ ic->op = CAST;
+ IC_LEFT (ic)->type = TYPE;
+ IC_LEFT (ic)->isLiteral = 0;
+ setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+ }
return;
}
}
if (operandLitValue (IC_RIGHT (ic)) == 1.0)
{
- ic->op = '=';
- IC_RIGHT (ic) = IC_LEFT (ic);
- IC_LEFT (ic) = NULL;
- SET_RESULT_RIGHT (ic);
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_LEFT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ operand *op;
+
+ ic->op = CAST;
+ op = IC_RIGHT (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;
}
}
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;
/*-----------------------------------------------------------------*/
/* updateSpillLocation - keeps track of register spill location */
/*-----------------------------------------------------------------*/
-void
+void
updateSpillLocation (iCode * ic, int induction)
{
sym_link *setype;
if (ic->nosupdate)
return;
+#if 0
/* for the form true_symbol := iTempNN */
if (ASSIGN_ITEMP_TO_SYM (ic) &&
!SPIL_LOC (IC_RIGHT (ic))) {
}
}
+#endif
#if 0 /* this needs furthur investigation can save a lot of code */
if (ASSIGN_SYM_TO_ITEMP(ic) &&
/* 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;
}
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;
}
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);
}
}
/*-----------------------------------------------------------------*/
/* fixUpTypes - KLUGE HACK fixup a lowering problem */
/*-----------------------------------------------------------------*/
-static void
+static void
fixUpTypes (iCode * ic)
{
sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
}
}
+#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 */
/* 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)
{
int change = 0;
int i;
set *ptrSetSet = NULL;
+ cseDef *expr;
/* if this block is not reachable */
if (ebb->noPath)
- return change;
+ return 0;
/* set of common subexpressions */
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;
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 */
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 */
/* 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;
}
if (SKIP_IC (ic))
continue;
- /* do some algebraic optimizations if possible */
- algebraicOpts (ic);
- while (constFold (ic, cseSet));
+ if (!computeOnly) {
+ /* do some algebraic optimizations if possible */
+ algebraicOpts (ic, ebb);
+ while (constFold (ic, cseSet));
+ }
/* small klugde */
if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
}
- /* if this is a condition statment then */
+ /* if this is a condition statement then */
/* check if the condition can be replaced */
if (ic->op == IFX)
{
/* if the assignment & result is a temp */
/* see if we can replace it */
- if (ic->op == '=')
+ if (!computeOnly && ic->op == '=')
{
/* update the spill location for this */
{
pdop = NULL;
applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
- if (pdop && IS_ITEMP (pdop) && !computeOnly)
+ if (pdop && !computeOnly &&
+ IS_ITEMP (pdop) && IS_PTR(operandType(pdop)))
ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
}
}
change = 1;
}
}
-
+
/* if left or right changed then do algebraic */
- if (change)
+ if (!computeOnly && change)
{
- algebraicOpts (ic);
+ algebraicOpts (ic, ebb);
while (constFold (ic, cseSet));
}
- /* if after all this it becomes a assignment to self
+ /* if after all this it becomes an assignment to self
then delete it and continue */
if (ASSIGNMENT_TO_SELF (ic))
{
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 */
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);
}
}
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;
}
}
- setToNull ((void **) &ebb->outExprs);
+ 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);
ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
/*-----------------------------------------------------------------*/
/* cseAllBlocks - will sequentially go thru & do cse for all blocks */
/*-----------------------------------------------------------------*/
-int
-cseAllBlocks (eBBlock ** ebbs, int count)
+int
+cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
{
int i;
int change = 0;
/* if optimization turned off */
for (i = 0; i < count; i++)
- change += cseBBlock (ebbs[i], FALSE, ebbs, count);
+ change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
return change;
}