* src/SDCCcse.c (cseBBlock, newCseDef, ifFromAddrTaken): purge CSEs
over a function call if the CSE is derived from a symbol whose
address has been taken (fixes bug #
1029883)
* support/regression/tests/bug-
1029883: a new regression test for
this bug
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3501
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2004-09-19 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * src/SDCCcse.h (struct cseDef),
+ * src/SDCCcse.c (cseBBlock, newCseDef, ifFromAddrTaken): purge CSEs
+ over a function call if the CSE is derived from a symbol whose
+ address has been taken (fixes bug #1029883)
+ * support/regression/tests/bug-1029883: a new regression test for
+ this bug
+
2004-09-18 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/hc08/gen.c (emitinline): fixed bug #1029778
2004-09-18 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/hc08/gen.c (emitinline): fixed bug #1029778
cdp->key = sym->key;
cdp->ancestors = newBitVect(iCodeKey);
cdp->fromGlobal = 0;
cdp->key = sym->key;
cdp->ancestors = newBitVect(iCodeKey);
cdp->fromGlobal = 0;
+ cdp->fromAddrTaken = 0;
if (ic->op!=IF && ic->op!=JUMPTABLE)
{
if (ic->op!=IF && ic->op!=JUMPTABLE)
{
{
bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
{
bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
+ cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken;
}
if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
{
bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
}
if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
{
bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
+ cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
return (isOperandGlobal (cdp->sym));
}
return (isOperandGlobal (cdp->sym));
}
+/*-------------------------------------------------------------------*/
+/* ifFromAddrTaken - if definition is derived from a symbol whose */
+/* address was taken */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifFromAddrTaken)
+{
+ cseDef *cdp = item;
+
+ return cdp->fromAddrTaken;
+}
+
+
/*-----------------------------------------------------------------*/
/* ifAnyGetPointer - if get pointer icode */
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* ifAnyGetPointer - if get pointer icode */
/*-----------------------------------------------------------------*/
since they can be modified by the function call */
deleteItemIf (&cseSet, ifDefGlobal);
since they can be modified by the function call */
deleteItemIf (&cseSet, ifDefGlobal);
- /* and also itemps derived from globals */
+ /* and also iTemps derived from globals */
deleteItemIf (&cseSet, ifFromGlobal);
deleteItemIf (&cseSet, ifFromGlobal);
+
+ /* Delete iTemps derived from symbols whose address */
+ /* has been taken */
+ deleteItemIf (&cseSet, ifFromAddrTaken);
/* delete all getpointer iCodes from cseSet, this should
be done only for global arrays & pointers but at this
/* delete all getpointer iCodes from cseSet, this should
be done only for global arrays & pointers but at this
iCode *diCode; /* defining instruction */
bitVect *ancestors; /* keys of the symbol's ancestors */
int fromGlobal:1; /* defining symbol's value computed from a global */
iCode *diCode; /* defining instruction */
bitVect *ancestors; /* keys of the symbol's ancestors */
int fromGlobal:1; /* defining symbol's value computed from a global */
+ int fromAddrTaken:1; /* defining symbol's value computed from a */
+ /* symbol whose address was taken */
--- /dev/null
+/* Make sure global common subexpression optimization does not
+ inappropriately cache values across function calls.
+
+ sign1: signed, unsigned
+ sign2: signed, unsigned
+ type: int
+
+ */
+#include <testfwk.h>
+
+typedef struct
+{
+ {sign1} {type} field1;
+ {sign1} {type} *field2;
+ {sign1} {type} field3;
+} struct1;
+
+
+void
+spoil({sign1} {type} val)
+{
+ UNUSED(val);
+}
+
+void
+inc1({sign1} {type} *valptr)
+{
+ (*valptr)++;
+}
+
+{sign2}
+gcse1({sign2} {type} target)
+{
+ spoil(target);
+ inc1(&target);
+ return target;
+}
+
+
+void
+inc2(struct1 *s)
+{
+ (*s->field2)++;
+}
+
+{sign2}
+gcse2({sign2} {type} target)
+{
+ struct1 s;
+
+ s.field2 = &s.field3;
+ *s.field2 = target;
+ spoil(s.field3);
+ inc2(&s);
+ return s.field3;
+}
+
+
+void
+testgcse(void)
+{
+ ASSERT(gcse1(1)==2);
+ ASSERT(gcse2(1)==2);
+}