IC_RESULT needs to be a symbol
[fw/sdcc] / src / SDCCcse.c
index 00cda0b8521905d298220c27e98f27810eaa43c9..af3d2ce94a0372abbfc4b8bcac47fcb002eecb51 100644 (file)
@@ -1,3 +1,9 @@
+//#define LIVERANGEHUNT
+#ifdef LIVERANGEHUNT
+  #define LRH(x) x
+#else
+  #define LRH(x)
+#endif
 /*-------------------------------------------------------------------------
   SDCCcse.c - source file for Common Subexpressions and other utility
 
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 #include "common.h"
+#include "newalloc.h"
 
 /*-----------------------------------------------------------------*/
 /* newCseDef - new cseDef                                          */
 /*-----------------------------------------------------------------*/
-cseDef *newCseDef (operand *sym, iCode *ic)
+cseDef *
+newCseDef (operand * sym, iCode * ic)
 {
-    cseDef *cdp ;
-    
-    assert (sym);
-    ALLOC(cdp,sizeof(cseDef));    
-
-    cdp->sym = sym;
-    cdp->diCode = ic;
-    cdp->key = sym->key;       
-         
-    return cdp;
+  cseDef *cdp;
+
+  assert (sym);
+  cdp = Safe_alloc (sizeof (cseDef));
+
+  cdp->sym = sym;
+  cdp->diCode = ic;
+  cdp->key = sym->key;
+
+  return cdp;
 }
 
 
@@ -46,77 +54,156 @@ cseDef *newCseDef (operand *sym, iCode *ic)
 /*-----------------------------------------------------------------*/
 /* int isCseDefEqual - two definitions are equal                   */
 /*-----------------------------------------------------------------*/
-int isCseDefEqual ( void *vsrc, void *vdest)
+int 
+isCseDefEqual (void *vsrc, void *vdest)
 {
-    cseDef *src = vsrc;
-    cseDef *dest = vdest;  
+  cseDef *src = vsrc;
+  cseDef *dest = vdest;
+
+  if (src == dest)
+    return 1;
+
+  return (src->key == dest->key &&
+         src->diCode == dest->diCode);
 
-    if (src == dest)
-       return 1;
-    
-    return (src->key == dest->key &&
-           src->diCode == dest->diCode ) ;
-     
 }
 
 /*-----------------------------------------------------------------*/
 /* pcseDef - in the cseDef                                         */
 /*-----------------------------------------------------------------*/
-int pcseDef (void *item, va_list ap)
+int 
+pcseDef (void *item, va_list ap)
 {
-    cseDef *cdp = item;
-    iCodeTable *icTab ;
-
-    (void)ap;
-    
-    if (!cdp->sym)
-       fprintf(stdout,"**null op**");
-    printOperand(cdp->sym,stdout);
-    icTab = getTableEntry(cdp->diCode->op) ;
-    icTab->iCodePrint(stdout,cdp->diCode,icTab->printName);
-    return 1;
+  cseDef *cdp = item;
+  iCodeTable *icTab;
+
+  (void) ap;
+
+  if (!cdp->sym)
+    fprintf (stdout, "**null op**");
+  printOperand (cdp->sym, stdout);
+  icTab = getTableEntry (cdp->diCode->op);
+  icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
+  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);
+  // if op is a register equivalent
+  if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+    operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
+    if (isOperandEqual(*rop, *op)) {
+      printf ("true");
+      *rop=cop;
+      OP_SYMBOL((*op))->isreqv=0;
+      OP_SYMBOL(cop)->isreqv=1;
+    } else {
+      printf ("false");
+    }
+  }
+  printf ("\n");
+#endif
+  *op=cop;
 }
 
 /*-----------------------------------------------------------------*/
 /* replaceAllSymBySym - replaces all operands by operand in an     */
 /*                      instruction chain                          */
 /*-----------------------------------------------------------------*/
-void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
+void 
+replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 {
-    iCode *lic;
+  iCode *lic;
+
+  LRH(printf ("replaceAllSymBySym: from %s to %s\n", 
+             OP_SYMBOL(from)->name, 
+             IS_SYMOP(to) ? OP_SYMBOL(to)->name) : "!SYM");
+  for (lic = ic; lic; lic = lic->next)
+    {
+      int siaddr;
+
+      /* 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;
 
-    for (lic = ic ; lic ; lic = lic->next ) {
-       int siaddr ;
+           }
+         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 (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);
+               }
 
-       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);
            }
-           else {              
-               bitVectUnSetBit (OP_DEFS(from),lic->key);
-               OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->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 ;
+         siaddr = IC_RESULT (lic)->isaddr;
+         IC_RESULT (lic) = operandFromOperand (to);
+         IC_RESULT (lic)->isaddr = siaddr;
        }
 
-       if (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 ;
+      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;
        }
 
-       if (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 ;
+      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;
        }
     }
 }
@@ -124,866 +211,1035 @@ void replaceAllSymBySym (iCode *ic, operand *from , operand *to)
 /*-----------------------------------------------------------------*/
 /* iCodeKeyIs - if the icode keys match then return 1              */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(iCodeKeyIs)
+DEFSETFUNC (iCodeKeyIs)
 {
-    cseDef *cdp = item;
-    V_ARG(int,key);
+  cseDef *cdp = item;
+  V_ARG (int, key);
 
-    if (cdp->diCode->key == key)
-       return 1;
-    else
-       return 0;
+  if (cdp->diCode->key == key)
+    return 1;
+  else
+    return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* removeFromInExprs - removes an icode from inexpressions         */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(removeFromInExprs)
+DEFSETFUNC (removeFromInExprs)
 {
-    eBBlock *ebp = item;
-    V_ARG(iCode *,ic);
-    V_ARG(operand *,from);
-    V_ARG(operand *,to);
-    V_ARG(eBBlock *,cbp);
+  eBBlock *ebp = item;
+  V_ARG (iCode *, ic);
+  V_ARG (operand *, from);
+  V_ARG (operand *, to);
+  V_ARG (eBBlock *, cbp);
 
-    if (ebp->visited)
-       return 0;
+  if (ebp->visited)
+    return 0;
 
-    ebp->visited = 1;
-    deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key);
-    if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum))
-       replaceAllSymBySym(ebp->sch,from,to);
+  ebp->visited = 1;
+  deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
+  if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
+    replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
 
-    applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
-    return 0;
+  applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
 /*-----------------------------------------------------------------*/
-static bool isGlobalInNearSpace (operand *op)
+static bool 
+isGlobalInNearSpace (operand * op)
 {
-    link *type = getSpec(operandType(op));
-    /* this is 8051 specific: optimization
-       suggested by Jean-Louis VERN, with 8051s we have no
-       advantage of putting variables in near space into
-       registers */
-    if (isOperandGlobal(op)  &&
-       IN_DIRSPACE(SPEC_OCLS(type)))
-       return TRUE;
-    else
-       return FALSE;
+  sym_link *type = getSpec (operandType (op));
+  /* this is 8051 specific: optimization
+     suggested by Jean-Louis VERN, with 8051s we have no
+     advantage of putting variables in near space into
+     registers */
+  if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) &&
+      IN_DIRSPACE (SPEC_OCLS (type)))
+    return TRUE;
+  else
+    return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
 /* findCheaperOp - cseBBlock support routine, will check to see if */
 /*              we have a operand previously defined               */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(findCheaperOp) 
