fixed bug #459459
[fw/sdcc] / src / SDCCcse.c
index 5e09ba08dab41ec7683cfcf04884bf9b43b04c83..258d5fef2b5aeb21b42decdfeb67684c8106af26 100644 (file)
@@ -253,26 +253,25 @@ DEFSETFUNC (findCheaperOp)
       /* 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)))
+      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 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
+         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)) &&
@@ -281,12 +280,12 @@ DEFSETFUNC (findCheaperOp)
                  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);
-       }
+                 SPIL_LOC (IC_RIGHT (cdp->diCode)))))
+             *opp = IC_RESULT (cdp->diCode);
+           else
+             *opp = IC_RIGHT (cdp->diCode);
+         }
+      }
       else
        *opp = IC_RESULT (cdp->diCode);
     }
@@ -301,7 +300,9 @@ DEFSETFUNC (findCheaperOp)
       IS_ITEMP (IC_RESULT (cdp->diCode)))
     *opp = IC_RESULT (cdp->diCode);
 
-  if (*opp)
+  if ((*opp) && 
+      (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp))) &&
+      (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))
     {
 
       if ((isGlobalInNearSpace (cop) &&
@@ -325,10 +326,18 @@ DEFSETFUNC (findCheaperOp)
          (*opp)->isaddr = cop->isaddr;
        }
 
+      if ((*opp)->type==VALUE && 
+         IS_SYMOP(cop) && 
+         !IS_SPEC(OP_SYMBOL(cop)->type)) {
+       // this could be a pointer to some space, so we can not
+       *opp=NULL;
+       return 0;
+      }
+
       return 1;
 
     }
-
+  *opp=NULL;
   return 0;
 }
 
@@ -820,7 +829,7 @@ algebraicOpts (iCode * ic)
          SET_ISADDR (IC_RESULT (ic), 0);
        }
       /* if casting to the same */
-      if (checkType (operandType (IC_RESULT (ic)),
+      if (compareType (operandType (IC_RESULT (ic)),
                     operandType (IC_RIGHT (ic))) == 1)
        {
          ic->op = '=';
@@ -847,51 +856,57 @@ algebraicOpts (iCode * ic)
 /* updateSpillLocation - keeps track of register spill location    */
 /*-----------------------------------------------------------------*/
 void 
-updateSpillLocation (iCode * ic)
+updateSpillLocation (iCode * ic, int induction)
 {
 
-  sym_link *setype;
-
-  if (POINTER_SET (ic))
-    return;
-
-  if (ic->nosupdate)
-    return;
+       sym_link *setype;
 
-  /* for the form true_symbol := iTempNN */
-  if (ASSIGN_ITEMP_TO_SYM (ic)
-      && !SPIL_LOC (IC_RIGHT (ic)))
-    {
+       if (POINTER_SET (ic))
+               return;
 
-      setype = getSpec (operandType (IC_RESULT (ic)));
+       if (ic->nosupdate)
+               return;
 
-      if (!IC_RIGHT (ic)->noSpilLoc &&
-         !IS_VOLATILE (setype) &&
-         !IN_FARSPACE (SPEC_OCLS (setype)) &&
-         !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+       /* for the form true_symbol := iTempNN */
+       if (ASSIGN_ITEMP_TO_SYM (ic) && 
+           !SPIL_LOC (IC_RIGHT (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)));
 
-      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))))
 
-      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;
+       }
 
-       SPIL_LOC (IC_RIGHT (ic)) =
-         SPIL_LOC (IC_RESULT (ic));
-    }
+       if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
+         
+               if (!SPIL_LOC (IC_RIGHT (ic)) &&
+                   !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
+                   OP_SYMBOL (IC_RESULT (ic))->isreqv) {
+
+                       setype = getSpec (operandType (IC_RESULT (ic)));
+             
+                       if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
+                           !IS_VOLATILE (setype) &&
+                           !IN_FARSPACE (SPEC_OCLS (setype)) &&
+                           !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+
+                               SPIL_LOC (IC_RIGHT (ic)) =
+                                       SPIL_LOC (IC_RESULT (ic));
+               }
+               /* 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    */
 /*-----------------------------------------------------------------*/
@@ -1118,7 +1133,7 @@ constFold (iCode * ic, set * cseSet)
   if (IS_ITEMP (IC_RESULT (ic)))
     {
       SPIL_LOC (IC_RESULT (ic)) = NULL;
-      IC_RESULT (ic)->noSpilLoc = 1;
+      OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
     }
 
 
@@ -1159,8 +1174,10 @@ deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
             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))
+         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));
            }
@@ -1212,7 +1229,8 @@ fixUpTypes (iCode * ic)
 {
   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;
@@ -1221,7 +1239,7 @@ fixUpTypes (iCode * ic)
   /* 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)
+      compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
     {
       setOperandType (IC_RESULT (ic), t2->next);
     }
@@ -1393,7 +1411,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
        {
 
          /* update the spill location for this */
-         updateSpillLocation (ic);
+         updateSpillLocation (ic,0);
 
          if (POINTER_SET (ic) &&
              !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
@@ -1493,7 +1511,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          !computeOnly)
        {
          applyToSet (cseSet, findPrevIc, ic, &pdic);
-         if (pdic && checkType (operandType (IC_RESULT (pdic)),
+         if (pdic && compareType (operandType (IC_RESULT (pdic)),
                                 operandType (IC_RESULT (ic))) != 1)
            pdic = NULL;
        }