Applied patch #2762516
[fw/sdcc] / src / SDCCcse.c
index b720c2622ab23a0aeee729d6c24a8d317602ff2d..1b43a42850a335c01fc35c78d708e5cddef2da30 100644 (file)
@@ -1,9 +1,3 @@
-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
-  #define LRH(x) x
-#else
-  #define LRH(x)
-#endif
 /*-------------------------------------------------------------------------
   SDCCcse.c - source file for Common Subexpressions and other utility
 
@@ -30,6 +24,8 @@
 
 #include "common.h"
 #include "newalloc.h"
+#include "dbuf_string.h"
+
 
 /*-----------------------------------------------------------------*/
 /* newCseDef - new cseDef                                          */
@@ -45,16 +41,76 @@ newCseDef (operand * sym, iCode * ic)
   cdp->sym = sym;
   cdp->diCode = ic;
   cdp->key = sym->key;
+  cdp->ancestors = newBitVect(iCodeKey);
+  cdp->fromGlobal = 0;
+  cdp->fromAddrTaken = 0;
+
+  if (ic->op!=IF && ic->op!=JUMPTABLE)
+    {
+      if (IC_LEFT (ic) && IS_SYMOP (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));
+          cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
+        }
+    }
 
   return cdp;
 }
 
+void
+updateCseDefAncestors(cseDef *cdp, set * cseSet)
+{
+  cseDef *loop;
+  set *sl;
+  iCode *ic = cdp->diCode;
+
+  if (ic->op!=IF && ic->op!=JUMPTABLE)
+    {
+      if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
+        {
+          bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
+          for (sl = cseSet; sl; sl = sl->next)
+            {
+              loop = sl->item;
+              if (loop->sym->key == IC_LEFT (ic)->key)
+                {
+                  cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
+                  cdp->fromGlobal |= loop->fromGlobal;
+                  cdp->fromAddrTaken |= loop->fromAddrTaken;
+                  break;
+                }
+            }
+        }
+      if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
+        {
+          bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
+          for (sl = cseSet; sl; sl = sl->next)
+            {
+              loop = sl->item;
+              if (loop->sym->key == IC_RIGHT (ic)->key)
+                {
+                  cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
+                  cdp->fromGlobal |= loop->fromGlobal;
+                  cdp->fromAddrTaken |= loop->fromAddrTaken;
+                  break;
+                }
+            }
+        }
+    }
+}
 
 
 /*-----------------------------------------------------------------*/
 /* int isCseDefEqual - two definitions are equal                   */
 /*-----------------------------------------------------------------*/
-int 
+int
 isCseDefEqual (void *vsrc, void *vdest)
 {
   cseDef *src = vsrc;
@@ -64,18 +120,19 @@ isCseDefEqual (void *vsrc, void *vdest)
     return 1;
 
   return (src->key == dest->key &&
-         src->diCode == dest->diCode);
+          src->diCode == dest->diCode);
 
 }
 
 /*-----------------------------------------------------------------*/
 /* pcseDef - in the cseDef                                         */
 /*-----------------------------------------------------------------*/
-int 
+int
 pcseDef (void *item, va_list ap)
 {
   cseDef *cdp = item;
   iCodeTable *icTab;
+  struct dbuf_s dbuf;
 
   (void) ap;
 
@@ -83,17 +140,21 @@ pcseDef (void *item, va_list ap)
     fprintf (stdout, "**null op**");
   printOperand (cdp->sym, stdout);
   icTab = getTableEntry (cdp->diCode->op);
-  icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
+  dbuf_init (&dbuf, 1024);
+  icTab->iCodePrint (&dbuf, cdp->diCode, icTab->printName);
+  dbuf_write_and_destroy (&dbuf, stdout);
   return 1;
 }
 
 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
 #ifdef RANGEHUNT
-  printf ("ReplaceOpWithCheaperOp (%s:%d with %s:%d): ", 
-         OP_SYMBOL((*op))->name, OP_SYMBOL((*op))->isreqv,
-         OP_SYMBOL(cop)->name, OP_SYMBOL(cop)->isreqv);
+  printf ("ReplaceOpWithCheaperOp\n\t");
+  printOperand (*op, stdout);
+  printf ("\nwith\t");
+  printOperand (cop, stdout);
+
   // if op is a register equivalent