+DEFSETFUNC (findCheaperOp)
 {
-    cseDef *cdp = item ;   
-    V_ARG(operand *,cop);
-    V_ARG(operand **,opp);
+  cseDef *cdp = item;
+  V_ARG (operand *, cop);
+  V_ARG (operand **, opp);
+  V_ARG (int, checkSign);
 
-    /* if we have already found it */
-    if (*opp) 
-       return 1;
+  /* if we have already found it */
+  if (*opp)
+    return 1;
 
-    /* not found it yet check if this is the one */
-    /* and this is not the defining one          */
-    if (cop->key == cdp->key) {
-
-       /* do a special check this will help in */
-       /* 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);
+  /* not found it yet check if this is the one */
+  /* and this is not the defining one          */
+  if (cop->key == cdp->key)
+    {
+
+      /* do a special check this will help in */
+      /* 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
-               /* 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 &&
-                       ( (!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_RIGHT (cdp->diCode);
+         }
+      }
+      else
+       *opp = IC_RESULT (cdp->diCode);
     }
 
-    /* if this is an assign to a temp. then check
-       if the right side is this then return this */
-    if (IS_TRUE_SYMOP(cop) && 
-       cdp->diCode->op == '=' &&
-       !POINTER_SET(cdp->diCode) &&
-       cop->key == IC_RIGHT(cdp->diCode)->key &&
-       !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) &&
-       IS_ITEMP(IC_RESULT(cdp->diCode)))
-       *opp = IC_RESULT(cdp->diCode);
-
-    if (*opp) {
-
-       if ((isGlobalInNearSpace(cop) && 
-           !isOperandLiteral(*opp)) ||
-           isOperandVolatile(*opp,FALSE) 
-           ) {
-           *opp = NULL;
-           return 0;
+  /* if this is an assign to a temp. then check
+     if the right side is this then return this */
+  if (IS_TRUE_SYMOP (cop) &&
+      cdp->diCode->op == '=' &&
+      !POINTER_SET (cdp->diCode) &&
+      cop->key == IC_RIGHT (cdp->diCode)->key &&
+      !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) &&
+      IS_ITEMP (IC_RESULT (cdp->diCode)))
+    *opp = IC_RESULT (cdp->diCode);
+
+  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)))))))
+      {
+
+      if ((isGlobalInNearSpace (cop) &&
+          !isOperandLiteral (*opp)) ||
+         isOperandVolatile (*opp, FALSE)
+       )
+       {
+         *opp = NULL;
+         return 0;
        }
-                   
-       if (cop->key == (*opp)->key )  {
-           *opp = NULL ;
-           return 0;       
+
+      if (cop->key == (*opp)->key)
+       {
+         *opp = NULL;
+         return 0;
        }
-       
-       if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
-           *opp = operandFromOperand(*opp);
-           (*opp)->isaddr = cop->isaddr;
+
+      if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
+       {
+         *opp = operandFromOperand (*opp);
+         (*opp)->isaddr = cop->isaddr;
        }
-       
-       return 1;
-       
+         
+      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));
+      return 1;
+
     }
-       
-    return 0;
+  *opp=NULL;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* findPointerSet - finds the right side of a pointer set op       */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(findPointerSet)
+DEFSETFUNC (findPointerSet)
 {
-    cseDef *cdp = item;
-    V_ARG(operand *,op);
-    V_ARG(operand **,opp);
-    V_ARG(operand *,rop);
-
-    if (POINTER_SET(cdp->diCode)               &&
-       IC_RESULT(cdp->diCode)->key == op->key &&
-       !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) &&
-       !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE)  &&
-       getSize(operandType(IC_RIGHT(cdp->diCode))) ==
-       getSize(operandType(rop))) {
-       *opp = IC_RIGHT(cdp->diCode);
-       return 1;
+  cseDef *cdp = item;
+  V_ARG (operand *, op);
+  V_ARG (operand **, opp);
+  V_ARG (operand *, rop);
+
+  if (POINTER_SET (cdp->diCode) &&
+      IC_RESULT (cdp->diCode)->key == op->key &&
+      !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) &&
+      !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) &&
+      getSize (operandType (IC_RIGHT (cdp->diCode))) ==
+      getSize (operandType (rop)))
+    {
+      *opp = IC_RIGHT (cdp->diCode);
+      return 1;
     }
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* findPrevIc - cseBBlock support function will return the iCode   */
 /*              which matches the current one                      */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(findPrevIc)
