* src/SDCCcse.h (struct cseDef),
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 19 Sep 2004 01:09:16 +0000 (01:09 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 19 Sep 2004 01:09:16 +0000 (01:09 +0000)
* 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

ChangeLog
src/SDCCcse.c
src/SDCCcse.h
support/regression/tests/bug-1029883.c [new file with mode: 0644]

index 60fae42589d82bfcfbeaec588e07fc2e3291f7d6..20b19185a314188058ddf896c59ddf363b444e0f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+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
index 51dc99775f283b7a5f0d043f5f108d10f22dcb9f..2838765943e4c7a958858461c51af39824803762 100644 (file)
@@ -42,6 +42,7 @@ newCseDef (operand * sym, iCode * ic)
   cdp->key = sym->key;
   cdp->ancestors = newBitVect(iCodeKey);
   cdp->fromGlobal = 0;
+  cdp->fromAddrTaken = 0;
 
   if (ic->op!=IF && ic->op!=JUMPTABLE)
     {
@@ -49,11 +50,13 @@ newCseDef (operand * sym, iCode * 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));
+          cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
         }
     }
 
@@ -79,6 +82,7 @@ updateCseDefAncestors(cseDef *cdp, set * cseSet)
                 {
                   cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
                   cdp->fromGlobal |= loop->fromGlobal;
+                  cdp->fromAddrTaken |= loop->fromAddrTaken;
                   break;
                 }
             }
@@ -93,6 +97,7 @@ updateCseDefAncestors(cseDef *cdp, set * cseSet)
                 {
                   cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
                   cdp->fromGlobal |= loop->fromGlobal;
+                  cdp->fromAddrTaken |= loop->fromAddrTaken;
                   break;
                 }
             }
@@ -532,6 +537,18 @@ DEFSETFUNC (ifDefGlobal)
   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                          */
 /*-----------------------------------------------------------------*/
@@ -1819,8 +1836,12 @@ cseBBlock (eBBlock * ebb, int computeOnly,
              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
index 0074f75eb9098dd29dc13502c76b2ed025b5a845..0e7c9c8ab39721b39aff805e439050d40c394e51 100644 (file)
@@ -36,6 +36,8 @@ typedef struct cseDef
     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 */
   }
 cseDef;
 
diff --git a/support/regression/tests/bug-1029883.c b/support/regression/tests/bug-1029883.c
new file mode 100644 (file)
index 0000000..eb2850f
--- /dev/null
@@ -0,0 +1,64 @@
+/*  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);
+}