-  if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+  if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
     operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
     if (isOperandEqual(*rop, *op)) {
       printf ("true");
@@ -113,95 +174,102 @@ void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
 /* replaceAllSymBySym - replaces all operands by operand in an     */
 /*                      instruction chain                          */
 /*-----------------------------------------------------------------*/
-void 
+void
 replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 {
   iCode *lic;
 
-  LRH(printf ("replaceAllSymBySym: from %s to %s\n", OP_SYMBOL(from)->name, OP_SYMBOL(to)->name));
+#ifdef RANGEHUNT
+  printf ("replaceAllSymBySym\n\t");
+  printOperand (from, stdout);
+  printf ("\nwith\t");
+  printOperand (to, stdout);
+  printf ("\n");
+#endif
   for (lic = ic; lic; lic = lic->next)
     {
-      int siaddr;
+      int isaddr;
 
       /* do the special cases first */
       if (lic->op == IFX)
-       {
-         if (IS_SYMOP (to) &&
-             IC_COND (lic)->key == from->key)
-           {
-
-             bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-             siaddr = IC_COND (lic)->isaddr;
-             IC_COND (lic) = operandFromOperand (to);
-             IC_COND (lic)->isaddr = siaddr;
-
-           }
-         continue;
-       }
+        {
+          if (IS_SYMOP (to) &&
+              IC_COND (lic)->key == from->key)
+            {
+
+              bitVectUnSetBit (OP_USES (from), lic->key);
+              OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
+              isaddr = IC_COND (lic)->isaddr;
+              IC_COND (lic) = operandFromOperand (to);
+              IC_COND (lic)->isaddr = isaddr;
+
+            }
+          continue;
+        }
 
       if (lic->op == JUMPTABLE)
-       {
-         if (IS_SYMOP (to) &&
-             IC_JTCOND (lic)->key == from->key)
-           {
-
-             bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-             siaddr = IC_COND (lic)->isaddr;
-             IC_JTCOND (lic) = operandFromOperand (to);
-             IC_JTCOND (lic)->isaddr = siaddr;
-
-           }
-         continue;
-       }
-
-      if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
-       {
-         /* maintain du chains */
-         if (POINTER_SET (lic))
-           {
-             bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-
-             /* also check if the "from" was in the non-dominating
-                pointer sets and replace it with "to" in the bitVector */
-             if (bitVectBitValue (*ndpset, from->key))
-               {
-                 bitVectUnSetBit (*ndpset, from->key);
-                 bitVectSetBit (*ndpset, to->key);
-               }
-
-           }
-         else
-           {
-             bitVectUnSetBit (OP_DEFS (from), lic->key);
-             OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
-           }
-         siaddr = IC_RESULT (lic)->isaddr;
-         IC_RESULT (lic) = operandFromOperand (to);
-         IC_RESULT (lic)->isaddr = siaddr;
-       }
+        {
+          if (IS_SYMOP (to) &&
+              IC_JTCOND (lic)->key == from->key)
+            {
+
+              bitVectUnSetBit (OP_USES (from), lic->key);
+              OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
+              isaddr = IC_COND (lic)->isaddr;
+              IC_JTCOND (lic) = operandFromOperand (to);
+              IC_JTCOND (lic)->isaddr = isaddr;
+
+            }
+          continue;
+        }
+
+      if (IS_SYMOP(to) &&
+          IC_RESULT (lic) && IC_RESULT (lic)->key == from->key)
+        {
+          /* maintain du chains */
+          if (POINTER_SET (lic))
+            {
+              bitVectUnSetBit (OP_USES (from), lic->key);
+              OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
+
+              /* also check if the "from" was in the non-dominating
+                 pointer sets and replace it with "to" in the bitVector */
+              if (bitVectBitValue (*ndpset, from->key))
+                {
+                  bitVectUnSetBit (*ndpset, from->key);
+                  bitVectSetBit (*ndpset, to->key);
+                }
+
+            }
+          else
+            {
+              bitVectUnSetBit (OP_DEFS (from), lic->key);
+              OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
+            }
+          isaddr = IC_RESULT (lic)->isaddr;
+          IC_RESULT (lic) = operandFromOperand (to);
+          IC_RESULT (lic)->isaddr = isaddr;
+        }
 
       if (IS_SYMOP (to) &&
-         IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
-       {
-         bitVectUnSetBit (OP_USES (from), lic->key);
-         OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-         siaddr = IC_RIGHT (lic)->isaddr;
-         IC_RIGHT (lic) = operandFromOperand (to);
-         IC_RIGHT (lic)->isaddr = siaddr;
-       }
+          IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
+        {
+          bitVectUnSetBit (OP_USES (from), lic->key);
+          OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
+          isaddr = IC_RIGHT (lic)->isaddr;
+          IC_RIGHT (lic) = operandFromOperand (to);
+          IC_RIGHT (lic)->isaddr = isaddr;
+        }
 
       if (IS_SYMOP (to) &&
-         IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
-       {
-         bitVectUnSetBit (OP_USES (from), lic->key);
-         OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-         siaddr = IC_LEFT (lic)->isaddr;
-         IC_LEFT (lic) = operandFromOperand (to);
-         IC_LEFT (lic)->isaddr = siaddr;
-       }
+          IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
+        {
+          bitVectUnSetBit (OP_USES (from), lic->key);
+          OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
+          isaddr = IC_LEFT (lic)->isaddr;
+          IC_LEFT (lic) = operandFromOperand (to);
+          IC_LEFT (lic)->isaddr = isaddr;
+        }
     }
 }
 
@@ -245,7 +313,7 @@ DEFSETFUNC (removeFromInExprs)
 /*-----------------------------------------------------------------*/
 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
 /*-----------------------------------------------------------------*/
-static bool 
+static bool
 isGlobalInNearSpace (operand * op)
 {
   sym_link *type = getSpec (operandType (op));
@@ -284,41 +352,41 @@ DEFSETFUNC (findCheaperOp)
       /* constant propagation & dead code elim */
       /* for assignments only                 */
       if (cdp->diCode->op == '=') {
-       /* if the result is volatile then return result */
-       if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
-         *opp = IC_RESULT (cdp->diCode);
-       else 
-         /* if this is a straight assignment and
-            left is a temp then prefer the temporary to the
-            true symbol */
-         if (!POINTER_SET (cdp->diCode) &&
-             IS_ITEMP (IC_RESULT (cdp->diCode)) &&
-             IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
-           *opp = IC_RESULT (cdp->diCode);
-         else {
-           /* if straight assignement && and both
-              are temps then prefer the one that
-              will not need extra space to spil, also
-              take into consideration if right side
-              an induction variable
-           */
-           if (!POINTER_SET (cdp->diCode) &&
-               IS_ITEMP (IC_RESULT (cdp->diCode)) &&
-               IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
-               !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
-               !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
-               ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
-                 SPIL_LOC (IC_RESULT (cdp->diCode))) ||
-                (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
-                 SPIL_LOC (IC_RESULT (cdp->diCode)) ==
-                 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
-             *opp = IC_RESULT (cdp->diCode);
-           else
-             *opp = IC_RIGHT (cdp->diCode);
-         }
+        /* if the result is volatile then return result */
+        if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
+          *opp = IC_RESULT (cdp->diCode);
+        else
+          /* if this is a straight assignment and
+             left is a temp then prefer the temporary to the
+             true symbol */
+          if (!POINTER_SET (cdp->diCode) &&
+              IS_ITEMP (IC_RESULT (cdp->diCode)) &&
+              IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
+            *opp = IC_RESULT (cdp->diCode);
+          else {
+            /* if straight assignment and both
+               are temps then prefer the one that
+               will not need extra space to spil, also
+               take into consideration if right side
+               is an induction variable
+            */
+            if (!POINTER_SET (cdp->diCode) &&
+                IS_ITEMP (IC_RESULT (cdp->diCode)) &&
+                IS_ITEMP (IC_RIGHT (cdp->diCode)) &&
+                !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind &&
+                !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
+                ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) &&
+                  SPIL_LOC (IC_RESULT (cdp->diCode))) ||
+                 (SPIL_LOC (IC_RESULT (cdp->diCode)) &&
+                  SPIL_LOC (IC_RESULT (cdp->diCode)) ==
+                  SPIL_LOC (IC_RIGHT (cdp->diCode)))))
+              *opp = IC_RESULT (cdp->diCode);
+            else
+              *opp = IC_RIGHT (cdp->diCode);
+          }
       }
       else
-       *opp = IC_RESULT (cdp->diCode);
+        *opp = IC_RESULT (cdp->diCode);
     }
 
   /* if this is an assign to a temp. then check
@@ -331,59 +399,65 @@ DEFSETFUNC (findCheaperOp)
       IS_ITEMP (IC_RESULT (cdp->diCode)))
     *opp = IC_RESULT (cdp->diCode);
 
-  if ((*opp) && 
-      (isOperandLiteral(*opp) || !checkSign || 
+  if ((*opp) &&
+      (isOperandLiteral(*opp) || !checkSign ||
        (checkSign &&
-       IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
-       (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
-        (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
+        IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
+        (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
+         (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
       {
 
       if ((isGlobalInNearSpace (cop) &&
-          !isOperandLiteral (*opp)) ||
-         isOperandVolatile (*opp, FALSE)
-       )
-       {
-         *opp = NULL;
-         return 0;
-       }
+           !isOperandLiteral (*opp)) ||
+          isOperandVolatile (*opp, FALSE)
+        )
+        {
+          *opp = NULL;
+          return 0;
+        }
 
       if (cop->key == (*opp)->key)
-       {
-         *opp = NULL;
-         return 0;
-       }
+        {
+          *opp = NULL;
+          return 0;
+        }
 
       if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
-       {
-         *opp = operandFromOperand (*opp);
-         (*opp)->isaddr = cop->isaddr;
-       }
-         
+        {
+          *opp = operandFromOperand (*opp);
+          (*opp)->isaddr = cop->isaddr;
+        }
+
+      /* copy signedness to literal operands */
+      if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
+          && isOperandLiteral(*opp)
+          && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
+          && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
+      {
+          SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
+      }
+
       if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
-         SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
-       {
-           // special case: we can make an unsigned char literal 
-           // into an int literal with no cost.
-           if (isOperandLiteral(*opp)
-            && SPEC_NOUN(operandType(*opp)) == V_CHAR
-            && SPEC_NOUN(operandType(cop)) == V_INT)
-           {
-               *opp = operandFromOperand (*opp);
-               SPEC_NOUN(operandType(*opp)) = V_INT;
-           }
-           else
-           {
-               // No clue...
-               *opp = NULL;
-               return 0;
-           }
-           
-        }
-         
-      LRH(printf ("findCheaperOp: %s < %s\n",\
-             IS_SYMOP((*opp)) ? OP_SYMBOL((*opp))->name : "!SYM",\
-             OP_SYMBOL(cop)->name));
+          SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
+        {
+            // special case: we can make an unsigned char literal
+            // into an int literal with no cost.
+            if (isOperandLiteral(*opp)
+             && SPEC_NOUN(operandType(*opp)) == V_CHAR
+             && SPEC_NOUN(operandType(cop)) == V_INT)
+            {
+                *opp = operandFromOperand (*opp);
+                SPEC_NOUN(operandType(*opp)) = V_INT;
+            }
+            else
+            {
+                // No clue...
+                *opp = NULL;
+                return 0;
+            }
+
+        }
+
       return 1;
 
     }
@@ -408,6 +482,16 @@ DEFSETFUNC (findPointerSet)
       getSize (operandType (IC_RIGHT (cdp->diCode))) ==
       getSize (operandType (rop)))
     {
+      if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
+          SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
+          SPEC_USIGN (operandType (rop)))
+        {
+          /* bug #1493710
+            Reminder for Bernhard: check of signedness
+            could be unnecessary together with 'checkSign', if
+            signedness of operation is stored in ic */
+          return 0;
+        }
       *opp = IC_RIGHT (cdp->diCode);
       return 1;
     }
@@ -433,19 +517,17 @@ DEFSETFUNC (findPrevIc)
   if (isiCodeEqual (ic, cdp->diCode) &&
       isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
     {
-      LRH(printf ("findPrevIc same: %d %d\n", ic->key, cdp->diCode->key));
-       *icp = cdp->diCode;
+      *icp = cdp->diCode;
       return 1;
     }
 
   /* if iCodes are not the same */
   /* see the operands maybe interchanged */
   if (ic->op == cdp->diCode->op &&
-      (ic->op == '+' || ic->op == '*') &&
+      IS_ASSOCIATIVE(ic) &&
       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
     {
-      LRH(printf ("findPrevIc inter: %d %d\n", ic->key, cdp->diCode->key));
       *icp = cdp->diCode;
       return 1;
     }
@@ -467,6 +549,16 @@ DEFSETFUNC (ifAssignedFromGlobal)
   return 0;
 }
 
+/*-------------------------------------------------------------------*/
+/* ifFromGlobal - if definition is derived from global               */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifFromGlobal)
+{
+  cseDef *cdp = item;
+
+  return cdp->fromGlobal;
+}
+
 /*-----------------------------------------------------------------*/
 /* ifDefGlobal - if definition is global                           */
 /*-----------------------------------------------------------------*/
@@ -477,6 +569,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                          */
 /*-----------------------------------------------------------------*/
@@ -497,6 +601,8 @@ DEFSETFUNC (ifOperandsHave)
   cseDef *cdp = item;
   V_ARG (operand *, op);
 
