* Makefile.in, configure.in, configure,
[fw/sdcc] / src / SDCCcse.c
index f6e6ec03a313cecf33a649478bf3f43e0fca8b15..1b43a42850a335c01fc35c78d708e5cddef2da30 100644 (file)
@@ -364,11 +364,11 @@ DEFSETFUNC (findCheaperOp)
               IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
             *opp = IC_RESULT (cdp->diCode);
           else {
               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
                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)) &&
             */
             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 */
           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 (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)));
             {
               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)));
           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);
             {
               ic->op = CAST;
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -915,7 +915,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
         }
       break;
     case '-':
         }
       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 = '=';
       if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
         {
           ic->op = '=';
@@ -1038,6 +1038,25 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             }
           if (rightValue == -1.0)
             {
             }
           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;
               /* convert x * -1 to -x */
               ic->op = UNARYMINUS;
               IC_RIGHT (ic) = NULL;
@@ -1054,20 +1073,59 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
           IC_LEFT (ic) = NULL;
           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
           IC_RESULT (ic)->isaddr = 0;
           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;
         }
           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:
       break;
       /* if both are the same for an comparison operators */
     case EQ_OP:
@@ -1093,28 +1151,28 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
         }
       break;
     case CAST:
         }
       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);
             }
             }
-            break;
+          /* 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)))
         {
     case '!':
       if (IS_OP_LITERAL (IC_LEFT (ic)))
         {
@@ -1135,6 +1193,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
             {
               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->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
             }
@@ -1162,6 +1221,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 {
                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
                   IC_RESULT (newic) = IC_LEFT (ic);
                 {
                   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->lineno = ic->lineno;
                   addiCodeToeBBlock (ebp, newic, ic->next);
                 }
@@ -1209,6 +1269,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
             {
               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->lineno = ic->lineno;
               addiCodeToeBBlock (ebp, newic, ic->next);
             }
@@ -1263,6 +1324,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 {
                   iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
                   IC_RESULT (newic) = IC_LEFT (ic);
                 {
                   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->lineno = ic->lineno;
                   addiCodeToeBBlock (ebp, newic, ic->next);
                 }
@@ -1283,19 +1345,21 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             {
               iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
               IC_RESULT (newic) = IC_LEFT (ic);
             {
               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->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);
             }
               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)))
         }
       /* swap literal to right ic */
       if (IS_OP_LITERAL (IC_LEFT (ic)))
@@ -1479,25 +1543,20 @@ ifxOptimize (iCode * ic, set * cseSet,
   /* if the conditional is a literal then */
   if (IS_OP_LITERAL (IC_COND (ic)))
     {
   /* if the conditional is a literal then */
   if (IS_OP_LITERAL (IC_COND (ic)))
     {
-
       if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (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)++;
           /* change to a goto */
           ic->op = GOTO;
           IC_LABEL (ic) = IC_TRUE (ic);
           (*change)++;
-
         }
       else
         {
         }
       else
         {
-
           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
             {
               ic->op = GOTO;
               IC_LABEL (ic) = IC_FALSE (ic);
               (*change)++;
           if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic))
             {
               ic->op = GOTO;
               IC_LABEL (ic) = IC_FALSE (ic);
               (*change)++;
-
             }
           else
             {
             }
           else
             {
@@ -1512,9 +1571,10 @@ ifxOptimize (iCode * ic, set * cseSet,
       /* too often, if it does happen then the user pays */
       /* the price */
       computeControlFlow (ebbi);
       /* 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;
     }
 
       return;
     }
 
@@ -1525,10 +1585,10 @@ ifxOptimize (iCode * ic, set * cseSet,
   if (elementsInSet (ebb->succList) == 1 &&
       isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
     {
   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);
       if (IS_OP_VOLATILE (IC_COND (ic)))
         {
           IC_RIGHT (ic) = IC_COND (ic);
@@ -1544,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);
   if (ic->op == IFX)
     {
       OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
@@ -1882,7 +1941,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
         continue;
 
       /* if this is an assignment from true symbol
         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))))
         {
       if (ic->op == '=' && !POINTER_SET (ic) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {
@@ -2186,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) &&
          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))))
         {
           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {