* src/SDCCBlock.c (addiCodeToeBBlock): fixed bug 1652207: GOTO icodes appended by...
[fw/sdcc] / src / SDCCcse.c
index ad94b3a58a55a5e38d4245dd87f8c9b7f8246c97..7d86488d608017f3c36d5c4c96243ea6a5d63f23 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,17 +140,21 @@ 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;
 }
 
 void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
 #ifdef RANGEHUNT
-  printf ("ReplaceOpWithCheaperOp %s with %s: ",
-          IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
-          IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
+  printf ("ReplaceOpWithCheaperOp\n\t");
+  printOperand (*op, stdout);
+  printf ("\nwith\t");
+  printOperand (cop, stdout);
+
   // if op is a register equivalent
-  if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+  if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
     operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
     if (isOperandEqual(*rop, *op)) {
       printf ("true");
@@ -173,6 +179,13 @@ 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;
@@ -415,6 +428,15 @@ DEFSETFUNC (findCheaperOp)
           (*opp)->isaddr = cop->isaddr;
         }
 
+      /* copy signedness to literal operands */
+      if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
+          && isOperandLiteral(*opp)
+          && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
+          && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
+      {
+          SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
+      }
+
       if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
           SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
         {
@@ -460,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;
     }
@@ -492,7 +524,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 +850,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 +862,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 +874,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 +888,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 +902,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);
@@ -1535,7 +1584,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 +1594,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 +1784,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: