+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
cdp->key = sym->key;
cdp->ancestors = newBitVect(iCodeKey);
cdp->fromGlobal = 0;
+ cdp->fromAddrTaken = 0;
if (ic->op!=IF && ic->op!=JUMPTABLE)
{
{
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));
+ cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
}
}
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
break;
}
}
{
cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
break;
}
}
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 */
/*-----------------------------------------------------------------*/
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);
+
+ /* 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
--- /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);
+}