yes
[fw/sdcc] / src / SDCCcse.c
index e0fd0d9b01c0f3817b64731a85853f19cddf12e4..8942590efaa793ca29e633f76590d7e36fadaa51 100644 (file)
 /*-----------------------------------------------------------------*/
 /* newCseDef - new cseDef                                          */
 /*-----------------------------------------------------------------*/
-cseDef *newCseDef (operand *sym, iCode *ic)
+cseDef *
+newCseDef (operand * sym, iCode * ic)
 {
-    cseDef *cdp ;
+  cseDef *cdp;
 
-    assert (sym);
-    cdp = Safe_calloc(1,sizeof(cseDef));
+  assert (sym);
+  cdp = Safe_alloc (sizeof (cseDef));
 
-    cdp->sym = sym;
-    cdp->diCode = ic;
-    cdp->key = sym->key;
+  cdp->sym = sym;
+  cdp->diCode = ic;
+  cdp->key = sym->key;
 
-    return cdp;
+  return cdp;
 }
 
 
@@ -47,414 +48,505 @@ 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;
+  if (src == dest)
+    return 1;
 
-    return (src->key == dest->key &&
-      src->diCode == dest->diCode ) ;
+  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 ;
+  cseDef *cdp = item;
+  iCodeTable *icTab;
 
-    (void)ap;
+  (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;
+  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, bitVect **ndpset)
+void 
+replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 {
-    iCode *lic;
-
-    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 ;
-
-    }
-    continue ;
-  }
-
-  if (lic->op == JUMPTABLE) {
-    if (IS_SYMOP(to) &&
-        IC_JTCOND(lic)->key == from->key) {
-
-      bitVectUnSetBit (OP_USES(from),lic->key);
-      OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
-      siaddr = IC_COND(lic)->isaddr ;
-      IC_JTCOND(lic) = operandFromOperand(to);
-      IC_JTCOND(lic)->isaddr = siaddr ;
-
-    }
-    continue ;
-  }
-
-  if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
-      /* maintain du chains */
-      if (POINTER_SET(lic)) {
-    bitVectUnSetBit (OP_USES(from),lic->key);
-    OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
-
-    /* also check if the "from" was in the non-dominating
-       pointer sets and replace it with "to" in the bitVector */
-    if (bitVectBitValue(*ndpset,from->key)) {
-        bitVectUnSetBit(*ndpset,from->key);
-        bitVectSetBit(*ndpset,to->key);
-    }
-
-      }
-      else {
-    bitVectUnSetBit (OP_DEFS(from),lic->key);
-    OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
-      }
-      siaddr = IC_RESULT(lic)->isaddr ;
-      IC_RESULT(lic) = operandFromOperand(to);
-      IC_RESULT(lic)->isaddr = siaddr ;
-  }
-
-  if (IS_SYMOP(to) &&
-      IC_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_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 ;
-  }
+  iCode *lic;
+
+  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;
+
+           }
+         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);
+               }
+
+           }
+         else
+           {
+             bitVectUnSetBit (OP_DEFS (from), lic->key);
+             OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
+           }
+         siaddr = IC_RESULT (lic)->isaddr;
+         IC_RESULT (lic) = operandFromOperand (to);
+         IC_RESULT (lic)->isaddr = siaddr;
+       }
+
+      if (IS_SYMOP (to) &&
+         IC_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_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;
+       }
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* 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->ndompset);
+  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)
 {
-    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;
+  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
+             *opp = IC_RIGHT (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_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 (cop->key == (*opp)->key )  {
-      *opp = NULL ;
-      return 0;
-  }
-
-  if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
-      *opp = operandFromOperand(*opp);
-      (*opp)->isaddr = cop->isaddr;
-  }
-
-  return 1;
+  /* 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 ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop))
+       {
+         *opp = operandFromOperand (*opp);
+         (*opp)->isaddr = cop->isaddr;
+       }
+         
+      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;
+           }
+           
+        }
+         
+      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);
+  cseDef *cdp = item;
+  V_ARG (iCode *, ic);
+  V_ARG (iCode **, icp);
 
-    /* if already found */
-    if (*icp)
-  return 1;
+  /* 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;
+  /* if the iCodes are the same */
+  if (isiCodeEqual (ic, cdp->diCode) &&
+      isOperandEqual (cdp->sym, IC_RESULT (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))) {
-  *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;
     }
 
-    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;
+  cseDef *cdp = item;
 
-    return (isOperandGlobal(cdp->sym));
+  return (isOperandGlobal (cdp->sym));
 }
 
 /*-----------------------------------------------------------------*/
 /* ifAnyGetPointer - if get pointer icode                          */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(ifAnyGetPointer)
+DEFSETFUNC (ifAnyGetPointer)
 {
-    cseDef *cdp = item;
+  cseDef *cdp = item;
 
-    if (cdp->diCode && POINTER_GET(cdp->diCode)) return 1;
-    return 0;
+  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_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;
+  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;
+  /* 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_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_RESULT (cdp->diCode) &&
+      IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
+    return 1;
 
-    return 0;
+  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 ;
+  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;
-    }
+  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)
+DEFSETFUNC (ifDefSymIsX)
 {
-    cseDef *cdp  = item;
-    V_ARG(operand *,op);
+  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));
 
 }
 
@@ -462,590 +554,678 @@ DEFSETFUNC(ifDefSymIsX)
 /*-----------------------------------------------------------------*/
 /* ifDiCodeIs - returns truw if diCode is same                     */
 /*-----------------------------------------------------------------*/
- int ifDiCodeIs (set *cseSet, iCode *ic)
+int 
+ifDiCodeIs (set * cseSet, iCode * ic)
 {
-    cseDef *loop;
-    set *sl;
+  cseDef *loop;
+  set *sl;
 
-    if (!ic)
-  return 0;
+  if (!ic)
+    return 0;
 
-    for (sl = cseSet ; sl ; sl = sl->next ) {
-  loop = sl->item ;
-  if (loop->diCode == ic)
-      return 1;
+  for (sl = cseSet; sl; sl = sl->next)
+    {
+      loop = sl->item;
+      if (loop->diCode == ic)
+       return 1;
     }
-    return 0;
+  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)
+DEFSETFUNC (ifDiCodeIsX)
 {
-    cseDef *cdp  = item;
-    V_ARG(iCode *,ic);
+  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 ) {
+  /* 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))) {
+      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;
-  }
+         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)) &&
+      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;
-  }
+         !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;
-  }
-  /* 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 ;
-  }
-  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 ;
-  }
-  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 (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 ;
-      }
-  }
-  break ;
+  /* 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 (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;
+       }
+      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 (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;
+           }
+       }
+      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 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;
-    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);
-  }
+      /* 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;
+       }
+      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 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;
-
-    if (POINTER_SET(ic))
-  return;
-
-    if (ic->nosupdate)
-  return;
-
-    /* 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;
-    }
-
-    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))) )
-
-      SPIL_LOC(IC_RIGHT(ic)) =
-    SPIL_LOC(IC_RESULT(ic));
-    }
+       sym_link *setype;
+
+       if (POINTER_SET (ic))
+               return;
+
+       if (ic->nosupdate)
+               return;
+
+       /* for the form true_symbol := iTempNN */
+       if (ASSIGN_ITEMP_TO_SYM (ic) && 
+           !SPIL_LOC (IC_RIGHT (ic))) {
+
+               setype = getSpec (operandType (IC_RESULT (ic)));
+
+               if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
+                   !IS_VOLATILE (setype) &&
+                   !IN_FARSPACE (SPEC_OCLS (setype)) &&
+                   !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+               {
+                   wassert(IS_SYMOP(IC_RESULT (ic)));
+                   wassert(IS_SYMOP(IC_RIGHT (ic)));
+                       SPIL_LOC (IC_RIGHT (ic)) =
+                               IC_RESULT (ic)->operand.symOperand;
+               }
+           
+       }
+
+#if 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);
+  /* 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));
+  /* 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;
+  /* these are the definitions that this operand can use */
+  op->usesDefs = adefs;
 
-    /* the out defs is an union */
-    *oud = bitVectUnion(*oud,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);
-  }
-  /* 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);
+  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);
     }
-    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)++;
-  }
-    }
-
-    /* if the conditional is a literal then */
-    if (IS_OP_LITERAL(IC_COND(ic))) {
+  operand *pdop;
+  symbol *label;
 
-  if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
+  /* 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)++;
+       }
+    }
 
-      /* change to a goto */
-      ic->op = GOTO ;
-      IC_LABEL(ic) = IC_TRUE(ic);
-      (*change)++;
+  /* if the conditional is a literal then */
+  if (IS_OP_LITERAL (IC_COND (ic)))
+    {
 
-  } else {
+      if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
+       {
 
-      if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
-    ic->op = GOTO ;
-    IC_LABEL(ic) = IC_FALSE(ic);
-    (*change)++;
+         /* change to a goto */
+         ic->op = GOTO;
+         IC_LABEL (ic) = IC_TRUE (ic);
+         (*change)++;
 
-      } else {
-    /* then kill this if condition */
-    remiCodeFromeBBlock (ebb,ic);
+       }
+      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);
       }
-  }
-
-  /* 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 ;
+      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;
-    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;
+  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;
+  /* 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 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 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;
+  /* 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;
+  /* 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;
+  /* 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;
+  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;
-  IC_RESULT(ic)->noSpilLoc = 1;
+  /* 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;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1053,501 +1233,581 @@ 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));
-      }
-      /* 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));
-      }
-  }
+  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, (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);
+  eBBlock *ebp = item;
+  V_ARG (operand *, op);
+  V_ARG (int, dfnum);
 
-    if (ebp->visited)
-  return 0;
+  if (ebp->visited)
+    return 0;
 
-    ebp->visited = 1;
-    if (ebp->dfnum > dfnum) {
-  deleteItemIf(&ebp->inExprs,ifPointerGet,op);
+  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)
+static void 
+fixUpTypes (iCode * ic)
 {
-  sym_link *t1 = operandType(IC_LEFT(ic)) ,*t2;
+  sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
 
-  if (IS_DS390_PORT)
-  {
+  /* 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) &&
-      checkType(t2=operandType(IC_RESULT(ic)),t1) == 1) {
-    setOperandType(IC_RESULT(ic),t2->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   */
 /*             this is the hackiest kludgiest routine in the whole */
 /*             system. also the most important, since almost all   */
 /*             data flow related information is computed by it     */
 /*-----------------------------------------------------------------*/
-int 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 ;
-
-  /* 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);
-  }
-
-  /* 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);
-      /* 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);
-    if (pdop)
-        IC_LEFT(ic) = pdop ;
-      }
-      /* the lookup could have changed it*/
-      if (IS_SYMOP(IC_LEFT(ic))) {
-    OP_USES(IC_LEFT(ic)) =
-        bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
-    setUsesDefs(IC_LEFT(ic),ebb->defSet,
-          ebb->outDefs,&ebb->usesDefs);
-      }
-
-
-      /* if we a sending a pointer as a parameter
-         then kill all cse since the pointed to item
-         might be changed in the function being called */
-      if ((ic->op == IPUSH || ic->op == SEND) &&
-    IS_PTR(operandType(IC_LEFT(ic)))) {
-    deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb);
-    ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key);
-    for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
-    applyToSet(ebb->succList,delGetPointerSucc,
-         IC_LEFT(ic),ebb->dfnum);
-      }
-      continue;
-  }
-
-  /* if jumptable then mark the usage */
-  if (ic->op == JUMPTABLE ) {
-      OP_USES(IC_JTCOND(ic)) =
-    bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
-      setUsesDefs(IC_JTCOND(ic),ebb->defSet,
-      ebb->outDefs,&ebb->usesDefs);
-      continue;
-  }
-
-  if (SKIP_IC(ic))
-      continue ;
-
-  /* do some algebraic optimizations if possible */
-  algebraicOpts (ic);
-  while (constFold(ic,cseSet));
-
-  /* small klugde */
-  if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
-      setOperandType(IC_LEFT(ic),
-         aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
-      fixUpTypes(ic);
-
-  }
-  if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
-      setOperandType(IC_RESULT(ic),
-         aggrToPtr(operandType(IC_RESULT(ic)),FALSE));
-  }
-
-  /* if this is a condition statment then */
-  /* 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) &&
-    !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype))) {
-    pdop = NULL ;
-    applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
-    if (pdop && IS_ITEMP(pdop) && !computeOnly)
-        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;
-        }
-        /* 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);
-        }
-
-    }
-    else {
-        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) {
+  set *cseSet;
+  iCode *ic;
+  int change = 0;
+  int i;
+  set *ptrSetSet = NULL;
+
+  /* if this block is not reachable */
+  if (ebb->noPath)
+    return 0;
 