+DEFSETFUNC (findPrevIc)
 {
-    cseDef *cdp = item ;    
-    V_ARG(iCode *,ic);
-    V_ARG(iCode **,icp);
-
-    /* if already found */
-    if (*icp)
-       return 1;  
-   
-    /* if the iCodes are the same */
-    if (isiCodeEqual(ic,cdp->diCode) && 
-       isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) {
-       *icp = cdp->diCode ;
-       return 1;
+  cseDef *cdp = item;
+  V_ARG (iCode *, ic);
+  V_ARG (iCode **, icp);
+
+  /* if already found */
+  if (*icp)
+    return 1;
+
+  /* if the iCodes are the same */
+  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;
+      return 1;
     }
 
-    /* if iCodes are not the same */
-    /* see the operands maybe interchanged */
-    if (ic->op == cdp->diCode->op          &&
-       ( ic->op == '+' || ic->op == '*' ) &&
-       isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) &&
-       isOperandEqual(IC_RIGHT(ic),IC_LEFT(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 == '*') &&
+      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;
     }
 
-    return 0;
+  return 0;
+}
+
+/*-------------------------------------------------------------------*/
+/* ifAssignedFromGlobal - if definition is an assignment from global */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifAssignedFromGlobal)
+{
+  cseDef *cdp = item;
+  iCode *dic=cdp->diCode;
+
+  if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
+    return 1;
+  }
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* ifDefGlobal - if definition is global                           */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifDefGlobal)
+DEFSETFUNC (ifDefGlobal)
+{
+  cseDef *cdp = item;
+
+  return (isOperandGlobal (cdp->sym));
+}
+
+/*-----------------------------------------------------------------*/
+/* ifAnyGetPointer - if get pointer icode                          */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC (ifAnyGetPointer)
 {
-    cseDef *cdp = item;
-    
-    return (isOperandGlobal(cdp->sym));
+  cseDef *cdp = item;
+
+  if (cdp->diCode && POINTER_GET (cdp->diCode))
+    return 1;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* ifOperandsHave - if any of the operand are the same as this     */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifOperandsHave)
+DEFSETFUNC (ifOperandsHave)
 {
-    cseDef *cdp = item;    
-    V_ARG(operand *,op);    
+  cseDef *cdp = item;
+  V_ARG (operand *, op);
 
-    
-    if (IC_LEFT(cdp->diCode) && 
-       IS_SYMOP(IC_LEFT(cdp->diCode)) &&
-       IC_LEFT(cdp->diCode)->key == op->key)
-       return 1;
-    
-    if (IC_RIGHT(cdp->diCode)  &&
-       IS_SYMOP(IC_RIGHT(cdp->diCode)) &&
-       IC_RIGHT(cdp->diCode)->key == op->key)
-       return 1;
-    
-    /* or if any of the operands are volatile */
-    if (IC_LEFT(cdp->diCode) && 
-       IS_OP_VOLATILE(IC_LEFT(cdp->diCode)))        
-       return 1;    
-
-    if (IC_RIGHT(cdp->diCode) && 
-       IS_OP_VOLATILE(IC_RIGHT(cdp->diCode))) 
-       return 1;
-    
 
-    if (IC_RESULT(cdp->diCode) && 
-       IS_OP_VOLATILE(IC_RESULT(cdp->diCode)))         
-       return 1;    
+  if (IC_LEFT (cdp->diCode) &&
+      IS_SYMOP (IC_LEFT (cdp->diCode)) &&
+      IC_LEFT (cdp->diCode)->key == op->key)
+    return 1;
 
-    return 0;
+  if (IC_RIGHT (cdp->diCode) &&
+      IS_SYMOP (IC_RIGHT (cdp->diCode)) &&
+      IC_RIGHT (cdp->diCode)->key == op->key)
+    return 1;
+
+  /* or if any of the operands are volatile */
+  if (IC_LEFT (cdp->diCode) &&
+      IS_OP_VOLATILE (IC_LEFT (cdp->diCode)))
+    return 1;
+
+  if (IC_RIGHT (cdp->diCode) &&
+      IS_OP_VOLATILE (IC_RIGHT (cdp->diCode)))
+    return 1;
+
+
+  if (IC_RESULT (cdp->diCode) &&
+      IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
+    return 1;
+
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* ifDefSymIs - if a definition is found in the set                */
 /*-----------------------------------------------------------------*/
- int ifDefSymIs (set *cseSet, operand *sym)
+int 
+ifDefSymIs (set * cseSet, operand * sym)
 {
-    cseDef *loop ;
-    set *sl ;
-
-    if (!sym || !IS_SYMOP(sym))
-       return 0;  
-    for (sl = cseSet ; sl ; sl = sl->next ) {
-       loop = sl->item;        
-       if (loop->sym->key == sym->key )           
-           return 1;   
-    }
+  cseDef *loop;
+  set *sl;
+
+  if (!sym || !IS_SYMOP (sym))
     return 0;
+  for (sl = cseSet; sl; sl = sl->next)
+    {
+      loop = sl->item;
+      if (loop->sym->key == sym->key)
+       return 1;
+    }
+  return 0;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* ifDefSymIsX - will return 1 if the symbols match                */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifDefSymIsX)
-{     
-    cseDef *cdp  = item;
-    V_ARG(operand *,op);    
+DEFSETFUNC (ifDefSymIsX)
+{
+  cseDef *cdp = item;
+  V_ARG (operand *, op);
 
-    if (op && cdp->sym)
-       return cdp->sym->key == op->key ;
-    else
-       return ( isOperandEqual(cdp->sym,op) );
-            
-} 
+  if (op && cdp->sym)
+    return cdp->sym->key == op->key;
+  else
+    return (isOperandEqual (cdp->sym, op));
+
+}
 
 
 /*-----------------------------------------------------------------*/
 /* ifDiCodeIs - returns truw if diCode is same                     */
 /*-----------------------------------------------------------------*/
- int ifDiCodeIs (set *cseSet, iCode *ic)
+int 
+ifDiCodeIs (set * cseSet, iCode * ic)
 {
-    cseDef *loop;
-    set *sl;
-    
-    if (!ic)
-       return 0;
-
-    for (sl = cseSet ; sl ; sl = sl->next ) {
-       loop = sl->item ;
-       if (loop->diCode == ic)
-           return 1;
-    }
+  cseDef *loop;
+  set *sl;
+
+  if (!ic)
     return 0;
-    
+
+  for (sl = cseSet; sl; sl = sl->next)
+    {
+      loop = sl->item;
+      if (loop->diCode == ic)
+       return 1;
+    }
+  return 0;
+
 }
 
 /*-----------------------------------------------------------------*/
 /* ifPointerGet - returns true if the icode is pointer get sym     */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifPointerGet)
+DEFSETFUNC (ifPointerGet)
 {
-    cseDef *cdp = item;
-    V_ARG(operand *,op);
-    iCode *dic = cdp->diCode;
-    operand *left = IC_LEFT(cdp->diCode);
+  cseDef *cdp = item;
+  V_ARG (operand *, op);
+  iCode *dic = cdp->diCode;
+  operand *left = IC_LEFT (cdp->diCode);
 
-    if (POINTER_GET(dic) && left->key == op->key)
-       return 1;
+  if (POINTER_GET (dic) && left->key == op->key)
+    return 1;
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* ifPointerSet - returns true if the icode is pointer set sym     */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifPointerSet)
+DEFSETFUNC (ifPointerSet)
 {
-    cseDef *cdp = item;
-    V_ARG(operand *,op);
+  cseDef *cdp = item;
+  V_ARG (operand *, op);
 
-    if (POINTER_SET(cdp->diCode) &&
-       IC_RESULT(cdp->diCode)->key == op->key)
-       return 1;
+  if (POINTER_SET (cdp->diCode) &&
+      IC_RESULT (cdp->diCode)->key == op->key)
+    return 1;
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* ifDiCodeIsX - will return 1 if the symbols match                 */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifDiCodeIsX)
-{     
-    cseDef *cdp  = item;
-    V_ARG(iCode *,ic);    
+DEFSETFUNC (ifDiCodeIsX)
+{
+  cseDef *cdp = item;
+  V_ARG (iCode *, ic);
+
+  return cdp->diCode == ic;
 
-    return cdp->diCode == ic;
-            
+}
+
+/*-----------------------------------------------------------------*/
+/* findBackwardDef - scan backwards to find deinition of operand   */
+/*-----------------------------------------------------------------*/
+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;
+    }
+    return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* algebraicOpts - does some algebraic optimizations               */
 /*-----------------------------------------------------------------*/
-void algebraicOpts (iCode *ic)
+void 
+algebraicOpts (iCode * ic)
 {
-    /* we don't deal with the following iCodes
-       here */
-    if (ic->op == IFX   ||
-       ic->op == IPUSH ||
-       ic->op == IPOP  ||
-       ic->op == CALL  ||
-       ic->op == PCALL ||
-       ic->op == RETURN ||
-       POINTER_GET(ic))
-       return ;
-
-    /* if both operands present & ! IFX */
-    /* then if they are both literal we */
-    /* perform the operation right now  */
-    if (IC_RESULT(ic) &&
-       IC_RIGHT(ic)  &&
-       IC_LEFT(ic)   &&
-       IS_OP_LITERAL(IC_LEFT(ic)) &&
-       IS_OP_LITERAL(IC_RIGHT(ic))) {
-       
-       IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
-                                        IC_RIGHT(ic),
-                                        ic->op,
-                                        operandType(IC_RESULT(ic)));
-       ic->op = '=';       
-       IC_LEFT(ic) = NULL ;
-       SET_RESULT_RIGHT(ic);
-       return ;
-       
+  /* we don't deal with the following iCodes
+     here */
+  if (ic->op == IFX ||
+      ic->op == IPUSH ||
+      ic->op == IPOP ||
+      ic->op == CALL ||
+      ic->op == PCALL ||
+      ic->op == RETURN ||
+      POINTER_GET (ic))
+    return;
+
+  /* if both operands present & ! IFX */
+  /* then if they are both literal we */
+  /* perform the operation right now  */
+  if (IC_RESULT (ic) &&
+      IC_RIGHT (ic) &&
+      IC_LEFT (ic) &&
+      IS_OP_LITERAL (IC_LEFT (ic)) &&
+      IS_OP_LITERAL (IC_RIGHT (ic)))
+    {
+
+      IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
+                                       IC_RIGHT (ic),
+                                       ic->op,
+                                       operandType (IC_RESULT (ic)));
+      ic->op = '=';
+      IC_LEFT (ic) = NULL;
+      SET_RESULT_RIGHT (ic);
+      return;
+
     }
-    /* if not ifx & only one operand present */
-    if (IC_RESULT(ic) &&
-       IC_LEFT(ic)   &&
-       IS_OP_LITERAL(IC_LEFT(ic)) &&
-       !IC_RIGHT(ic)) {
-       
-       IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
-                                        IC_RIGHT(ic),
-                                        ic->op,
-                                        operandType(IC_RESULT(ic)));
-       ic->op = '=';
-       IC_LEFT(ic) = NULL ;
-       SET_RESULT_RIGHT(ic);
-       return ;
+  /* if not ifx & only one operand present */
+  if (IC_RESULT (ic) &&
+      IC_LEFT (ic) &&
+      IS_OP_LITERAL (IC_LEFT (ic)) &&
+      !IC_RIGHT (ic))
+    {
+
+      IC_RIGHT (ic) = operandOperation (IC_LEFT (ic),
+                                       IC_RIGHT (ic),
+                                       ic->op,
+                                       operandType (IC_RESULT (ic)));
+      ic->op = '=';
+      IC_LEFT (ic) = NULL;
+      SET_RESULT_RIGHT (ic);
+      return;
     }
 
-    
-    /* a special case : or in short a kludgy solution will think 
-       about a better solution over a glass of wine someday */
-    if ( ic->op == GET_VALUE_AT_ADDRESS ) {
-
-       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;
+
+  /* a special case : or in short a kludgy solution will think
+     about a better solution over a glass of wine someday */
+  if (ic->op == GET_VALUE_AT_ADDRESS)
+    {
+
+      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;
        }
 
-       if (IS_ITEMP(IC_LEFT(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;
+      if (IS_ITEMP (IC_LEFT (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;
        }
 
     }
-   
 
-    /* depending on the operation */
-    switch (ic->op) {
-    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;
+
+  /* depending on the operation */
+  switch (ic->op)
+    {
+    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;
        }
-       /* if addition then check if one of them is a zero */ 
-       /* if yes turn it  into assignmnt*/
-       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 ;
+      /* if addition then check if one of them is a zero */
+      /* if yes turn it  into assignmnt */
+      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;
        }
-       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 ;
+      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;
        }
-       break ;
-    case '-' :
-       /* if subtracting the 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 ;
-       }           
-           
-       /* 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 ;
+      break;
+    case '-':
+      /* if subtracting the 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;
        }
-       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 ;
+
+      /* 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;
        }
-       break;
-       /* if multiplication then check if either of */
-       /* them is zero then the result is zero      */
-       /* if either of them is one then result is   */
-       /* 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 (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;
+       }
+      break;
+      /* if multiplication then check if either of */
+      /* them is zero then the result is zero      */
+      /* if either of them is one then result is   */
+      /* 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;
            }
-           if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
-               ic->op = '=' ;
-               IC_LEFT(ic) = NULL ;
-               SET_RESULT_RIGHT(ic);
-               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 (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 ;
+         if (operandLitValue (IC_RIGHT (ic)) == 1.0)
+           {
+             ic->op = '=';
+             IC_RIGHT (ic) = IC_LEFT (ic);
+             IC_LEFT (ic) = NULL;
+             SET_RESULT_RIGHT (ic);
+             return;
            }
        }
-       break ;
+      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;
+      /* 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;
        }
-       /* 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 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;
        }
-       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);
+      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);
        }
-       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);
+      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);
        }
-       break ;
-    case CAST :
-       /* if this is a cast of a literal value */
-       if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
-           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 ( checkType(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);            
+      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;
+    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);
        }
     }
-    
-    return ;
+
+  return;
 }
 #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
 /*-----------------------------------------------------------------*/
 /* updateSpillLocation - keeps track of register spill location    */
 /*-----------------------------------------------------------------*/
-void updateSpillLocation ( iCode *ic)
+void 
+updateSpillLocation (iCode * ic, int induction)
 {
+       sym_link *setype;
 
-    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))) {
+       /* for the form true_symbol := iTempNN */
+       if (ASSIGN_ITEMP_TO_SYM (ic) && 
+           !SPIL_LOC (IC_RIGHT (ic))) {
 
-       setype = getSpec(operandType(IC_RESULT(ic)));
-       
-        if (!IC_RIGHT(ic)->noSpilLoc           &&
-           !IS_VOLATILE(setype)               &&
-           !IN_FARSPACE(SPEC_OCLS(setype))    &&
-           !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
-           
-           SPIL_LOC(IC_RIGHT(ic))  =
-               IC_RESULT(ic)->operand.symOperand;   
-    }
+               setype = getSpec (operandType (IC_RESULT (ic)));
 
-    if (ASSIGN_ITEMP_TO_ITEMP(ic) &&
-       !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 (!IC_RIGHT(ic)->noSpilLoc           &&
-           !IS_VOLATILE(setype)               &&
-           !IN_FARSPACE(SPEC_OCLS(setype))    &&
-           !OTHERS_PARM(OP_SYMBOL(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;
+               }
            
-           SPIL_LOC(IC_RIGHT(ic)) = 
-               SPIL_LOC(IC_RESULT(ic));
-    }
-}
+       }
 
+#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;
+       }
+#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));
+               }
+       }
+}
 /*-----------------------------------------------------------------*/
 /* setUsesDef - sets the uses def bitvector for a given operand    */
 /*-----------------------------------------------------------------*/
-void setUsesDefs (operand *op, bitVect *bdefs, 
-                 bitVect *idefs, bitVect **oud)
+void 
+setUsesDefs (operand * op, bitVect * bdefs,
+            bitVect * idefs, bitVect ** oud)
 {
-    /* compute the definitions alive at this point */
-    bitVect *adefs = bitVectUnion(bdefs,idefs);
-
-    /* of these definitions find the ones that are */
-    /* for this operand */
-    adefs = bitVectIntersect(adefs,OP_DEFS(op));
-    
-    /* these are the definitions that this operand can use */
-    op->usesDefs = adefs;
-    
-    /* the out defs is an union */
-    *oud = bitVectUnion(*oud,adefs);
+  /* compute the definitions alive at this point */
+  bitVect *adefs = bitVectUnion (bdefs, idefs);
+
+  /* of these definitions find the ones that are */
+  /* for this operand */
+  adefs = bitVectIntersect (adefs, OP_DEFS (op));
+
+  /* these are the definitions that this operand can use */
+  op->usesDefs = adefs;
+
+  /* the out defs is an union */
+  *oud = bitVectUnion (*oud, adefs);
 }
 
 /*-----------------------------------------------------------------*/
 /* unsetDefsAndUses - clear this operation for the operands        */
 /*-----------------------------------------------------------------*/
-void unsetDefsAndUses ( iCode *ic ) 
+void 
+unsetDefsAndUses (iCode * ic)
 {
-    if ( ic->op == JUMPTABLE)
-       return ;
-
-    /* take away this definition from the def chain of the */
-    /* result & take away from use set of the operands */
-    if (ic->op != IFX) {
-       /* 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 (ic->op == JUMPTABLE)
+    return;
+
+  /* take away this definition from the def chain of the */
+  /* result & take away from use set of the operands */
+  if (ic->op != IFX)
+    {
+      /* 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);
        }
-       /* turn off the useSet for the operands */
-       if (IS_SYMOP(IC_LEFT(ic)))
-           bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
-       
-       if (IS_SYMOP(IC_RIGHT(ic)))
-           bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
+      /* turn off the useSet for the operands */
+      if (IS_SYMOP (IC_LEFT (ic)))
+       bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+
+      if (IS_SYMOP (IC_RIGHT (ic)))
+       bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
     }
-    else /* must be ifx turn off the use */
-       if (IS_SYMOP(IC_COND(ic)))
-           bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);    
+  else
+    /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic)))
+    bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
 }
 
 /*-----------------------------------------------------------------*/
 /* ifxOptimize - changes ifx conditions if it can                  */
 /*-----------------------------------------------------------------*/
-void ifxOptimize (iCode *ic, set *cseSet, 
-                        int computeOnly , 
-                        eBBlock *ebb, int *change,
-                        eBBlock **ebbs, int count)
+void 
+ifxOptimize (iCode * ic, set * cseSet,
+            int computeOnly,
+            eBBlock * ebb, int *change,
+            eBBlock ** ebbs, int count)
 {
-    operand *pdop ;
-    symbol *label;
-
-    /* if the condition can be replaced */
-    if (!computeOnly) {
-       pdop = NULL ;
-       applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
-       if (pdop) {
-           IC_COND(ic) = pdop ;
-           (*change)++;
+  operand *pdop;
+  symbol *label;
+
+  /* if the condition can be replaced */
+  if (!computeOnly)
+    {
+      pdop = NULL;
+      applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
+      if (pdop)
+       {
+         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)++;
-           
-       } 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 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)++;
+
        }
-       
-       /* 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);
-       werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
-       return ;
+      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);
+           }
+       }
+
+      /* 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);
+      }
+      return;
     }
-    
-    /* if there is only one successor and that successor
-       is the same one we are conditionally going to then
-       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))) {
-
-       remiCodeFromeBBlock(ebb,ic);
-       computeControlFlow (ebbs,count,1);
-       werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
-       return ;        
+
+  /* if there is only one successor and that successor
+     is the same one we are conditionally going to then
+     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)))
+    {
+
+      remiCodeFromeBBlock (ebb, ic);
+      computeControlFlow (ebbs, count, 1);
+      if (!options.lessPedantic) {
+       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+      }
+      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);
-    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);
+  return;
 }
 
 /*-----------------------------------------------------------------*/
 /* diCodeForSym - finds the definiting instruction for a symbol    */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(diCodeForSym)
+DEFSETFUNC (diCodeForSym)
 {
-    cseDef *cdp = item;
-    V_ARG(operand *,sym);
-    V_ARG(iCode **,dic);
+  cseDef *cdp = item;
+  V_ARG (operand *, sym);
+  V_ARG (iCode **, dic);
 
-    /* if already found */
-    if (*dic)
-       return 0;
+  /* if already found */
+  if (*dic)
+    return 0;
 
-    /* if not if this is the defining iCode */
-    if (sym->key == cdp->key) {
-       *dic = cdp->diCode ;
-       return 1;
+  /* if not if this is the defining iCode */
+  if (sym->key == cdp->key)
+    {
+      *dic = cdp->diCode;
+      return 1;
     }
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* constFold - does some constant folding                          */
 /*-----------------------------------------------------------------*/
-int constFold (iCode *ic, set *cseSet)
+int 
+constFold (iCode * ic, set * cseSet)
 {
-    iCode *dic = NULL;
-    /* this routine will change
-       a = b + 10;
-       c = a + 10;
-       to
-       c = b + 20; */
-
-    /* deal with only + & - */
-    if (ic->op != '+' &&
-       ic->op != '-' )
-       return 0;
-
-    /* this check is a hueristic to prevent live ranges
-       from becoming too long */
-    if (IS_PTR(operandType(IC_RESULT(ic))))
-       return 0;
-
-    /* check if operation with a literal */
-    if (!IS_OP_LITERAL(IC_RIGHT(ic)))
-       return 0;
-
-    /* check if we can find a definition for the
-       right hand side */
-    if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
-       return 0;
-
-    /* check that this is also a +/-  */
-    if (dic->op != '+' && dic->op != '-')
-       return 0;
-
-    /* with a literal */
-    if (!IS_OP_LITERAL(IC_RIGHT(dic)))
-       return 0;
-
-    /* it is if the operations are the same*/
-    /* the literal parts need to be added  */
-    IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));    
-    if (ic->op == dic->op )
-       IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
-                                     operandLitValue(IC_RIGHT(dic)));
-    else
-       IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
-                                     operandLitValue(IC_RIGHT(dic)));
-
-    if (IS_ITEMP(IC_RESULT(ic))) {
-       SPIL_LOC(IC_RESULT(ic)) = NULL;
-       IC_RESULT(ic)->noSpilLoc = 1;
+  iCode *dic = NULL;
+  iCode *ldic = NULL;
+  /* this routine will change
+     a = b + 10;
+     c = a + 10;
+     to
+     c = b + 20; */
+
+  /* deal with only + & - */
+  if (ic->op != '+' &&
+      ic->op != '-')
+    return 0;
+
+  /* this check is a hueristic to prevent live ranges
+     from becoming too long */
+  if (IS_PTR (operandType (IC_RESULT (ic))))
+      return 0;
+
+  /* check if operation with a literal */
+  if (!IS_OP_LITERAL (IC_RIGHT (ic)))
+    return 0;
+
+  /* check if we can find a definition for the
+     right hand side */
+  if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
+    return 0;
+
+  /* check that this is also a +/-  */
+  if (dic->op != '+' && dic->op != '-')
+    return 0;
+
+  /* with a literal */
+  if (!IS_OP_LITERAL (IC_RIGHT (dic)))
+    return 0;
+
+  /* find the definition of the left operand
+     of dic.then check if this defined with a
+     get_pointer return 0 if the pointer size is
+     less than 2 (MCS51 specific) */
+  if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic)))
+    return 0;
+
+  if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1)
+    return 0;
+
+  /* it is if the operations are the same */
+  /* the literal parts need to be added  */
+  IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic));
+  if (ic->op == dic->op)
+    IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) +
+                                   operandLitValue (IC_RIGHT (dic)));
+  else
+    IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) -
+                                   operandLitValue (IC_RIGHT (dic)));
+
+  if (IS_ITEMP (IC_RESULT (ic)))
+    {
+      SPIL_LOC (IC_RESULT (ic)) = NULL;
+      OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
     }
-       
-    
-    return 1;
+
+
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -991,72 +1247,155 @@ int 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 deleteGetPointers (set **cseSet, set **pss, operand *op,eBBlock *ebb)
+static void 
+deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
 {
-    set *compItems = NULL;
-    cseDef *cdp ;
-    operand *cop;
-    
-    /* easy return */
-    if (!*cseSet && !*pss)
-       return ;
-    
-    /* first 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)) {
-       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));
+  set *compItems = NULL;
+  cseDef *cdp;
+  operand *cop;
+
+  /* easy return */
+  if (!*cseSet && !*pss)
+    return;
+
+  /* first 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))
+    {
+      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,IC_LEFT(cdp->diCode),isOperandEqual) ||
-               isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
-                   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));
            }
        }
     }
-    
-    /* 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(pss,ifPointerSet,cop);
+
+  /* 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 (pss, ifPointerSet, cop);
     }
 }
 
 /*-----------------------------------------------------------------*/
-/* delGetPointerSucc - delete get pointer from inExprs of succ with*/
+/* delGetPointerSucc - delete get pointer from inExprs of succ with */
 /*                     dfnum > supplied                            */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(delGetPointerSucc)
+DEFSETFUNC (delGetPointerSucc)
 {
-    eBBlock *ebp = item;
-    V_ARG(operand *,op);
-    V_ARG(int,dfnum);
-
-    if (ebp->visited)
-       return 0;
-    
-    ebp->visited = 1;
-    if (ebp->dfnum > dfnum) {
-       deleteItemIf(&ebp->inExprs,ifPointerGet,op);
+  eBBlock *ebp = item;
+  V_ARG (operand *, op);
+  V_ARG (int, dfnum);
+
+  if (ebp->visited)
+    return 0;
+
+  ebp->visited = 1;
+  if (ebp->dfnum > dfnum)
+    {
+      deleteItemIf (&ebp->inExprs, ifPointerGet, op);
     }
 
-    return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
-}    
+  return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
+}
+
+/*-----------------------------------------------------------------*/
+/* fixUpTypes - KLUGE HACK fixup a lowering problem                */
+/*-----------------------------------------------------------------*/
+static void 
+fixUpTypes (iCode * ic)
+{
+  sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
+
+  /* if (TARGET_IS_DS390) */
+  if (options.model == MODEL_FLAT24)
+    {
+      /* hack-o-matic! */
+      return;
+    }
+
+  /* for pointer_gets if the types of result & left r the
+     same then change it type of result to next */
+  if (IS_PTR (t1) &&
+      compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
+    {
+      setOperandType (IC_RESULT (ic), t2->next);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* isSignedOp - will return 1 if sign is important to operation    */
+/*-----------------------------------------------------------------*/
+static int isSignedOp (iCode *ic)
+{
+    switch (ic->op) {
+    case '!':
+    case '~':
+    case UNARYMINUS:
+    case IPUSH:
+    case IPOP:
+    case CALL:
+    case PCALL:
+    case RETURN:
+    case '+':
+    case '-':
+    case EQ_OP:
+    case AND_OP:
+    case OR_OP:
+    case '^':
+    case '|':
+    case BITWISEAND:
+    case INLINEASM:
+    case LEFT_OP:
+    case GET_VALUE_AT_ADDRESS:
+    case '=':
+    case IFX:
+    case RECEIVE:
+    case SEND:
+       return 0;
+    case '*':
+    case '/':
+    case '%':
+    case '>':
+    case '<':
+    case LE_OP:
+    case GE_OP:
+    case NE_OP:
+    case RRC:
+    case RLC:
+    case GETHBIT:
+    case RIGHT_OP:
+    case CAST:
+    case ARRAYINIT:
+       return 1;
+    default:
+       return 0;
+    }
+ }
 
 /*-----------------------------------------------------------------*/
 /* cseBBlock - common subexpression elimination for basic blocks   */
@@ -1064,389 +1403,423 @@ DEFSETFUNC(delGetPointerSucc)
 /*             system. also the most important, since almost all   */
 /*             data flow related information is computed by it     */
 /*-----------------------------------------------------------------*/
-int cseBBlock ( eBBlock *ebb, int computeOnly, 
-               eBBlock **ebbs, int count)
+int 
+cseBBlock (eBBlock * ebb, int computeOnly,
+          eBBlock ** ebbs, int count)
 {
-    set *cseSet ;
-    iCode *ic ;           
-    int change = 0 ;
-    int i;   
-    set *ptrSetSet = NULL;
-
-    /* if this block is not reachable */
-    if (ebb->noPath)
-       return change;
-
-   /* 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);
-
-    ebb->outDefs = bitVectCopy (ebb->inDefs);
-    bitVectDefault = iCodeKey;
-    ebb->defSet = newBitVect(iCodeKey);
-    ebb->usesDefs=newBitVect(iCodeKey);
-
-    /* for all the instructions in this block do */
-    for (ic = ebb->sch ; ic ; ic = ic->next ) {
-       
-       iCode *pdic; 
-       operand *pdop ;
-       iCode *defic;
-       
-       if (SKIP_IC2(ic))
-           continue ;
+  set *cseSet;
+  iCode *ic;
+  int change = 0;
+  int i;
+  set *ptrSetSet = NULL;
+
+  /* if this block is not reachable */
+  if (ebb->noPath)
+    return change;
 
-       /* 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);
+  /* 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);
+
+  ebb->outDefs = bitVectCopy (ebb->inDefs);
+  bitVectDefault = iCodeKey;
+  ebb->defSet = newBitVect (iCodeKey);
+  ebb->usesDefs = newBitVect (iCodeKey);
+
+  /* for all the instructions in this block do */
+  for (ic = ebb->sch; ic; ic = ic->next)
+    {
+      iCode *pdic;
+      operand *pdop;
+      iCode *defic;
+      int checkSign ;
+
+      ic->eBBlockNum = ebb->bbnum;
+
+      if (SKIP_IC2 (ic))
+       continue;
+
+      /* if this is an assignment from true symbol
+         to a temp then do pointer post inc/dec optimzation */
+      if (ic->op == '=' && !POINTER_SET (ic) &&
+         IS_PTR (operandType (IC_RESULT (ic))))
+       {
+         ptrPostIncDecOpt (ic);
        }
 
-       /* 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);
-               if (pdop)
-                   IC_LEFT(ic) = pdop ;
+      /* 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);
+       }
+
+      /* 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);
+         /* 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);
+
+         /* 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;
+         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 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 (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));
+      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 (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 */
-       /* check if the condition can be replaced */
-       if (ic->op == IFX ) {
-           ifxOptimize (ic, cseSet, computeOnly, 
-                        ebb, &change, 
-                        ebbs, count);
-           continue ;
+      /* if this is a condition statment then */
+      /* check if the condition can be replaced */
+      if (ic->op == IFX)
+       {
+         ifxOptimize (ic, cseSet, computeOnly,
+                      ebb, &change,
+                      ebbs, count);
+         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);
-
-           if (POINTER_SET(ic)) {
-               pdop = NULL ;
-               applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
-               if (pdop && IS_ITEMP(pdop) && !computeOnly)                 
-                   IC_RESULT(ic) = pdop;                               
+
+      /* 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);
            }
-       }           
-       
-       /* do the operand lookup i.e. for both the */
-       /* right & left operand : check the cseSet */
-       /* to see if they have been replaced if yes*/
-       /* then replace them with those from cseSet*/
-       /* 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) ;
-           if (pdop)  { 
-               if (POINTER_GET(ic)) {
-                   if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
-                       IC_LEFT(ic) = pdop;
-                       change = 1;
+       }
+
+      checkSign = isSignedOp(ic);
+
+      /* do the operand lookup i.e. for both the */
+      /* right & left operand : check the cseSet */
+      /* to see if they have been replaced if yes */
+      /* then replace them with those from cseSet */
+      /* 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;
-                       IC_RIGHT(ic) = pdop;
-                       SET_ISADDR(IC_RESULT(ic),0);
+                 /* 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 {
-                   IC_LEFT(ic)  = pdop ;
-                   change = 1;
+             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);
-           if (pdop) {
-               
-               IC_RIGHT(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;
+         }
+       }
        
-       /* if left or right changed then do algebraic */
-       if (change) {
-           algebraicOpts(ic);
-           while(constFold(ic,cseSet));
+      /* if left or right changed then do algebraic */
+      if (change)
+       {
+         algebraicOpts (ic);
+         while (constFold (ic, cseSet));
        }
 
-       /* if after all this it becomes a assignment to self 
-          then delete it and continue */
-       if (ASSIGNMENT_TO_SELF(ic)) {      
-           remiCodeFromeBBlock(ebb,ic);
-           continue;
-       }           
-       
-       /* now we will check to see if the entire */
-       /* operation has been performed before    */
-       /* and is available                       */     
-       /* don't do assignments they will be killed */
-       /* by dead code elimination if required  do */
-       /* 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))) &&
-           ! ASSIGNMENT(ic)                        && 
-             IS_ITEMP(IC_RESULT(ic))               &&
-           ! computeOnly) {
-           applyToSet (cseSet,findPrevIc,ic,&pdic);
-       } 
-       
-       /* if found then eliminate this and add to*/
-       /* to cseSet an element containing result */
-       /* of this with previous opcode           */      
-       if (pdic) {
-
-           if (IS_ITEMP(IC_RESULT(ic))) {
-
-               /* replace in the remaining of this block */
-               replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic));
-               /* remove this iCode from inexpressions of all
-                  its successors, it cannot be in the in expressions
-                  of any of the predecessors */        
-               for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
-               applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
-                          IC_RESULT(pdic),ebb);
-
-               /* if this was moved from another block */
-               /* then replace in those blocks too     */
-               if ( ic->movedFrom ) {
-                   eBBlock *owner ;
-                   for (owner = setFirstItem(ic->movedFrom); owner ;
-                        owner = setNextItem(ic->movedFrom))
-                       replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic));
-               }
-               pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
-           } 
-           else
-               addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));                     
-           
-           if (!computeOnly) 
-               /* eliminate this */
-               remiCodeFromeBBlock (ebb,ic);               
-                   
-           defic = pdic ;          
-           change++ ;
+      /* if after all this it becomes a assignment to self
+         then delete it and continue */
+      if (ASSIGNMENT_TO_SELF (ic))
+       {
+         remiCodeFromeBBlock (ebb, ic);
+         continue;
+       }
 
-           if (IS_ITEMP(IC_RESULT(ic)))
-               continue ;
+      /* now we will check to see if the entire */
+      /* operation has been performed before    */
+      /* and is available                       */
+      /* don't do assignments they will be killed */
+      /* by dead code elimination if required  do */
+      /* 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;
+       }
 
+      /* 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 {
-
-           /* just add this as a previous expression except in */
-           /* case of a pointer access in which case this is a */
-           /* usage not a definition                           */
-           if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
-               deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
-               addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
-           }
-           defic = ic;
-
+         /* 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 assignment to a parameter which is not
-          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);
+      }
+
+      if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
+         deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
+         addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
+      }
+      defic = ic;
+
+      /* if assignment to a parameter which is not
+         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);
        }
 
-       /* 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);
+      /* 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);
            }
        }
 
-       /* 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)));     
-           
+      /* 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)));
+
        }
-       
-       /* 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);
+
+      /* 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);
 
        }
 
-       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);
+      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);
 
        }
 
-       /* 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));
+      /* 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));
        }
-       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);
-           }
-              
-
-       /* 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));
+      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);
+       }
+
+
+      /* 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));
        }
     }
 
-    setToNull ((void **)&ebb->outExprs);
-    ebb->outExprs = cseSet;        
-    ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
-    ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
-    return change ;
+  setToNull ((void **) &ebb->outExprs);
+  ebb->outExprs = cseSet;
+  ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
+  ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
+  return change;
 }
 
 /*-----------------------------------------------------------------*/
-/* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
+/* cseAllBlocks - will sequentially go thru & do cse for all blocks */
 /*-----------------------------------------------------------------*/
-int cseAllBlocks (eBBlock **ebbs,int count)
+int 
+cseAllBlocks (eBBlock ** ebbs, int count)
 {
-    int i;
-    int change = 0 ;
+  int i;
+  int change = 0;
 
-    /* if optimization turned off */
+  /* if optimization turned off */
 
-    for (i = 0 ; i < count ;i++ ) 
-       change += cseBBlock (ebbs[i],FALSE,ebbs,count);
+  for (i = 0; i < count; i++)
+    change += cseBBlock (ebbs[i], FALSE, ebbs, count);
 
-    return change;
+  return change;
 }