From 59456663963fc7a4b0f67f42780419de513bae62 Mon Sep 17 00:00:00 2001 From: epetrich Date: Sun, 19 Sep 2004 01:09:16 +0000 Subject: [PATCH] * 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 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3501 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 9 ++++ src/SDCCcse.c | 23 ++++++++- src/SDCCcse.h | 2 + support/regression/tests/bug-1029883.c | 64 ++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 support/regression/tests/bug-1029883.c diff --git a/ChangeLog b/ChangeLog index 60fae425..20b19185 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-09-19 Erik Petrich + + * 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 * src/hc08/gen.c (emitinline): fixed bug #1029778 diff --git a/src/SDCCcse.c b/src/SDCCcse.c index 51dc9977..28387659 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -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 diff --git a/src/SDCCcse.h b/src/SDCCcse.h index 0074f75e..0e7c9c8a 100644 --- a/src/SDCCcse.h +++ b/src/SDCCcse.h @@ -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 index 00000000..eb2850ff --- /dev/null +++ b/support/regression/tests/bug-1029883.c @@ -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 + +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); +} -- 2.30.2