-    IC_RIGHT(ic) = pdop;
-    change = 1;
+  /* 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);
+       }
+
+      /* 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);
+           }
+
+
+         /* if we a sending a pointer as a parameter
+            then kill all cse since the pointed to item
+            might be changed in the function being called */
+         if ((ic->op == IPUSH || ic->op == SEND) &&
+             IS_PTR (operandType (IC_LEFT (ic))))
+           {
+             deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb);
+             ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key);
+             for (i = 0; i < count; ebbs[i++]->visited = 0);
+             applyToSet (ebb->succList, delGetPointerSucc,
+                         IC_LEFT (ic), ebb->dfnum);
+           }
+         continue;
+       }
+
+      /* if jumptable then mark the usage */
+      if (ic->op == JUMPTABLE)
+       {
+         OP_USES(IC_JTCOND (ic))=
+           bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
+         setUsesDefs (IC_JTCOND (ic), ebb->defSet,
+                      ebb->outDefs, &ebb->usesDefs);
+         continue;
+       }
+
+      if (SKIP_IC (ic))
+       continue;
+
+      if (!computeOnly) {
+       /* do some algebraic optimizations if possible */
+       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)           ||
-         bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))) &&
-      ! ASSIGNMENT(ic)                        &&
-        IS_ITEMP(IC_RESULT(ic))               &&
-      ! computeOnly) {
-      applyToSet (cseSet,findPrevIc,ic,&pdic);
-      if (pdic && checkType(operandType(IC_RESULT(pdic)),
-          operandType(IC_RESULT(ic))) != 1)
-        pdic = NULL;
-  }
-
-  /* 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),&ebb->ndompset);
-    /* 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),&owner->ndompset);
-    }
-    pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
+      /* small klugde */
+      if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic))))
+       {
+         setOperandType (IC_LEFT (ic),
+                         aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
+         fixUpTypes (ic);
+
+       }
+      if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic))))
+       {
+         setOperandType (IC_RESULT (ic),
+                         aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+       }
+
+      /* if this is a condition statement 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 (!computeOnly && 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);
+           }
+       }
+
+      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;
+                     ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+                     SET_ISADDR (IC_RESULT (ic), 0);
+                   }
+
+               }
+             else
+               {
+                 ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
+                 change = 1;
+               }
+           }
+       }
+
+      /*right operand */
+      if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
+       {
+
+         pdop = NULL;
+         applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
+         if (pdop) {
+           ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+           change = 1;
+         }
+       }
+       
+      /* if left or right changed then do algebraic */
+      if (!computeOnly && change)
+       {
+         algebraicOpts (ic);
+         while (constFold (ic, cseSet));
+       }
+
+      /* if after all this it becomes an 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) ||
+            bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) &&
+         !ASSIGNMENT (ic) &&
+         IS_ITEMP (IC_RESULT (ic)) &&
+         !computeOnly)
+       {
+           applyToSet (cseSet, findPrevIc, ic, &pdic);
+         if (pdic && compareType (operandType (IC_RESULT (pdic)),
+                                operandType (IC_RESULT (ic))) != 1)
+           pdic = NULL;
+         if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0) 
+             pdic = NULL;
+       }
+
+      /* Alternate code */
+      if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+       if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
+         /* Mmm, found an equivalent pointer get at a lower level. 
+            This could be a loop however with the same pointer set 
+            later on */
+       } else {
+         /* if previous definition found change this to an assignment */
+         ic->op = '=';
+         IC_LEFT(ic) = NULL;
+         IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
+         SET_ISADDR(IC_RESULT(ic),0);
+         SET_ISADDR(IC_RIGHT (ic),0);    
+       }
       }
-      else
-    addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));
-
-      if (!computeOnly)
-    /* eliminate this */
-    remiCodeFromeBBlock (ebb,ic);
 
-      defic = pdic ;
-      change++ ;
-
-      if (IS_ITEMP(IC_RESULT(ic)))
-    continue ;
-
-  } 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));
+      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,&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)));
-
-  }
-
-  /* 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);
-
-  }
-
-  /* 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));
-  }
+      /* 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, &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)));
+
+       }
+
+      /* 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);
+
+       }
+
+      /* 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));
+       }
     }
 
-    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 computeOnly)
 {
-    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], computeOnly, ebbs, count);
 
-    return change;
+  return change;
 }
-