* src/ds390/gen.c (pushSide): fixed 'too few arguments'
[fw/sdcc] / src / SDCCcse.c
index 35a5df940f476513025bc343d0386ae13e69f198..23f0205085bd2b543e9d8995b11b3db3811ed8a1 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "common.h"
 #include "newalloc.h"
+#include "dbuf_string.h"
 
 
 /*-----------------------------------------------------------------*/
@@ -131,6 +132,7 @@ pcseDef (void *item, va_list ap)
 {
   cseDef *cdp = item;
   iCodeTable *icTab;
+  struct dbuf_s dbuf;
 
   (void) ap;
 
@@ -138,7 +140,9 @@ pcseDef (void *item, va_list ap)
     fprintf (stdout, "**null op**");
   printOperand (cdp->sym, stdout);
   icTab = getTableEntry (cdp->diCode->op);
-  icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
+  dbuf_init (&dbuf, 1024);
+  icTab->iCodePrint (&dbuf, cdp->diCode, icTab->printName);
+  dbuf_write_and_destroy (&dbuf, stdout);
   return 1;
 }
 
@@ -175,9 +179,16 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 {
   iCode *lic;
 
+#ifdef RANGEHUNT
+  printf ("replaceAllSymBySym\n\t");
+  printOperand (from, stdout);
+  printf ("\nwith\t");
+  printOperand (to, stdout);
+  printf ("\n");
+#endif
   for (lic = ic; lic; lic = lic->next)
     {
-      int siaddr;
+      int isaddr;
 
       /* do the special cases first */
       if (lic->op == IFX)
@@ -188,9 +199,9 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 
               bitVectUnSetBit (OP_USES (from), lic->key);
               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-              siaddr = IC_COND (lic)->isaddr;
+              isaddr = IC_COND (lic)->isaddr;
               IC_COND (lic) = operandFromOperand (to);
-              IC_COND (lic)->isaddr = siaddr;
+              IC_COND (lic)->isaddr = isaddr;
 
             }
           continue;
@@ -204,9 +215,9 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
 
               bitVectUnSetBit (OP_USES (from), lic->key);
               OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-              siaddr = IC_COND (lic)->isaddr;
+              isaddr = IC_COND (lic)->isaddr;
               IC_JTCOND (lic) = operandFromOperand (to);
-              IC_JTCOND (lic)->isaddr = siaddr;
+              IC_JTCOND (lic)->isaddr = isaddr;
 
             }
           continue;
@@ -235,9 +246,9 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
               bitVectUnSetBit (OP_DEFS (from), lic->key);
               OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
             }
-          siaddr = IC_RESULT (lic)->isaddr;
+          isaddr = IC_RESULT (lic)->isaddr;
           IC_RESULT (lic) = operandFromOperand (to);
-          IC_RESULT (lic)->isaddr = siaddr;
+          IC_RESULT (lic)->isaddr = isaddr;
         }
 
       if (IS_SYMOP (to) &&
@@ -245,9 +256,9 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
         {
           bitVectUnSetBit (OP_USES (from), lic->key);
           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-          siaddr = IC_RIGHT (lic)->isaddr;
+          isaddr = IC_RIGHT (lic)->isaddr;
           IC_RIGHT (lic) = operandFromOperand (to);
-          IC_RIGHT (lic)->isaddr = siaddr;
+          IC_RIGHT (lic)->isaddr = isaddr;
         }
 
       if (IS_SYMOP (to) &&
@@ -255,9 +266,9 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
         {
           bitVectUnSetBit (OP_USES (from), lic->key);
           OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
-          siaddr = IC_LEFT (lic)->isaddr;
+          isaddr = IC_LEFT (lic)->isaddr;
           IC_LEFT (lic) = operandFromOperand (to);
-          IC_LEFT (lic)->isaddr = siaddr;
+          IC_LEFT (lic)->isaddr = isaddr;
         }
     }
 }
@@ -471,6 +482,16 @@ DEFSETFUNC (findPointerSet)
       getSize (operandType (IC_RIGHT (cdp->diCode))) ==
       getSize (operandType (rop)))
     {
+      if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
+          SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
+          SPEC_USIGN (operandType (rop)))
+        {
+          /* bug #1493710
+            Reminder for Bernhard: check of signedness
+            could be unnecessary together with 'checkSign', if
+            signedness of operation is stored in ic */
+          return 0;
+        }
       *opp = IC_RIGHT (cdp->diCode);
       return 1;
     }
@@ -936,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);
@@ -945,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.              */
@@ -966,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;
@@ -979,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.              */
@@ -1005,6 +1036,13 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
                 }
               return;
             }
+          if (rightValue == -1.0)
+            {
+              /* convert x * -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
         }
       break;
     case '/':
@@ -1097,6 +1135,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);
             }
@@ -1124,6 +1163,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);
                 }
@@ -1151,7 +1191,7 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               default:
                 return;
               }
-            if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+            if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
             {
               ic->op = '=';
               IC_RIGHT (ic) = IC_LEFT (ic);
@@ -1171,6 +1211,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);
             }
@@ -1219,12 +1260,13 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
               default:
                 return;
               }
-            if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+            if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
               {
                 if (IS_OP_VOLATILE (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);
                 }
@@ -1245,11 +1287,13 @@ 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);
             }
@@ -1871,7 +1915,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 
           /* and also iTemps derived from globals */
           deleteItemIf (&cseSet, ifFromGlobal);
-          
+
           /* Delete iTemps derived from symbols whose address */
           /* has been taken */
           deleteItemIf (&cseSet, ifFromAddrTaken);
@@ -1959,11 +2003,11 @@ cseBBlock (eBBlock * ebb, int computeOnly,
               IC_LEFT (ic)->aggr2ptr = 0;
               fixUpTypes (ic);
             }
-          else if (IC_LEFT (ic)->aggr2ptr)
+          else if (IC_LEFT (ic)->aggr2ptr == 1)
             {/* band aid for kludge */
               setOperandType (IC_LEFT (ic),
                               aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
-              IC_LEFT (ic)->aggr2ptr = 0;
+              IC_LEFT (ic)->aggr2ptr++;
               fixUpTypes (ic);
             }
         }
@@ -1976,11 +2020,11 @@ cseBBlock (eBBlock * ebb, int computeOnly,
                               aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
               IC_RESULT (ic)->aggr2ptr = 0;
             }
-          else if (IC_RESULT (ic)->aggr2ptr)
+          else if (IC_RESULT (ic)->aggr2ptr == 1)
             {/* band aid for kludge */
               setOperandType (IC_RESULT (ic),
                               aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
-              IC_RESULT (ic)->aggr2ptr = 0;
+              IC_RESULT (ic)->aggr2ptr++;
             }
         }
 
@@ -2002,7 +2046,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
           /* update the spill location for this */
           updateSpillLocation (ic,0);
 
-          if (POINTER_SET (ic) &&
+          if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
               !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
             {
               pdop = NULL;
@@ -2069,7 +2113,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
             }
         }
 
-      /*right operand */
+      /* right operand */
       if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
         {
 
@@ -2111,7 +2155,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
           IS_ITEMP (IC_RESULT (ic)) &&
           !computeOnly)
         {
-            applyToSet (cseSet, findPrevIc, ic, &pdic);
+          applyToSet (cseSet, findPrevIc, ic, &pdic);
           if (pdic && compareType (operandType (IC_RESULT (pdic)),
                                  operandType (IC_RESULT (ic))) != 1)
             pdic = NULL;
@@ -2148,6 +2192,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)) &&
           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {
@@ -2176,12 +2221,11 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* delete from the cseSet anything that has */
       /* operands matching the result of this     */
       /* except in case of pointer access         */
-      if (!(POINTER_SET (ic)) && IC_RESULT (ic))
+      if (!(POINTER_SET (ic)) && IS_SYMOP (IC_RESULT (ic)))
         {
           deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
           /* delete any previous definitions */
           ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
-
         }
 
       /* add the left & right to the defUse set */
@@ -2190,7 +2234,6 @@ cseBBlock (eBBlock * ebb, int computeOnly,
           OP_USES(IC_LEFT (ic))=
             bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
           setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
         }
 
       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
@@ -2198,12 +2241,11 @@ cseBBlock (eBBlock * ebb, int computeOnly,
           OP_USES(IC_RIGHT (ic))=
             bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
           setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
         }
 
       /* for the result it is special case, put the result */
       /* in the defuseSet if it a pointer or array access  */
-      if (POINTER_SET (defic))
+      if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
         {
           OP_USES(IC_RESULT (ic))=
             bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
@@ -2222,16 +2264,18 @@ cseBBlock (eBBlock * ebb, int computeOnly,
           addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic));
         }
       else
-        /* add the result to defintion set */ if (IC_RESULT (ic))
         {
-          OP_DEFS(IC_RESULT (ic))=
-            bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
-          ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
-          ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
-          ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
+          /* add the result to definition set */
+          if (IS_SYMOP (IC_RESULT (ic)))
+            {
+              OP_DEFS(IC_RESULT (ic))=
+                bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+              ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
+              ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
+              ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
+            }
         }
 
-
       /* if this is an addressof instruction then */
       /* put the symbol in the address of list &  */
       /* delete it from the cseSet                */