* fixed GCC 4.4.0 mingw compilation:
[fw/sdcc] / src / SDCCcse.c
index fc45babf2fe0f1a81f940bcc25148a993ba90314..1b43a42850a335c01fc35c78d708e5cddef2da30 100644 (file)
@@ -364,11 +364,11 @@ DEFSETFUNC (findCheaperOp)
               IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
             *opp = IC_RESULT (cdp->diCode);
           else {
-            /* if straight assignement && and both
+            /* if straight assignment 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
+               is an induction variable
             */
             if (!POINTER_SET (cdp->diCode) &&
                 IS_ITEMP (IC_RESULT (cdp->diCode)) &&
@@ -858,14 +858,14 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
           return;
         }
       /* if addition then check if one of them is a zero */
-      /* if yes turn it into assignmnt or cast */
+      /* if yes turn it into assignment or cast */
       if (IS_OP_LITERAL (IC_LEFT (ic)) &&
           operandLitValue (IC_LEFT (ic)) == 0.0)
         {
           int typematch;
           typematch = compareType (operandType (IC_RESULT (ic)),
                                    operandType (IC_RIGHT (ic)));
-          if (typematch<0)
+          if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
             {
               ic->op = CAST;
               IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
@@ -891,7 +891,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
           int typematch;
           typematch = compareType (operandType (IC_RESULT (ic)),
                                    operandType (IC_LEFT (ic)));
-          if (typematch<0)
+          if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
             {
               ic->op = CAST;
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -915,7 +915,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
         }
       break;
     case '-':
-      /* if subtracting the the same thing then zero     */
+      /* if subtracting the same thing then zero     */
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
         {
           ic->op = '=';
@@ -957,8 +957,9 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
     case '*':
       if (IS_OP_LITERAL (IC_LEFT (ic)))
         {
+         double leftValue = operandLitValue (IC_LEFT (ic));
 
-          if (operandLitValue (IC_LEFT (ic)) == 0.0)
+          if (leftValue == 0.0)
             {
               ic->op = '=';
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -966,7 +967,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               SET_RESULT_RIGHT (ic);
               return;
             }
-          if (operandLitValue (IC_LEFT (ic)) == 1.0)
+          if (leftValue == 1.0)
             {
               /* '*' can have two unsigned chars as operands */
               /* and an unsigned int as result.              */
@@ -987,12 +988,21 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 }
               return;
             }
+          if (leftValue == -1.0)
+            {
+              /* convert -1 * x to -x */
+              ic->op = UNARYMINUS;
+              IC_LEFT (ic) = IC_RIGHT (ic);
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
         }
 
       if (IS_OP_LITERAL (IC_RIGHT (ic)))
         {
+          double rightValue = operandLitValue (IC_RIGHT (ic));
 
-          if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+          if (rightValue == 0.0)
             {
               ic->op = '=';
               IC_LEFT (ic) = NULL;
@@ -1000,7 +1010,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               return;
             }
 
-          if (operandLitValue (IC_RIGHT (ic)) == 1.0)
+          if (rightValue == 1.0)
             {
               /* '*' can have two unsigned chars as operands */
               /* and an unsigned int as result.              */
@@ -1026,6 +1036,32 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 }
               return;
             }
+          if (rightValue == -1.0)
+            {
+              /* '*' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
+              /* convert x * -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
         }
       break;
     case '/':
@@ -1037,20 +1073,59 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
           IC_LEFT (ic) = NULL;
           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
           IC_RESULT (ic)->isaddr = 0;
-          break;
+          return;
         }
-      /* if this is a division then check if right */
-      /* is one then change it to an assignment    */
-      if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-          operandLitValue (IC_RIGHT (ic)) == 1.0)
+      /* if this is a division then check if left is zero */
+      /* and right is not then change it to an assignment */
+      if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) &&
+          (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0))
         {
-
           ic->op = '=';
           IC_RIGHT (ic) = IC_LEFT (ic);
           IC_LEFT (ic) = NULL;
           SET_RESULT_RIGHT (ic);
           return;
         }
+      /* if this is a division then check if right */
+      /* is one then change it to an assignment    */
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          double rightValue = operandLitValue (IC_RIGHT (ic));
+          if (rightValue == 1.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          if (rightValue == -1.0)
+            {
+              /* '/' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
+              /* convert x / -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
+        }
       break;
       /* if both are the same for an comparison operators */
     case EQ_OP:
@@ -1076,28 +1151,28 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
         }
       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))))
             {
-                    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);
-                    }
+              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;
+        }
+      break;
     case '!':
       if (IS_OP_LITERAL (IC_LEFT (ic)))
         {
@@ -1118,6 +1193,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
               newic->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
             }