+  if (bitVectBitValue(cdp->ancestors, op->key))
+    return 1;
 
   if (IC_LEFT (cdp->diCode) &&
       IS_SYMOP (IC_LEFT (cdp->diCode)) &&
@@ -528,7 +634,7 @@ DEFSETFUNC (ifOperandsHave)
 /*-----------------------------------------------------------------*/
 /* ifDefSymIs - if a definition is found in the set                */
 /*-----------------------------------------------------------------*/
-int 
+int
 ifDefSymIs (set * cseSet, operand * sym)
 {
   cseDef *loop;
@@ -540,7 +646,7 @@ ifDefSymIs (set * cseSet, operand * sym)
     {
       loop = sl->item;
       if (loop->sym->key == sym->key)
-       return 1;
+        return 1;
     }
   return 0;
 }
@@ -553,19 +659,24 @@ DEFSETFUNC (ifDefSymIsX)
 {
   cseDef *cdp = item;
   V_ARG (operand *, op);
+  int match;
 
   if (op && cdp->sym)
-    return cdp->sym->key == op->key;
+    match = cdp->sym->key == op->key;
   else
-    return (isOperandEqual (cdp->sym, op));
-
+    match = (isOperandEqual (cdp->sym, op));
+  #if 0
+  if (match)
+    printf("%s ",OP_SYMBOL(cdp->sym)->name);
+  #endif
+  return match;
 }
 
 
 /*-----------------------------------------------------------------*/
-/* ifDiCodeIs - returns truw if diCode is same                     */
+/* ifDiCodeIs - returns true if diCode is same                     */
 /*-----------------------------------------------------------------*/
-int 
+int
 ifDiCodeIs (set * cseSet, iCode * ic)
 {
   cseDef *loop;
@@ -578,7 +689,7 @@ ifDiCodeIs (set * cseSet, iCode * ic)
     {
       loop = sl->item;
       if (loop->diCode == ic)
-       return 1;
+        return 1;
     }
   return 0;
 
@@ -635,8 +746,8 @@ iCode *findBackwardDef(operand *op,iCode *ic)
     iCode *lic;
 
     for (lic = ic; lic ; lic = lic->prev) {
-       if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic))) 
-           return lic;
+        if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
+            return lic;
     }
     return NULL;
 }
@@ -644,8 +755,8 @@ iCode *findBackwardDef(operand *op,iCode *ic)
 /*-----------------------------------------------------------------*/
 /* algebraicOpts - does some algebraic optimizations               */
 /*-----------------------------------------------------------------*/
-void 
-algebraicOpts (iCode * ic)
+static void
+algebraicOpts (iCode * ic, eBBlock * ebp)
 {
   /* we don't deal with the following iCodes
      here */
@@ -669,9 +780,9 @@ algebraicOpts (iCode * ic)
     {
 
       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
-                                       IC_RIGHT (ic),
-                                       ic->op,
-                                       operandType (IC_RESULT (ic)));
+                                        IC_RIGHT (ic),
+                                        ic->op,
+                                        operandType (IC_RESULT (ic)));
       ic->op = '=';
       IC_LEFT (ic) = NULL;
       SET_RESULT_RIGHT (ic);
@@ -686,9 +797,9 @@ algebraicOpts (iCode * ic)
     {
 
       IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
-                                       IC_RIGHT (ic),
-                                       ic->op,
-                                       operandType (IC_RESULT (ic)));
+                                        IC_RIGHT (ic),
+                                        ic->op,
+                                        operandType (IC_RESULT (ic)));
       ic->op = '=';
       IC_LEFT (ic) = NULL;
       SET_RESULT_RIGHT (ic);
@@ -702,33 +813,33 @@ algebraicOpts (iCode * ic)
     {
 
       if (IS_ITEMP (IC_RESULT (ic)) &&
-         IS_TRUE_SYMOP (IC_LEFT (ic)))
-       {
-
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
-         IC_RIGHT (ic)->isaddr = 0;
-         IC_LEFT (ic) = NULL;
-         IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
-         IC_RESULT (ic)->isaddr = 0;
-         setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
-         return;
-       }
+          IS_TRUE_SYMOP (IC_LEFT (ic)))
+        {
+
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
+          IC_RIGHT (ic)->isaddr = 0;
+          IC_LEFT (ic) = NULL;
+          IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
+          IC_RESULT (ic)->isaddr = 0;
+          setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic)));
+          return;
+        }
 
       if (IS_ITEMP (IC_LEFT (ic)) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
+          IS_ITEMP (IC_RESULT (ic)) &&
 /*      !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
 /*      !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
-         !IC_LEFT (ic)->isaddr)
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
-         IC_RIGHT (ic)->isaddr = 0;
-         IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
-         IC_RESULT (ic)->isaddr = 0;
-         IC_LEFT (ic) = NULL;
-         return;
-       }
+          !IC_LEFT (ic)->isaddr)
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic));
+          IC_RIGHT (ic)->isaddr = 0;
+          IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
+          IC_RESULT (ic)->isaddr = 0;
+          IC_LEFT (ic) = NULL;
+          return;
+        }
 
     }
 
@@ -739,71 +850,105 @@ algebraicOpts (iCode * ic)
     case '+':
       /* if adding the same thing change to left shift by 1 */
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key &&
-         !IS_FLOAT (operandType (IC_RESULT (ic))))
-       {
-         ic->op = LEFT_OP;
-         IC_RIGHT (ic) = operandFromLit (1);
-         return;
-       }
+          !(IS_FLOAT (operandType (IC_RESULT (ic)))
+            || IS_FIXED(operandType (IC_RESULT (ic)))))
+        {
+          ic->op = LEFT_OP;
+          IC_RIGHT (ic) = operandFromLit (1);
+          return;
+        }
       /* if addition then check if one of them is a zero */
-      /* if yes turn it  into assignmnt */
+      /* if yes turn it into assignment or cast */
       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
-         operandLitValue (IC_LEFT (ic)) == 0.0)
-       {
-
-         ic->op = '=';
-         IC_LEFT (ic) = NULL;
-         SET_ISADDR (IC_RESULT (ic), 0);
-         SET_ISADDR (IC_RIGHT (ic), 0);
-         return;
-       }
+          operandLitValue (IC_LEFT (ic)) == 0.0)
+        {
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_RIGHT (ic)));
+          if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
+            {
+              ic->op = CAST;
+              IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
+            }
+          else
+            {
+              ic->op = '=';
+              IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
+            }
+          SET_ISADDR (IC_RESULT (ic), 0);
+          SET_ISADDR (IC_RIGHT (ic), 0);
+          return;
+        }
       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-         operandLitValue (IC_RIGHT (ic)) == 0.0)
-       {
-
-         ic->op = '=';
-         IC_RIGHT (ic) = IC_LEFT (ic);
-         IC_LEFT (ic) = 0;
-         SET_ISADDR (IC_RIGHT (ic), 0);
-         SET_ISADDR (IC_RESULT (ic), 0);
-         return;
-       }
+          operandLitValue (IC_RIGHT (ic)) == 0.0)
+        {
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_LEFT (ic)));
+          if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
+            {
+              ic->op = CAST;
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
+            }
+          else
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
+            }
+          SET_ISADDR (IC_RIGHT (ic), 0);
+          SET_ISADDR (IC_RESULT (ic), 0);
+          return;
+        }
       break;
     case '-':
-      /* if subtracting the the same thing then zero     */
+      /* if subtracting the same thing then zero     */
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromLit (0);
-         IC_LEFT (ic) = NULL;
-         IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
-         IC_RESULT (ic)->isaddr = 0;
-         return;
-       }
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (0);
+          IC_LEFT (ic) = NULL;
+          IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
+          IC_RESULT (ic)->isaddr = 0;
+          return;
+        }
 
       /* if subtraction then check if one of the operand */
       /* is zero then depending on which operand change  */
       /* to assignment or unary minus                    */
       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-         operandLitValue (IC_RIGHT (ic)) == 0.0)
-       {
-         /* right size zero change to assignment */
-         ic->op = '=';
-         IC_RIGHT (ic) = IC_LEFT (ic);
-         IC_LEFT (ic) = NULL;
-         SET_ISADDR (IC_RIGHT (ic), 0);
-         SET_ISADDR (IC_RESULT (ic), 0);
-         return;
-       }
+          operandLitValue (IC_RIGHT (ic)) == 0.0)
+        {
+          /* right size zero change to assignment */
+          ic->op = '=';
+          IC_RIGHT (ic) = IC_LEFT (ic);
+          IC_LEFT (ic) = NULL;
+          SET_ISADDR (IC_RIGHT (ic), 0);
+          SET_ISADDR (IC_RESULT (ic), 0);
+          return;
+        }
       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
-         operandLitValue (IC_LEFT (ic)) == 0.0)
-       {
-         /* left zero turn into an unary minus */
-         ic->op = UNARYMINUS;
-         IC_LEFT (ic) = IC_RIGHT (ic);
-         IC_RIGHT (ic) = NULL;
-         return;
-       }
+          operandLitValue (IC_LEFT (ic)) == 0.0)
+        {
+          /* left zero turn into an unary minus */
+          ic->op = UNARYMINUS;
+          IC_LEFT (ic) = IC_RIGHT (ic);
+          IC_RIGHT (ic) = NULL;
+          return;
+        }
       break;
       /* if multiplication then check if either of */
       /* them is zero then the result is zero      */
@@ -811,126 +956,434 @@ algebraicOpts (iCode * ic)
       /* the other one                             */
     case '*':
       if (IS_OP_LITERAL (IC_LEFT (ic)))
-       {
-
-         if (operandLitValue (IC_LEFT (ic)) == 0.0)
-           {
-             ic->op = '=';
-             IC_RIGHT (ic) = IC_LEFT (ic);
-             IC_LEFT (ic) = NULL;
-             SET_RESULT_RIGHT (ic);
-             return;
-           }
-         if (operandLitValue (IC_LEFT (ic)) == 1.0)
-           {
-             ic->op = '=';
-             IC_LEFT (ic) = NULL;
-             SET_RESULT_RIGHT (ic);
-             return;
-           }
-       }
+        {
+         double leftValue = operandLitValue (IC_LEFT (ic));
+
+          if (leftValue == 0.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          if (leftValue == 1.0)
+            {
+              /* '*' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (compareType (operandType (IC_RESULT (ic)),
+                               operandType (IC_RIGHT (ic))) == 1)
+                {
+                  ic->op = '=';
+                  IC_LEFT (ic) = NULL;
+                  SET_RESULT_RIGHT (ic);
+                }
+              else
+                {
+                  ic->op = CAST;
+                  IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
+                  IC_LEFT (ic)->type = TYPE;
+                  IC_LEFT (ic)->isLiteral = 0;
+                  setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+                }
+              return;
+            }
+          if (leftValue == -1.0)
+            {
+              /* convert -1 * x to -x */
+              ic->op = UNARYMINUS;
+              IC_LEFT (ic) = IC_RIGHT (ic);
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
+        }
 
       if (IS_OP_LITERAL (IC_RIGHT (ic)))
-       {
-
-         if (operandLitValue (IC_RIGHT (ic)) == 0.0)
-           {
-             ic->op = '=';
-             IC_LEFT (ic) = NULL;
-             SET_RESULT_RIGHT (ic);
-             return;
-           }
-
-         if (operandLitValue (IC_RIGHT (ic)) == 1.0)
-           {
-             ic->op = '=';
-             IC_RIGHT (ic) = IC_LEFT (ic);
-             IC_LEFT (ic) = NULL;
-             SET_RESULT_RIGHT (ic);
-             return;
-           }
-       }
+        {
+          double rightValue = operandLitValue (IC_RIGHT (ic));
+
+          if (rightValue == 0.0)
+            {
+              ic->op = '=';
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+
+          if (rightValue == 1.0)
+            {
+              /* '*' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (compareType (operandType (IC_RESULT (ic)),
+                               operandType (IC_LEFT (ic))) == 1)
+                {
+                  ic->op = '=';
+                  IC_RIGHT (ic) = IC_LEFT (ic);
+                  IC_LEFT (ic) = NULL;
+                  SET_RESULT_RIGHT (ic);
+                }
+              else
+                {
+                  operand *op;
+
+                  ic->op = CAST;
+                  op = IC_RIGHT (ic);
+                  IC_RIGHT (ic) = IC_LEFT (ic);
+                  IC_LEFT (ic) = operandFromOperand (op);
+                  IC_LEFT (ic)->type = TYPE;
+                  IC_LEFT (ic)->isLiteral = 0;
+                  setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+                }
+              return;
+            }
+          if (rightValue == -1.0)
+            {
+              /* '*' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
+              /* convert x * -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
+        }
       break;
     case '/':
       /* if division by self then 1 */
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromLit (1);
-         IC_LEFT (ic) = NULL;
-         IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
-         IC_RESULT (ic)->isaddr = 0;
-         break;
-       }
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (1);
+          IC_LEFT (ic) = NULL;
+          IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
+          IC_RESULT (ic)->isaddr = 0;
+          return;
+        }
+      /* if this is a division then check if left is zero */
+      /* and right is not then change it to an assignment */
+      if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) &&
+          (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0))
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = IC_LEFT (ic);
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+          return;
+        }
       /* if this is a division then check if right */
       /* is one then change it to an assignment    */
-      if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-         operandLitValue (IC_RIGHT (ic)) == 1.0)
-       {
-
-         ic->op = '=';
-         IC_RIGHT (ic) = IC_LEFT (ic);
-         IC_LEFT (ic) = NULL;
-         SET_RESULT_RIGHT (ic);
-         return;
-       }
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          double rightValue = operandLitValue (IC_RIGHT (ic));
+          if (rightValue == 1.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          if (rightValue == -1.0)
+            {
+              /* '/' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
+              /* convert x / -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
+        }
       break;
       /* if both are the same for an comparison operators */
     case EQ_OP:
     case LE_OP:
     case GE_OP:
       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromLit (1);
-         IC_LEFT (ic) = NULL;
-         SET_RESULT_RIGHT (ic);
-       }
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (1);
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+        }
       break;
     case NE_OP:
     case '>':
     case '<':
       if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) = operandFromLit (0);
-         IC_LEFT (ic) = NULL;
-         SET_RESULT_RIGHT (ic);
-       }
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (0);
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+        }
       break;
     case CAST:
-           {
-                   sym_link *otype = operandType(IC_RIGHT(ic));
-                   sym_link *ctype = operandType(IC_LEFT(ic));
-                   /* if this is a cast of a literal value */
-                   if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-                       !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype)))) {
-                           ic->op = '=';
-                           IC_RIGHT (ic) =
-                                   operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
-                                                                     operandLitValue (IC_RIGHT (ic))));
-                           IC_LEFT (ic) = NULL;
-                           SET_ISADDR (IC_RESULT (ic), 0);
-                   }
-                   /* if casting to the same */
-                   if (compareType (operandType (IC_RESULT (ic)),
-                                    operandType (IC_RIGHT (ic))) == 1) {
-                           ic->op = '=';
-                           IC_LEFT (ic) = NULL;
-                           SET_ISADDR (IC_RESULT (ic), 0);
-                   }
-           }
-           break;
+        {
+          sym_link *otype = operandType(IC_RIGHT(ic));
+          sym_link *ctype = operandType(IC_LEFT(ic));
+          /* if this is a cast of a literal value */
+          if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
+              !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype))))
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)),
+                                                                operandLitValue (IC_RIGHT (ic))));
+              IC_LEFT (ic) = NULL;
+              SET_ISADDR (IC_RESULT (ic), 0);
+            }
+          /* if casting to the same */
+          if (compareType (operandType (IC_RESULT (ic)), operandType (IC_RIGHT (ic))) == 1)
+            {
+              ic->op = '=';
+              IC_LEFT (ic) = NULL;
+              SET_ISADDR (IC_RESULT (ic), 0);
+            }
+        }
+      break;
     case '!':
       if (IS_OP_LITERAL (IC_LEFT (ic)))
-       {
-         ic->op = '=';
-         IC_RIGHT (ic) =
-           (operandLitValue (IC_LEFT (ic)) == 0 ?
-            operandFromLit (1) : operandFromLit (0));
-         IC_LEFT (ic) = NULL;
-         SET_ISADDR (IC_RESULT (ic), 0);
-       }
+        {
+          ic->op = '=';
+          IC_RIGHT (ic) =
+            (operandLitValue (IC_LEFT (ic)) == 0 ?
+             operandFromLit (1) : operandFromLit (0));
+          IC_LEFT (ic) = NULL;
+          SET_ISADDR (IC_RESULT (ic), 0);
+        }
+      break;
+    case BITWISEAND:
+      /* if both operands are equal */
+      /* if yes turn it into assignment */
+      if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+        {
+          if (IS_OP_VOLATILE (IC_LEFT (ic)))
+            {
+              iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+              IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
+              newic->lineno = ic->lineno;
+              addiCodeToeBBlock (ebp, newic, ic->next);
+            }
+          ic->op = '=';
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+          return;
+        }
+      /* swap literal to right ic */
+      if (IS_OP_LITERAL (IC_LEFT (ic)))
+        {
+          operand *op;
+
+          op = IC_LEFT (ic);
+          IC_LEFT (ic) = IC_RIGHT (ic);
+          IC_RIGHT (ic) = op;
+        }
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          /* if BITWISEAND then check if one of them is a zero */
+          /* if yes turn it into 0 assignment */
+          if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+            {
+              if (IS_OP_VOLATILE (IC_LEFT (ic)))
+                {
+                  iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+                  IC_RESULT (newic) = IC_LEFT (ic);
+                  newic->filename = ic->filename;
+                  newic->lineno = ic->lineno;
+                  addiCodeToeBBlock (ebp, newic, ic->next);
+                }
+              ic->op = '=';
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          /* if BITWISEAND then check if one of them is 0xff... */
+          /* if yes turn it into assignment */
+          {
+            unsigned val;
+
+            switch (getSize (operandType (IC_RIGHT (ic))))
+              {
+              case 1:
+                val = 0xff;
+                break;
+              case 2:
+                val = 0xffff;
+                break;
+              case 4:
+                val = 0xffffffff;
+                break;
+              default:
+                return;
+              }
+            if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          }
+        }
+      break;
+    case '|':
+      /* if both operands are equal */
+      /* if yes turn it into assignment */
+      if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+        {
+          if (IS_OP_VOLATILE (IC_LEFT (ic)))
+            {
+              iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+              IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
+              newic->lineno = ic->lineno;
+              addiCodeToeBBlock (ebp, newic, ic->next);
+            }
+            ic->op = '=';
+            IC_LEFT (ic) = NULL;
+            SET_RESULT_RIGHT (ic);
+            return;
+        }
+      /* swap literal to right ic */
+      if (IS_OP_LITERAL (IC_LEFT (ic)))
+        {
+          operand *op;
+
+          op = IC_LEFT (ic);
+          IC_LEFT (ic) = IC_RIGHT (ic);
+          IC_RIGHT (ic) = op;
+        }
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          /* if BITWISEOR then check if one of them is a zero */
+          /* if yes turn it into assignment */
+          if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          /* if BITWISEOR then check if one of them is 0xff... */
+          /* if yes turn it into 0xff... assignment */
+          {
+            unsigned val;
+
+            switch (getSize (operandType (IC_RIGHT (ic))))
+              {
+              case 1:
+                val = 0xff;
+                break;
+              case 2:
+                val = 0xffff;
+                break;
+              case 4:
+                val = 0xffffffff;
+                break;
+              default:
+                return;
+              }
+            if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
+              {
+                if (IS_OP_VOLATILE (IC_LEFT (ic)))
+                {
+                  iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+                  IC_RESULT (newic) = IC_LEFT (ic);
+                  newic->filename = ic->filename;
+                  newic->lineno = ic->lineno;
+                  addiCodeToeBBlock (ebp, newic, ic->next);
+                }
+                ic->op = '=';
+                IC_LEFT (ic) = NULL;
+                SET_RESULT_RIGHT (ic);
+                return;
+              }
+          }
+        }
+      break;
+    case '^':
+      /* if both operands are equal */
+      /* if yes turn it into 0 assignment */
+      if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+        {
+          if (IS_OP_VOLATILE (IC_LEFT (ic)))
+            {
+              iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+              IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
+              newic->lineno = ic->lineno;
+              addiCodeToeBBlock (ebp, newic, ic->next);
+
+              newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+              IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
+              newic->lineno = ic->lineno;
+              addiCodeToeBBlock (ebp, newic, ic->next);
+            }
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (0);
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+          return;
+        }
+      /* swap literal to right ic */
+      if (IS_OP_LITERAL (IC_LEFT (ic)))
+        {
+          operand *op;
+
+          op = IC_LEFT (ic);
+          IC_LEFT (ic) = IC_RIGHT (ic);
+          IC_RIGHT (ic) = op;
+        }
+      /* if XOR then check if one of them is a zero */
+      /* if yes turn it into assignment */
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+        }
+      break;
     }
 
   return;
@@ -939,75 +1392,82 @@ algebraicOpts (iCode * ic)
 /*-----------------------------------------------------------------*/
 /* updateSpillLocation - keeps track of register spill location    */
 /*-----------------------------------------------------------------*/
-void 
+void
 updateSpillLocation (iCode * ic, int induction)
 {
-       sym_link *setype;
+        sym_link *setype;
 
-       if (POINTER_SET (ic))
-               return;
+        if (POINTER_SET (ic))
+                return;
 
-       if (ic->nosupdate)
-               return;
+        if (ic->nosupdate)
+                return;
 
-       /* for the form true_symbol := iTempNN */
-       if (ASSIGN_ITEMP_TO_SYM (ic) && 
-           !SPIL_LOC (IC_RIGHT (ic))) {
+#if 0
+        /* for the form true_symbol := iTempNN */
+        if (ASSIGN_ITEMP_TO_SYM (ic) &&
+            !SPIL_LOC (IC_RIGHT (ic))) {
 
-               setype = getSpec (operandType (IC_RESULT (ic)));
+                setype = getSpec (operandType (IC_RESULT (ic)));
 
-               if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
-                   !IS_VOLATILE (setype) &&
-                   !IN_FARSPACE (SPEC_OCLS (setype)) &&
-                   !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
-               {
-                   wassert(IS_SYMOP(IC_RESULT (ic)));
-                   wassert(IS_SYMOP(IC_RIGHT (ic)));
-                       SPIL_LOC (IC_RIGHT (ic)) =
-                               IC_RESULT (ic)->operand.symOperand;
-               }
-           
-       }
+                if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
+                    !IS_VOLATILE (setype) &&
+                    !IN_FARSPACE (SPEC_OCLS (setype)) &&
+                    !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+                {
+                    wassert(IS_SYMOP(IC_RESULT (ic)));
+                    wassert(IS_SYMOP(IC_RIGHT (ic)));
+                        SPIL_LOC (IC_RIGHT (ic)) =
+                                IC_RESULT (ic)->operand.symOperand;
+                }
+
+        }
+#endif
 
 #if 0 /* this needs furthur investigation can save a lot of code */
-       if (ASSIGN_SYM_TO_ITEMP(ic) &&
-           !SPIL_LOC(IC_RESULT(ic))) {
-           if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
-               SPIL_LOC (IC_RESULT (ic)) =
-                   IC_RIGHT (ic)->operand.symOperand;
-       }
+        if (ASSIGN_SYM_TO_ITEMP(ic) &&
+            !SPIL_LOC(IC_RESULT(ic))) {
+            if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
+                SPIL_LOC (IC_RESULT (ic)) =
+                    IC_RIGHT (ic)->operand.symOperand;
+        }
 #endif
-       if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
-         
-               if (!SPIL_LOC (IC_RIGHT (ic)) &&
-                   !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
-                   OP_SYMBOL (IC_RESULT (ic))->isreqv) {
-
-                       setype = getSpec (operandType (IC_RESULT (ic)));
-             
-                       if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
-                           !IS_VOLATILE (setype) &&
-                           !IN_FARSPACE (SPEC_OCLS (setype)) &&
-                           !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
-
-                               SPIL_LOC (IC_RIGHT (ic)) =
-                                       SPIL_LOC (IC_RESULT (ic));
-               }
-               /* special case for inductions */
-               if (induction && 
-                   OP_SYMBOL(IC_RIGHT(ic))->isreqv && 
-                   !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
-                   !SPIL_LOC(IC_RESULT(ic))) {
-                       SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
-               }
-       }
+        if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
+
+                if (!SPIL_LOC (IC_RIGHT (ic)) &&
+                    !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
+                    OP_SYMBOL (IC_RESULT (ic))->isreqv) {
+
+                        setype = getSpec (operandType (IC_RESULT (ic)));
+
+                        if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
+                            !IS_VOLATILE (setype) &&
+                            !IN_FARSPACE (SPEC_OCLS (setype)) &&
+                            !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) {
+
+                                SPIL_LOC (IC_RIGHT (ic)) =
+                                        SPIL_LOC (IC_RESULT (ic));
+                                OP_SYMBOL (IC_RIGHT (ic))->prereqv =
+                                        OP_SYMBOL (IC_RESULT (ic))->prereqv;
+                        }
+                }
+                /* special case for inductions */
+                if (induction &&
+                    OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
+                    !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
+                    !SPIL_LOC(IC_RESULT(ic))) {
+                        SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
+                        OP_SYMBOL (IC_RESULT (ic))->prereqv =
+                                OP_SYMBOL (IC_RIGHT (ic))->prereqv;
+                }
+        }
 }
 /*-----------------------------------------------------------------*/
 /* setUsesDef - sets the uses def bitvector for a given operand    */
 /*-----------------------------------------------------------------*/
-void 
+void
 setUsesDefs (operand * op, bitVect * bdefs,
-            bitVect * idefs, bitVect ** oud)
+             bitVect * idefs, bitVect ** oud)
 {
   /* compute the definitions alive at this point */
   bitVect *adefs = bitVectUnion (bdefs, idefs);
@@ -1026,7 +1486,7 @@ setUsesDefs (operand * op, bitVect * bdefs,
 /*-----------------------------------------------------------------*/
 /* unsetDefsAndUses - clear this operation for the operands        */
 /*-----------------------------------------------------------------*/
-void 
+void
 unsetDefsAndUses (iCode * ic)
 {
   if (ic->op == JUMPTABLE)
@@ -1038,18 +1498,18 @@ unsetDefsAndUses (iCode * ic)
     {
       /* turn off def set */
       if (IS_SYMOP (IC_RESULT (ic)))
-       {
-         if (!POINTER_SET (ic))
-           bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
-         else
-           bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
-       }
+        {
+          if (!POINTER_SET (ic))
+            bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+          else
+            bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+        }
       /* turn off the useSet for the operands */
       if (IS_SYMOP (IC_LEFT (ic)))
-       bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+        bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
 
       if (IS_SYMOP (IC_RIGHT (ic)))
-       bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+        bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
     }
   else
     /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
@@ -1059,11 +1519,11 @@ unsetDefsAndUses (iCode * ic)
 /*-----------------------------------------------------------------*/
 /* ifxOptimize - changes ifx conditions if it can                  */
 /*-----------------------------------------------------------------*/
-void 
+void
 ifxOptimize (iCode * ic, set * cseSet,
-            int computeOnly,
-            eBBlock * ebb, int *change,
-            eBBlock ** ebbs, int count)
+             int computeOnly,
+             eBBlock * ebb, int *change,
+             ebbIndex * ebbi)
 {
   operand *pdop;
   symbol *label;
@@ -1074,51 +1534,47 @@ ifxOptimize (iCode * ic, set * cseSet,
       pdop = NULL;
       applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
       if (pdop)
-       {
-         ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
-         (*change)++;
-       }
+        {
+          ReplaceOpWithCheaperOp(&IC_COND (ic), pdop);
+          (*change)++;
+        }
     }
 
   /* if the conditional is a literal then */
   if (IS_OP_LITERAL (IC_COND (ic)))
     {
-
       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
-       {
-
-         /* change to a goto */
-         ic->op = GOTO;
-         IC_LABEL (ic) = IC_TRUE (ic);
-         (*change)++;
-
-       }
+        {
+          /* change to a goto */
+          ic->op = GOTO;
+          IC_LABEL (ic) = IC_TRUE (ic);
+          (*change)++;
+        }
       else
-       {
-
-         if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
-           {
-             ic->op = GOTO;
-             IC_LABEL (ic) = IC_FALSE (ic);
-             (*change)++;
-
-           }
-         else
-           {
-             /* then kill this if condition */
-             remiCodeFromeBBlock (ebb, ic);
-           }
-       }
+        {
+          if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
+            {
+              ic->op = GOTO;
+              IC_LABEL (ic) = IC_FALSE (ic);
+              (*change)++;
+            }
+          else
+            {
+              /* then kill this if condition */
+              remiCodeFromeBBlock (ebb, ic);
+            }
+        }
 
       /* now we need to recompute the control flow */
       /* since the control flow has changed        */
       /* 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);
-      if (!options.lessPedantic) {
-       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
-      }
+      computeControlFlow (ebbi);
+      if (!options.lessPedantic)
+        {
+          werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+        }
       return;
     }
 
@@ -1127,21 +1583,38 @@ 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)))
     {
-
-      remiCodeFromeBBlock (ebb, ic);
-      computeControlFlow (ebbs, count, 1);
-      if (!options.lessPedantic) {
-       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
-      }
-      return;
+      if (!options.lessPedantic)
+        {
+          werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+        }
+      if (IS_OP_VOLATILE (IC_COND (ic)))
+        {
+          IC_RIGHT (ic) = IC_COND (ic);
+          IC_LEFT (ic) = NULL;
+          IC_RESULT (ic) = NULL;
+          ic->op = DUMMY_READ_VOLATILE;
+        }
+      else
+        {
+          remiCodeFromeBBlock (ebb, ic);
+          computeControlFlow (ebbi);
+          return;
+        }
     }
 
-
-  /* if it remains an IFX the update the use Set */
-  OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
-  setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+  /* if it remains an IFX then update the use Set */
+  if (ic->op == IFX)
+    {
+      OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
+      setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+    }
+  else if (ic->op == DUMMY_READ_VOLATILE)
+    {
+      OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+      setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+    }
   return;
 }
 
@@ -1171,7 +1644,7 @@ DEFSETFUNC (diCodeForSym)
 /*-----------------------------------------------------------------*/
 /* constFold - does some constant folding                          */
 /*-----------------------------------------------------------------*/
-int 
+int
 constFold (iCode * ic, set * cseSet)
 {
   iCode *dic = NULL;
@@ -1187,7 +1660,7 @@ constFold (iCode * ic, set * cseSet)
       ic->op != '-')
     return 0;
 
-  /* this check is a hueristic to prevent live ranges
+  /* this check is a heuristic to prevent live ranges
      from becoming too long */
   if (IS_PTR (operandType (IC_RESULT (ic))))
       return 0;
@@ -1197,7 +1670,7 @@ constFold (iCode * ic, set * cseSet)
     return 0;
 
   /* check if we can find a definition for the
-     right hand side */
+     left hand side */
   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
     return 0;
 
@@ -1224,10 +1697,10 @@ constFold (iCode * ic, set * cseSet)
   IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
   if (ic->op == dic->op)
     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
-                                   operandLitValue (IC_RIGHT (dic)));
+                                    operandLitValue (IC_RIGHT (dic)));
   else
     IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
-                                   operandLitValue (IC_RIGHT (dic)));
+                                    operandLitValue (IC_RIGHT (dic)));
 
   if (IS_ITEMP (IC_RESULT (ic)))
     {
@@ -1244,56 +1717,58 @@ constFold (iCode * ic, set * cseSet)
 /* will delete from cseSet all get pointers computed from this     */
 /* pointer. A simple ifOperandsHave is not good enough here        */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
 {
   set *compItems = NULL;
   cseDef *cdp;
   operand *cop;
+  int changes;
 
   /* easy return */
   if (!*cseSet && !*pss)
     return;
 
-  /* first find all items computed from this operand .
+  addSet (&compItems, op);
+
+  /* Recursively find all items computed from this operand .
      This done fairly simply go thru the list and find
-     those that are computed by arthimetic with this
-     op */
-  for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
+     those that are computed by arthimetic with these
+     ops */
+  /* Also check for those computed from our computed
+     list . This will take care of situations like
+     iTemp1 = iTemp0 + 8;
+     iTemp2 = iTemp1 + 8; */
+  do
     {
-      if (IS_ARITHMETIC_OP (cdp->diCode))
-       {
-         if (isOperandEqual (IC_LEFT (cdp->diCode), op) ||
-             isOperandEqual (IC_RIGHT (cdp->diCode), op))
-           {
-             /* save it in our list of items */
-             addSet (&compItems, IC_RESULT (cdp->diCode));
-           }
-         /* also check for those computed from our computed
-            list . This will take care of situations like
-            iTemp1 = iTemp0 + 8;
-            iTemp2 = iTemp1 + 8; */
-         if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), 
-                          (insetwithFunc)isOperandEqual) ||
-             isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), 
-                          (insetwithFunc)isOperandEqual))
-           {
-             addSet (&compItems, IC_RESULT (cdp->diCode));
-           }
-       }
+      changes = 0;
+      for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
+        {
+          if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
+            {
+              if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
+                               (insetwithFunc)isOperandEqual) ||
+                  isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
+                               (insetwithFunc)isOperandEqual))
+                {
+                  if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
+                                    (insetwithFunc)isOperandEqual))
+                    {
+                  addSet (&compItems, IC_RESULT (cdp->diCode));
+                  changes++;
+                    }
+                }
+            }
+        }
     }
+  while (changes);
 
-  /* now delete all pointer gets with this op */
-  deleteItemIf (cseSet, ifPointerGet, op);
-  deleteItemIf (pss, ifPointerSet, op);
-
-  /* set the bit vector used by dataFlow computation later */
-  ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key);
   /* now for the computed items */
   for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems))
     {
       ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key);
       deleteItemIf (cseSet, ifPointerGet, cop);
+      deleteItemIf (cseSet, ifDefSymIsX, cop);
       deleteItemIf (pss, ifPointerSet, cop);
     }
 }
@@ -1323,7 +1798,7 @@ DEFSETFUNC (delGetPointerSucc)
 /*-----------------------------------------------------------------*/
 /* fixUpTypes - KLUGE HACK fixup a lowering problem                */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 fixUpTypes (iCode * ic)
 {
   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
@@ -1373,7 +1848,7 @@ static int isSignedOp (iCode *ic)
     case IFX:
     case RECEIVE:
     case SEND:
-       return 0;
+        return 0;
     case '*':
     case '/':
     case '%':
@@ -1385,45 +1860,67 @@ static int isSignedOp (iCode *ic)
     case RRC:
     case RLC:
     case GETHBIT:
+    case GETABIT:
+    case GETBYTE:
+    case GETWORD:
     case RIGHT_OP:
     case CAST:
     case ARRAYINIT:
-       return 1;
+        return 1;
     default:
-       return 0;
+        return 0;
     }
  }
 
+#if 0
+static void
+dumpCseSet(set *cseSet)
+{
+  while (cseSet)
+    {
+      cseDef *item=cseSet->item;
+      printf("->");
+      printOperand (item->sym, NULL);
+      printf("  ");
+      piCode (item->diCode, NULL);
+      cseSet = cseSet->next;
+    }
+}
+#endif
+
 /*-----------------------------------------------------------------*/
 /* cseBBlock - common subexpression elimination for basic blocks   */
 /*             this is the hackiest kludgiest routine in the whole */
 /*             system. also the most important, since almost all   */
 /*             data flow related information is computed by it     */
 /*-----------------------------------------------------------------*/
-int 
+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;
   int i;
   set *ptrSetSet = NULL;
+  cseDef *expr;
 
   /* if this block is not reachable */
   if (ebb->noPath)
-    return change;
+    return 0;
 
   /* set of common subexpressions */
   cseSet = setFromSet (ebb->inExprs);
 
   /* these will be computed by this routine */
-  setToNull ((void **) &ebb->outDefs);
-  setToNull ((void **) &ebb->defSet);
-  setToNull ((void **) &ebb->usesDefs);
-  setToNull ((void **) &ebb->ptrsSet);
-  setToNull ((void **) &ebb->addrOf);
-  setToNull ((void **) &ebb->ldefs);
+  setToNull ((void *) &ebb->outDefs);
+  setToNull ((void *) &ebb->defSet);
+  setToNull ((void *) &ebb->usesDefs);
+  setToNull ((void *) &ebb->ptrsSet);
+  setToNull ((void *) &ebb->addrOf);
+  setToNull ((void *) &ebb->ldefs);
 
   ebb->outDefs = bitVectCopy (ebb->inDefs);
   bitVectDefault = iCodeKey;
@@ -1441,142 +1938,183 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       ic->eBBlockNum = ebb->bbnum;
 
       if (SKIP_IC2 (ic))
-       continue;
+        continue;
 
       /* if this is an assignment from true symbol
-         to a temp then do pointer post inc/dec optimzation */
+         to a temp then do pointer post inc/dec optimization */
       if (ic->op == '=' && !POINTER_SET (ic) &&
-         IS_PTR (operandType (IC_RESULT (ic))))
-       {
-         ptrPostIncDecOpt (ic);
-       }
+          IS_PTR (operandType (IC_RESULT (ic))))
+        {
+          ptrPostIncDecOpt (ic);
+        }
 
       /* clear the def & use chains for the operands involved */
       /* in this operation . since it can change due to opts  */
       unsetDefsAndUses (ic);
 
       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
-       {
-         /* add to defSet of the symbol */
-         OP_DEFS(IC_RESULT (ic))=
-           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
-         /* add to the definition set of this block */
-         ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
-         ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
-         ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
-         setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-         /* delete global variables from the cseSet
-            since they can be modified by the function call */
-         deleteItemIf (&cseSet, ifDefGlobal);
-
-         /* and also itemps assigned from globals */
-         deleteItemIf (&cseSet, ifAssignedFromGlobal);
-
-         /* delete all getpointer iCodes from cseSet, this should
-            be done only for global arrays & pointers but at this
-            point we don't know if globals, so to be safe do all */
-         deleteItemIf (&cseSet, ifAnyGetPointer);
-       }
+        {
+          /* add to defSet of the symbol */
+          OP_DEFS(IC_RESULT (ic))=
+            bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+          /* add to the definition set of this block */
+          ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
+          ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
+          ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
+          setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+          /* delete global variables from the cseSet
+             since they can be modified by the function call */
+          deleteItemIf (&cseSet, ifDefGlobal);
+
+          /* 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
+             point we don't know if globals, so to be safe do all */
+          deleteItemIf (&cseSet, ifAnyGetPointer);
+
+          /* can't cache pointer set/get operations across a call */
+          deleteSet (&ptrSetSet);
+        }
 
       /* for pcall & ipush we need to add to the useSet */
       if ((ic->op == PCALL ||
-          ic->op == IPUSH ||
-          ic->op == IPOP ||
-          ic->op == SEND) &&
-         IS_SYMOP (IC_LEFT (ic)))
-       {
-
-         /* check if they can be replaced */
-         if (!computeOnly)
-           {
-             pdop = NULL;
-             applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
-             if (pdop)
-               ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
-           }
-         /* the lookup could have changed it */
-         if (IS_SYMOP (IC_LEFT (ic)))
-           {
-             OP_USES(IC_LEFT (ic))=
-               bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
-             setUsesDefs (IC_LEFT (ic), ebb->defSet,
-                          ebb->outDefs, &ebb->usesDefs);
-           }
-
-
-         /* if we a sending a pointer as a parameter
-            then kill all cse since the pointed to item
-            might be changed in the function being called */
-         if ((ic->op == IPUSH || ic->op == SEND) &&
-             IS_PTR (operandType (IC_LEFT (ic))))
-           {
-             deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
-             ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
-             for (i = 0; i < count; ebbs[i++]->visited = 0);
-             applyToSet (ebb->succList, delGetPointerSucc,
-                         IC_LEFT (ic), ebb->dfnum);
-           }
-         continue;
-       }
+           ic->op == IPUSH ||
+           ic->op == IPOP ||
+           ic->op == SEND) &&
+          IS_SYMOP (IC_LEFT (ic)))
+        {
+
+          /* check if they can be replaced */
+          if (!computeOnly)
+            {
+              pdop = NULL;
+              applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
+              if (pdop)
+                ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
+            }
+          /* the lookup could have changed it */
+          if (IS_SYMOP (IC_LEFT (ic)))
+            {
+              OP_USES(IC_LEFT (ic))=
+                bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+              setUsesDefs (IC_LEFT (ic), ebb->defSet,
+                           ebb->outDefs, &ebb->usesDefs);
+            }
+
+
+          /* if we a sending a pointer as a parameter
+             then kill all cse since the pointed to item
+             might be changed in the function being called */
+          if ((ic->op == IPUSH || ic->op == SEND) &&
+              IS_PTR (operandType (IC_LEFT (ic))))
+            {
+              deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
+              ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
+              for (i = 0; i < count; ebbs[i++]->visited = 0);
+              applyToSet (ebb->succList, delGetPointerSucc,
+                          IC_LEFT (ic), ebb->dfnum);
+            }
+          continue;
+        }
 
       /* if jumptable then mark the usage */
       if (ic->op == JUMPTABLE)
-       {
-         OP_USES(IC_JTCOND (ic))=
-           bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
-         setUsesDefs (IC_JTCOND (ic), ebb->defSet,
-                      ebb->outDefs, &ebb->usesDefs);
-         continue;
-       }
+        {
+          if (IS_SYMOP (IC_JTCOND (ic)))
+            {
+              OP_USES(IC_JTCOND (ic)) =
+                bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
+              setUsesDefs (IC_JTCOND (ic), ebb->defSet,
+                           ebb->outDefs, &ebb->usesDefs);
+            }
+          continue;
+        }
 
       if (SKIP_IC (ic))
-       continue;
-
-      /* do some algebraic optimizations if possible */
-      algebraicOpts (ic);
-      while (constFold (ic, cseSet));
-
-      /* small klugde */
-      if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
-       {
-         setOperandType (IC_LEFT (ic),
-                         aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
-         fixUpTypes (ic);
-
-       }
-      if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
-       {
-         setOperandType (IC_RESULT (ic),
-                         aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
-       }
-
-      /* if this is a condition statment then */
+        continue;
+
+      if (!computeOnly)
+        {
+          /* do some algebraic optimizations if possible */
+          algebraicOpts (ic, ebb);
+          while (constFold (ic, cseSet));
+        }
+
+      /* small kludge */
+      if (POINTER_GET (ic))
+        {
+          if (!IS_PTR (operandType (IC_LEFT (ic))))
+            {
+              setOperandType (IC_LEFT (ic),
+                              aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
+              IC_LEFT (ic)->aggr2ptr = 0;
+              fixUpTypes (ic);
+            }
+          else if (IC_LEFT (ic)->aggr2ptr == 1)
+            {/* band aid for kludge */
+              setOperandType (IC_LEFT (ic),
+                              aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
+              IC_LEFT (ic)->aggr2ptr++;
+              fixUpTypes (ic);
+            }
+        }
+
+      if (POINTER_SET (ic))
+        {
+          if (!IS_PTR (operandType (IC_RESULT (ic))))
+            {
+              setOperandType (IC_RESULT (ic),
+                              aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+              IC_RESULT (ic)->aggr2ptr = 0;
+            }
+          else if (IC_RESULT (ic)->aggr2ptr == 1)
+            {/* band aid for kludge */
+              setOperandType (IC_RESULT (ic),
+                              aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
+              IC_RESULT (ic)->aggr2ptr++;
+            }
+        }
+
+      /* if this is a condition statement then */
       /* check if the condition can be replaced */
       if (ic->op == IFX)
-       {
-         ifxOptimize (ic, cseSet, computeOnly,
-                      ebb, &change,
-                      ebbs, count);
-         continue;
-       }
+        {
+          ifxOptimize (ic, cseSet, computeOnly,
+                       ebb, &change,
+                       ebbi);
+          continue;
+        }
 
       /* if the assignment & result is a temp */
       /* see if we can replace it             */
-      if (ic->op == '=')
-       {
-
-         /* update the spill location for this */
-         updateSpillLocation (ic,0);
-
-         if (POINTER_SET (ic) &&
-             !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
-           {
-             pdop = NULL;
-             applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
-             if (pdop && IS_ITEMP (pdop) && !computeOnly)
-               ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
-           }
-       }
+      if (!computeOnly && ic->op == '=')
+        {
+
+          /* update the spill location for this */
+          updateSpillLocation (ic,0);
+
+          if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
+              !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
+            {
+              pdop = NULL;
+              applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
+              if (pdop && !computeOnly && IS_ITEMP (pdop))
+                {
+                  ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
+                  if (!IS_PTR (operandType (IC_RESULT (ic))))
+                    {
+                      setOperandType (IC_RESULT (ic),
+                                      aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+                    }
+                }
+            }
+        }
 
       checkSign = isSignedOp(ic);
 
@@ -1587,72 +2125,73 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* left operand */
       /* and left is a symbol  */
       if (IS_SYMOP (IC_LEFT (ic)) &&
-         !computeOnly && ic->op != ADDRESS_OF)
-       {
-
-         pdop = NULL;
-         applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
-         if (pdop)
-           {
-             if (POINTER_GET (ic))
-               {
-                 if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
-                   {
-                       /* some non dominating block does POINTER_SET with
-                          this variable .. unsafe to remove any POINTER_GETs */
-                       if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
-                           ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
-                       ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
-                     change = 1;
-                   }
-                 /* check if there is a pointer set
-                    for the same pointer visible if yes
-                    then change this into an assignment */
-                 pdop = NULL;
-                 if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
-                     !bitVectBitValue (ebb->ptrsSet, pdop->key))
-                   {
-                     ic->op = '=';
-                     IC_LEFT (ic) = NULL;
-                     ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
-                     SET_ISADDR (IC_RESULT (ic), 0);
-                   }
-
-               }
-             else
-               {
-                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
-                 change = 1;
-               }
-           }
-       }
-
-      /*right operand */
+          !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
+          !computeOnly && ic->op != ADDRESS_OF)
+        {
+
+          pdop = NULL;
+          applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
+          if (pdop)
+            {
+              if (POINTER_GET (ic))
+                {
+                  if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
+                    {
+                        /* some non dominating block does POINTER_SET with
+                           this variable .. unsafe to remove any POINTER_GETs */
+                        if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
+                            ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
+                        ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
+                      change = 1;
+                    }
+                  /* check if there is a pointer set
+                     for the same pointer visible if yes
+                     then change this into an assignment */
+                  pdop = NULL;
+                  if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) &&
+                      !bitVectBitValue (ebb->ptrsSet, pdop->key))
+                    {
+                      ic->op = '=';
+                      IC_LEFT (ic) = NULL;
+                      ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+                      SET_ISADDR (IC_RESULT (ic), 0);
+                    }
+
+                }
+              else
+                {
+                  ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
+                  change = 1;
+                }
+            }
+        }
+
+      /* right operand */
       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
-       {
-
-         pdop = NULL;
-         applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
-         if (pdop) {
-           ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
-           change = 1;
-         }
-       }
-       
+        {
+
+          pdop = NULL;
+          applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
+          if (pdop) {
+            ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+            change = 1;
+          }
+        }
+
       /* if left or right changed then do algebraic */
-      if (change)
-       {
-         algebraicOpts (ic);
-         while (constFold (ic, cseSet));
-       }
+      if (!computeOnly && change)
+        {
+          algebraicOpts (ic, ebb);
+          while (constFold (ic, cseSet));
+        }
 
-      /* if after all this it becomes a assignment to self
+      /* if after all this it becomes an assignment to self
          then delete it and continue */
-      if (ASSIGNMENT_TO_SELF (ic))
-       {
-         remiCodeFromeBBlock (ebb, ic);
-         continue;
-       }
+      if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
+        {
+          remiCodeFromeBBlock (ebb, ic);
+          continue;
+        }
 
       /* now we will check to see if the entire */
       /* operation has been performed before    */
@@ -1662,40 +2201,43 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* it only if result is a temporary         */
       pdic = NULL;
       if (!(POINTER_GET (ic) &&
-           (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
-            isOperandVolatile (IC_LEFT (ic), TRUE) ||
-            bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
-         !ASSIGNMENT (ic) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         !computeOnly)
-       {
-           applyToSet (cseSet, findPrevIc, ic, &pdic);
-         if (pdic && compareType (operandType (IC_RESULT (pdic)),
-                                operandType (IC_RESULT (ic))) != 1)
-           pdic = NULL;
-         if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) 
-             pdic = NULL;
-       }
+            (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
+             isOperandVolatile (IC_LEFT (ic), TRUE) ||
+             bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
+          !ASSIGNMENT (ic) &&
+          IS_ITEMP (IC_RESULT (ic)) &&
+          !computeOnly)
+        {
+          applyToSet (cseSet, findPrevIc, ic, &pdic);
+          if (pdic && compareType (operandType (IC_RESULT (pdic)),
+                                 operandType (IC_RESULT (ic))) != 1)
+            pdic = NULL;
+          if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
+              pdic = NULL;
+        }
 
       /* Alternate code */
       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
-       if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
-         /* Mmm, found an equivalent pointer get at a lower level. 
-            This could be a loop however with the same pointer set 
-            later on */
-       } else {
-         /* if previous definition found change this to an assignment */
-         ic->op = '=';
-         IC_LEFT(ic) = NULL;
-         IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
-         SET_ISADDR(IC_RESULT(ic),0);
-         SET_ISADDR(IC_RIGHT (ic),0);    
-       }
+        if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
+          /* Mmm, found an equivalent pointer get at a lower level.
+             This could be a loop however with the same pointer set
+             later on */
+        } else {
+          /* if previous definition found change this to an assignment */
+          ic->op = '=';
+          IC_LEFT(ic) = NULL;
+          IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
+          SET_ISADDR(IC_RESULT(ic),0);
+          SET_ISADDR(IC_RIGHT (ic),0);
+        }
       }
 
       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
-         deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
-         addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
+          cseDef *csed;
+          deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
+          csed = newCseDef (IC_RESULT (ic), ic);
+          updateCseDefAncestors (csed, cseSet);
+          addSetHead (&cseSet, csed);
       }
       defic = ic;
 
@@ -1703,101 +2245,106 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          mine and type is a pointer then delete
          pointerGets to take care of aliasing */
       if (ASSIGNMENT (ic) &&
-         OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
-         IS_PTR (operandType (IC_RESULT (ic))))
-       {
-         deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
-         for (i = 0; i < count; ebbs[i++]->visited = 0);
-         applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
-         ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
-       }
+          IS_SYMOP (IC_RESULT (ic)) &&
+          OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
+          IS_PTR (operandType (IC_RESULT (ic))))
+        {
+          deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb);
+          for (i = 0; i < count; ebbs[i++]->visited = 0);
+          applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum);
+          ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key);
+        }
 
       /* if this is a pointerget then see if we can replace
          this with a previously assigned pointer value */
       if (POINTER_GET (ic) &&
-         !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
-           isOperandVolatile (IC_LEFT (ic), TRUE)))
-       {
-         pdop = NULL;
-         applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
-         /* if we find it then locally replace all
-            references to the result with what we assigned */
-         if (pdop)
-           {
-             replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
-           }
-       }
+          !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) ||
+            isOperandVolatile (IC_LEFT (ic), TRUE)))
+        {
+          pdop = NULL;
+          applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic));
+          /* if we find it then locally replace all
+             references to the result with what we assigned */
+          if (pdop)
+            {
+              replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset);
+            }
+        }
 
       /* delete from the cseSet anything that has */
       /* operands matching the result of this     */
       /* except in case of pointer access         */
-      if (!(POINTER_SET (ic)) && IC_RESULT (ic))
-       {
-         deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
-         /* delete any previous definitions */
-         ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
-
-       }
+      if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
+        {
+          deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
+          /* delete any previous definitions */
+          ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
+        }
 
       /* add the left & right to the defUse set */
       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
-       {
-         OP_USES(IC_LEFT (ic))=
-           bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
-         setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
-       }
+        {
+          OP_USES(IC_LEFT (ic))=
+            bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+          setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+        }
 
       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
-       {
-         OP_USES(IC_RIGHT (ic))=
-           bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
-         setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
-       }
+        {
+          OP_USES(IC_RIGHT (ic))=
+            bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+          setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+        }
 
       /* for the result it is special case, put the result */
       /* in the defuseSet if it a pointer or array access  */
-      if (POINTER_SET (defic))
-       {
-         OP_USES(IC_RESULT (ic))=
-           bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
-         setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-         deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
-         ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
-         /* delete from inexpressions of all successors which
-            have dfNum > than this block */
-         for (i = 0; i < count; ebbs[i++]->visited = 0);
-         applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
-
-         /* delete from cseSet all other pointer sets
-            for this operand */
-         deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
-         /* add to the local pointerset set */
-         addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
-       }
+      if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
+        {
+          OP_USES(IC_RESULT (ic))=
+            bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+          setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+          deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
+          ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
+          /* delete from inexpressions of all successors which
+             have dfNum > than this block */
+          for (i = 0; i < count; ebbs[i++]->visited = 0);
+          applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum);
+
+          /* delete from cseSet all other pointer sets
+             for this operand */
+          deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic));
+          /* add to the local pointerset set */
+          addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
+        }
       else
-       /* add the result to defintion set */ if (IC_RESULT (ic))
-       {
-         OP_DEFS(IC_RESULT (ic))=
-           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
-         ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
-         ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
-         ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
-       }
-
+        {
+          /* add the result to definition set */
+          if (IS_SYMOP (IC_RESULT (ic)))
+            {
+              OP_DEFS(IC_RESULT (ic))=
+                bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+              ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
+              ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
+              ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
+            }
+        }
 
       /* if this is an addressof instruction then */
       /* put the symbol in the address of list &  */
       /* delete it from the cseSet                */
       if (defic->op == ADDRESS_OF)
-       {
-         addSetHead (&ebb->addrOf, IC_LEFT (ic));
-         deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
-       }
+        {
+          addSetHead (&ebb->addrOf, IC_LEFT (ic));
+          deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic));
+        }
     }
 
-  setToNull ((void **) &ebb->outExprs);
+  for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
+    if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
+        !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
+    addSetHead (&ebb->killedExprs, expr);
+  }
+  setToNull ((void *) &ebb->outExprs);
   ebb->outExprs = cseSet;
   ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
   ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
@@ -1807,16 +2354,18 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 /*-----------------------------------------------------------------*/
 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
 /*-----------------------------------------------------------------*/
-int 
-cseAllBlocks (eBBlock ** ebbs, int count)
+int
+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], FALSE, ebbs, count);
+    change += cseBBlock (ebbs[i], computeOnly, ebbi);
 
   return change;
 }