+2003-11-25 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ Fixed several common-sub-expression bugs (#772861, #768380, & #755323)
+ * src/SDCCdflow.c
+ * src/SDCCcse.c
+ * src/SDCCcse.h
+ * src/SDCCBBlock.h
+ * src/SDCCBBlock.c
+
2003-11-23 Klaus Flittner <klaus_flittner@gmx.de>
fixed bug #845089
FILE *of;
int i;
eBBlock *bb;
+ set *cseSet;
if (id) {
of=createDumpFile(id);
fprintf (of, "\nInductions Set bitvector :");
bitVectDebugOn (ebbs[i]->linds, of);
}
+
+ fprintf (of, "\ninExprs:");
+ for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) {
+ cseDef *item=cseSet->item;
+ fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+ if (item->fromGlobal)
+ fprintf (of, "g");
+ }
+ fprintf (of, "\noutExprs:");
+ for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) {
+ cseDef *item=cseSet->item;
+ fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+ if (item->fromGlobal)
+ fprintf (of, "g");
+ }
+ fprintf (of, "\nkilledExprs:");
+ for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) {
+ cseDef *item=cseSet->item;
+ fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+ if (item->fromGlobal)
+ fprintf (of, "g");
+ }
+
fprintf (of, "\n----------------------------------------------------------------\n");
printiCChain (ebbs[i]->sch, of);
}
/* data flow analysis */
set *inExprs; /* in coming common expressions */
set *outExprs; /* out going common expressions */
+ set *killedExprs; /* killed common expressions */
bitVect *inDefs; /* in coming defintions */
bitVect *outDefs; /* out going defintions */
bitVect *defSet; /* symbols defined in block */
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;
}
{
ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
deleteItemIf (cseSet, ifPointerGet, cop);
+ deleteItemIf (cseSet, ifDefSymIsX, cop);
deleteItemIf (pss, ifPointerSet, cop);
}
}
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
}
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);
unsigned int key;
operand *sym; /* defining symbol */
iCode *diCode; /* defining instruction */
-
+ bitVect *ancestors; /* keys of the symbol's ancestors */
+ int fromGlobal:1; /* defining symbol's value computed from a global */
}
cseDef;
(IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
bitVectBitsInCommon (src->defSet, OP_DEFS (IC_RIGHT (cdp->diCode))))))
return 1;
+
+ /* kill if cseBBlock() found a case we missed here */
+ if (isinSetWith(src->killedExprs, cdp, isCseDefEqual))
+ return 1;
return 0;
}
V_ARG (eBBlock *, dest);
V_ARG (int *, firstTime);
+ dest->killedExprs = unionSets (dest->killedExprs, ebp->killedExprs, THROW_DEST);
+
/* if in the dominator list then */
if (bitVectBitValue (dest->domVect, ebp->bbnum) && dest != ebp)
{
}
else
{
- cseDef *expr;
-
- /* cseBBlock does a much more thorough analysis than */
- /* ifKilledInBlock. Anything that is listed in inExprs */
- /* but not in outExprs must have been killed somehow. */
- for (expr=setFirstItem(ebp->inExprs); expr; expr=setNextItem(ebp->inExprs))
- if (!isinSet(ebp->outExprs, expr))
- deleteSetItem (&dest->inExprs, expr);
-
- /* delete only if killed in this block */
+ /* delete only if killed in this block*/
deleteItemIf (&dest->inExprs, ifKilledInBlock, ebp);
/* union the ndompset with pointers set in this block */
dest->ndompset = bitVectUnion (dest->ndompset, ebp->ptrsSet);
}
-
*firstTime = 0;
return 0;
}
+
/*-----------------------------------------------------------------*/
/* mergeInDefs - merge in incoming definitions */
/*-----------------------------------------------------------------*/
{
int i;
int change = 1;
-
+
+ for (i = 0; i < count; i++)
+ ebbs[i]->killedExprs = NULL;
+
while (change)
{
-
change = 0;
/* for all blocks */
set *pred;
set *oldOutExprs = NULL;
+ set *oldKilledExprs = NULL;
bitVect *oldOutDefs = NULL;
int firstTime;
eBBlock *pBlock;
/* make a copy of the outExpressions or outDefs : to be */
/* used for iteration */
if (optimize.global_cse)
- oldOutExprs = setFromSet (ebbs[i]->outExprs);
+ {
+ oldOutExprs = setFromSet (ebbs[i]->outExprs);
+ oldKilledExprs = setFromSet (ebbs[i]->killedExprs);
+ }
else
oldOutDefs = bitVectCopy (ebbs[i]->outDefs);
setToNull ((void *) &ebbs[i]->inDefs);
if (idom)
addSetHead (&pred, idom);
}
-
+
/* figure out the incoming expressions */
/* this is a little more complex */
setToNull ((void *) &ebbs[i]->inExprs);
/* if it change we will need to iterate */
if (optimize.global_cse)
- change += !isSetsEqualWith (ebbs[i]->outExprs, oldOutExprs, isCseDefEqual);
+ {
+ change += !isSetsEqualWith (ebbs[i]->outExprs, oldOutExprs, isCseDefEqual);
+ change += !isSetsEqualWith (ebbs[i]->killedExprs, oldKilledExprs, isCseDefEqual);
+ }
else
change += !bitVectEqual (ebbs[i]->outDefs, oldOutDefs);
}
- if (!change) /* iterate till no change */
- break;
+ if (!change) /* iterate till no change */
+ break;
}
return;