* src/SDCCcflow.c (dfNumCompare): committed the wrong version of this
[fw/sdcc] / src / SDCCcse.c
index 51dc99775f283b7a5f0d043f5f108d10f22dcb9f..ad94b3a58a55a5e38d4245dd87f8c9b7f8246c97 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                          */
 /*-----------------------------------------------------------------*/
@@ -1376,7 +1393,7 @@ void
 ifxOptimize (iCode * ic, set * cseSet,
              int computeOnly,
              eBBlock * ebb, int *change,
-             eBBlock ** ebbs, int count)
+             ebbIndex * ebbi)
 {
   operand *pdop;
   symbol *label;
@@ -1428,7 +1445,7 @@ ifxOptimize (iCode * ic, set * cseSet,
       /* this is very expensive but it does not happen */
       /* too often, if it does happen then the user pays */
       /* the price */
-      computeControlFlow (ebbs, count, 1);
+      computeControlFlow (ebbi);
       if (!options.lessPedantic) {
         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
       }
@@ -1440,7 +1457,7 @@ ifxOptimize (iCode * ic, set * cseSet,
      we can remove this conditional statement */
   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
   if (elementsInSet (ebb->succList) == 1 &&
-      isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
+      isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
     {
 
       if (!options.lessPedantic) {
@@ -1456,7 +1473,7 @@ ifxOptimize (iCode * ic, set * cseSet,
       else
         {
           remiCodeFromeBBlock (ebb, ic);
-          computeControlFlow (ebbs, count, 1);
+          computeControlFlow (ebbi);
           return;
         }
     }
@@ -1751,8 +1768,10 @@ dumpCseSet(set *cseSet)
 /*-----------------------------------------------------------------*/
 int
 cseBBlock (eBBlock * ebb, int computeOnly,
-           eBBlock ** ebbs, int count)
+           ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   set *cseSet;
   iCode *ic;
   int change = 0;
@@ -1819,8 +1838,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
@@ -1936,7 +1959,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
         {
           ifxOptimize (ic, cseSet, computeOnly,
                        ebb, &change,
-                       ebbs, count);
+                       ebbi);
           continue;
         }
 
@@ -1974,6 +1997,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* left operand */
       /* and left is a symbol  */
       if (IS_SYMOP (IC_LEFT (ic)) &&
+          !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
           !computeOnly && ic->op != ADDRESS_OF)
         {
 
@@ -2035,7 +2059,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 
       /* if after all this it becomes an assignment to self
          then delete it and continue */
-      if (ASSIGNMENT_TO_SELF (ic))
+      if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
         {
           remiCodeFromeBBlock (ebb, ic);
           continue;
@@ -2203,15 +2227,17 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
 /*-----------------------------------------------------------------*/
 int
-cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
+cseAllBlocks (ebbIndex * ebbi, int computeOnly)
 {
+  eBBlock ** ebbs = ebbi->dfOrder;
+  int count = ebbi->count;
   int i;
   int change = 0;
 
   /* if optimization turned off */
 
   for (i = 0; i < count; i++)
-    change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
+    change += cseBBlock (ebbs[i], computeOnly, ebbi);
 
   return change;
 }