* device/lib/time.c (mktime): fixed bug 1334315
[fw/sdcc] / src / SDCCcse.c
index 1e07bb45572b067f83df969f7e56c90abfd3f9de..a2cc6ef0130079eafb106019b0a3caca65ba1ac0 100644 (file)
@@ -492,7 +492,7 @@ DEFSETFUNC (findPrevIc)
   /* if iCodes are not the same */
   /* see the operands maybe interchanged */
   if (ic->op == cdp->diCode->op &&
-      (ic->op == '+' || ic->op == '*') &&
+      IS_ASSOCIATIVE(ic) &&
       isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
       isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
     {
@@ -818,7 +818,8 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
     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))))
+          !(IS_FLOAT (operandType (IC_RESULT (ic)))
+            || IS_FIXED(operandType (IC_RESULT (ic)))))
         {
           ic->op = LEFT_OP;
           IC_RIGHT (ic) = operandFromLit (1);
@@ -829,8 +830,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
           operandLitValue (IC_LEFT (ic)) == 0.0)
         {
-          if (compareType (operandType (IC_RESULT (ic)),
-                           operandType (IC_RIGHT (ic)))<0)
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_RIGHT (ic)));
+          if (typematch<0)
             {
               ic->op = CAST;
               IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
@@ -839,6 +842,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               ic->op = '=';
               IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
             }
           SET_ISADDR (IC_RESULT (ic), 0);
           SET_ISADDR (IC_RIGHT (ic), 0);
@@ -847,8 +856,10 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
       if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
           operandLitValue (IC_RIGHT (ic)) == 0.0)
         {
-          if (compareType (operandType (IC_RESULT (ic)),
-                           operandType (IC_LEFT (ic)))<0)
+          int typematch;
+          typematch = compareType (operandType (IC_RESULT (ic)),
+                                   operandType (IC_LEFT (ic)));
+          if (typematch<0)
             {
               ic->op = CAST;
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -859,6 +870,12 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               ic->op = '=';
               IC_RIGHT (ic) = IC_LEFT (ic);
               IC_LEFT (ic) = NULL;
+              if (typematch==0)
+                {
+                  /* for completely different types, preserve the source type */
+                  IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+                  setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+                }
             }
           SET_ISADDR (IC_RIGHT (ic), 0);
           SET_ISADDR (IC_RESULT (ic), 0);
@@ -1393,7 +1410,7 @@ void
 ifxOptimize (iCode * ic, set * cseSet,
              int computeOnly,
              eBBlock * ebb, int *change,
-             eBBlock ** ebbs, int count)
+             ebbIndex * ebbi)
 {
   operand *pdop;
   symbol *label;
@@ -1445,7 +1462,7 @@ ifxOptimize (iCode * ic, set * cseSet,
       /* 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);
+      computeControlFlow (ebbi);
       if (!options.lessPedantic) {
         werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
       }
@@ -1457,7 +1474,7 @@ ifxOptimize (iCode * ic, set * cseSet,
      we can remove this conditional statement */
   label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
   if (elementsInSet (ebb->succList) == 1 &&
-      isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
+      isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
     {
 
       if (!options.lessPedantic) {
@@ -1473,7 +1490,7 @@ ifxOptimize (iCode * ic, set * cseSet,
       else
         {
           remiCodeFromeBBlock (ebb, ic);
-          computeControlFlow (ebbs, count, 1);
+          computeControlFlow (ebbi);
           return;
         }
     }
@@ -1535,7 +1552,7 @@ constFold (iCode * ic, set * cseSet)
       ic->op != '-')
     return 0;
 
-  /* this check is a hueristic to prevent live ranges
+  /* this check is a heuristic to prevent live ranges
      from becoming too long */
   if (IS_PTR (operandType (IC_RESULT (ic))))
       return 0;
@@ -1545,7 +1562,7 @@ constFold (iCode * ic, set * cseSet)
     return 0;
 
   /* check if we can find a definition for the
-     right hand side */
+     left hand side */
   if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
     return 0;
 
@@ -1735,6 +1752,9 @@ static int isSignedOp (iCode *ic)
     case RRC:
     case RLC:
     case GETHBIT:
+    case GETABIT:
+    case GETBYTE:
+    case GETWORD:
     case RIGHT_OP:
     case CAST:
     case ARRAYINIT:
@@ -1768,8 +1788,10 @@ dumpCseSet(set *cseSet)
 /*-----------------------------------------------------------------*/
 int
 cseBBlock (eBBlock * ebb, int computeOnly,
-           eBBlock ** ebbs, int count)
+           ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   set *cseSet;
   iCode *ic;
   int change = 0;
@@ -1957,7 +1979,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
         {
           ifxOptimize (ic, cseSet, computeOnly,
                        ebb, &change,
-                       ebbs, count);
+                       ebbi);
           continue;
         }
 
@@ -2057,7 +2079,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 
       /* if after all this it becomes an assignment to self
          then delete it and continue */
-      if (ASSIGNMENT_TO_SELF (ic))
+      if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
         {
           remiCodeFromeBBlock (ebb, ic);
           continue;
@@ -2225,15 +2247,17 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 /* cseAllBlocks - will sequentially go thru & do cse for all blocks */
 /*-----------------------------------------------------------------*/
 int
-cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
+cseAllBlocks (ebbIndex * ebbi, int computeOnly)
 {
+  eBBlock ** ebbs = ebbi->dfOrder;
+  int count = ebbi->count;
   int i;
   int change = 0;
 
   /* if optimization turned off */
 
   for (i = 0; i < count; i++)
-    change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
+    change += cseBBlock (ebbs[i], computeOnly, ebbi);
 
   return change;
 }