@@ -1145,6 +1221,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 {
                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
                   IC_RESULT (newic) = IC_LEFT (ic);
+                  newic->filename = ic->filename;
                   newic->lineno = ic->lineno;
                   addiCodeToeBBlock (ebp, newic, ic->next);
                 }
@@ -1192,6 +1269,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
               newic->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
             }
@@ -1246,6 +1324,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 {
                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
                   IC_RESULT (newic) = IC_LEFT (ic);
+                  newic->filename = ic->filename;
                   newic->lineno = ic->lineno;
                   addiCodeToeBBlock (ebp, newic, ic->next);
                 }
@@ -1266,19 +1345,21 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
               newic->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
 
               newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
+              newic->filename = ic->filename;
               newic->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
             }
-            ic->op = '=';
-            IC_RIGHT (ic) = operandFromLit (0);
-            IC_LEFT (ic) = NULL;
-            SET_RESULT_RIGHT (ic);
-            return;
+          ic->op = '=';
+          IC_RIGHT (ic) = operandFromLit (0);
+          IC_LEFT (ic) = NULL;
+          SET_RESULT_RIGHT (ic);
+          return;
         }
       /* swap literal to right ic */
       if (IS_OP_LITERAL (IC_LEFT (ic)))
@@ -1462,25 +1543,20 @@ ifxOptimize (iCode * ic, set * cseSet,
   /* if the conditional is a literal then */
   if (IS_OP_LITERAL (IC_COND (ic)))
     {
-
       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic))
         {
-
           /* change to a goto */
           ic->op = GOTO;
           IC_LABEL (ic) = IC_TRUE (ic);
           (*change)++;
-
         }
       else
         {
-
           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
             {
               ic->op = GOTO;
               IC_LABEL (ic) = IC_FALSE (ic);
               (*change)++;
-
             }
           else
             {
@@ -1495,9 +1571,10 @@ ifxOptimize (iCode * ic, set * cseSet,
       /* too often, if it does happen then the user pays */
       /* the price */
       computeControlFlow (ebbi);
-      if (!options.lessPedantic) {
-        werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
-      }
+      if (!options.lessPedantic)
+        {
+          werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+        }
       return;
     }
 
@@ -1508,10 +1585,10 @@ ifxOptimize (iCode * ic, set * cseSet,
   if (elementsInSet (ebb->succList) == 1 &&
       isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
     {
-
-      if (!options.lessPedantic) {
-        werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
-      }
+      if (!options.lessPedantic)
+        {
+          werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+        }
       if (IS_OP_VOLATILE (IC_COND (ic)))
         {
           IC_RIGHT (ic) = IC_COND (ic);
@@ -1527,8 +1604,7 @@ ifxOptimize (iCode * ic, set * cseSet,
         }
     }
 
-
-  /* if it remains an IFX the update the use Set */
+  /* if it remains an IFX then update the use Set */
   if (ic->op == IFX)
     {
       OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
@@ -1865,7 +1941,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
         continue;
 
       /* if this is an assignment from true symbol
-         to a temp then do pointer post inc/dec optimzation */
+         to a temp then do pointer post inc/dec optimization */
       if (ic->op == '=' && !POINTER_SET (ic) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {
@@ -2169,7 +2245,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          mine and type is a pointer then delete
          pointerGets to take care of aliasing */
       if (ASSIGNMENT (ic) &&
-                  IS_SYMOP (IC_RESULT (ic)) &&
+          IS_SYMOP (IC_RESULT (ic)) &&
           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {