#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;
+ }
+ }
+ }
+ }
+}
/*-----------------------------------------------------------------*/
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)
{
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;
}
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;
/* 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;
}
{
if (!options.lessPedantic) {
- werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
}
if (IS_OP_VOLATILE (IC_COND (ic)))
{
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))
- {
- /* 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))
+ if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
{
- 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);
}
}
}
}
+#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 */
int change = 0;
int i;
set *ptrSetSet = NULL;
+ cseDef *expr;
/* if this block is not reachable */
if (ebb->noPath)
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 (!(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;
}
}
+ 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);