* src/SDCCmain.c (linkEdit): Added runtime path detection to the mcs51 port.
[fw/sdcc] / src / SDCCcse.c
index b02adc0e708917510a9424c6d523ec99fc410ac5..18ca4ea6e50376b63322d57ae775607cb9ae08cf 100644 (file)
@@ -34,7 +34,7 @@ newCseDef (operand * sym, iCode * ic)
   cseDef *cdp;
 
   assert (sym);
-  cdp = Safe_calloc (1, sizeof (cseDef));
+  cdp = Safe_alloc (sizeof (cseDef));
 
   cdp->sym = sym;
   cdp->diCode = ic;
@@ -300,7 +300,10 @@ DEFSETFUNC (findCheaperOp)
       IS_ITEMP (IC_RESULT (cdp->diCode)))
     *opp = IC_RESULT (cdp->diCode);
 
-  if ((*opp)&&(SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp))))
+  if ((*opp) && 
+      (isOperandLiteral(*opp) ||
+       (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
+       (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))))
     {
 
       if ((isGlobalInNearSpace (cop) &&
@@ -391,6 +394,20 @@ DEFSETFUNC (findPrevIc)
   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                           */
 /*-----------------------------------------------------------------*/
@@ -808,25 +825,28 @@ algebraicOpts (iCode * 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;
+           {
+                   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)))
        {
@@ -846,51 +866,57 @@ algebraicOpts (iCode * ic)
 /* updateSpillLocation - keeps track of register spill location    */
 /*-----------------------------------------------------------------*/
 void 
-updateSpillLocation (iCode * ic)
+updateSpillLocation (iCode * ic, int induction)
 {
 
-  sym_link *setype;
+       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 (POINTER_SET (ic))
+               return;
 
-      if (!IC_RIGHT (ic)->noSpilLoc &&
-         !IS_VOLATILE (setype) &&
-         !IN_FARSPACE (SPEC_OCLS (setype)) &&
-         !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+       if (ic->nosupdate)
+               return;
 
-       SPIL_LOC (IC_RIGHT (ic)) =
-         IC_RESULT (ic)->operand.symOperand;
-    }
+       /* for the form true_symbol := iTempNN */
+       if (ASSIGN_ITEMP_TO_SYM (ic) && 
+           !SPIL_LOC (IC_RIGHT (ic))) {
 
-  if (ASSIGN_ITEMP_TO_ITEMP (ic) &&
-      !SPIL_LOC (IC_RIGHT (ic)) &&
-  !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) &&
-      OP_SYMBOL (IC_RESULT (ic))->isreqv)
-    {
+               setype = getSpec (operandType (IC_RESULT (ic)));
 
-      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    */
 /*-----------------------------------------------------------------*/
@@ -1005,7 +1031,9 @@ ifxOptimize (iCode * ic, set * cseSet,
       /* too often, if it does happen then the user pays */
       /* the price */
       computeControlFlow (ebbs, count, 1);
-      werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+      if (!options.lessPedantic) {
+       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+      }
       return;
     }
 
@@ -1019,7 +1047,9 @@ ifxOptimize (iCode * ic, set * cseSet,
 
       remiCodeFromeBBlock (ebb, ic);
       computeControlFlow (ebbs, count, 1);
-      werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+      if (!options.lessPedantic) {
+       werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+      }
       return;
     }
 
@@ -1117,7 +1147,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,9 +1189,9 @@ deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
             iTemp1 = iTemp0 + 8;
             iTemp2 = iTemp1 + 8; */
          if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode), 
-                          (void*)isOperandEqual) ||
+                          (insetwithFunc)isOperandEqual) ||
              isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode), 
-                          (void*)isOperandEqual))
+                          (insetwithFunc)isOperandEqual))
            {
              addSet (&compItems, IC_RESULT (cdp->diCode));
            }
@@ -1213,7 +1243,8 @@ fixUpTypes (iCode * ic)
 {
   sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
 
-  if (TARGET_IS_DS390)
+  /* if (TARGET_IS_DS390) */
+  if (options.model == MODEL_FLAT24)
     {
       /* hack-o-matic! */
       return;
@@ -1222,7 +1253,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);
     }
@@ -1300,6 +1331,10 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          /* 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 */
@@ -1394,7 +1429,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)))
@@ -1457,7 +1492,6 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
          if (pdop)
            {
-
              IC_RIGHT (ic) = pdop;
              change = 1;
            }
@@ -1494,20 +1528,20 @@ 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;
        }
 
+#if 0
       /* 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
@@ -1556,7 +1590,23 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          defic = ic;
 
        }
+#else
+      /* Alternate code */
+      if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+         /* if previous definition found change this to an assignment */
+         ic->op = '=';
+         IC_LEFT(ic) = NULL;
+         IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
+         SET_ISADDR(IC_RESULT(ic),0);
+         SET_ISADDR(IC_RIGHT (ic),0);    
+      }
 
+      if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
+         deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
+         addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
+      }
+      defic = ic;
+#endif
       /* if assignment to a parameter which is not
          mine and type is a pointer then delete
          pointerGets to take care of aliasing */