Fixed a potential bug in genGenPointerSet
[fw/sdcc] / src / mcs51 / ralloc.c
index 6b9c977a9b09c35e22fa2eddc33487e883e89772..5b46166f29e9b7e6c4dff7feb216c7705e281e66 100644 (file)
@@ -1182,10 +1182,15 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    else
                        sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
 
-                   /* if the allocation falied which means
+                   /* if the allocation failed which means
                       this was spilt then break */
-                   if (!sym->regs[j])
-                       break;
+                   if (!sym->regs[j]) {
+                     if (j) {
+                       fprintf (stderr, "%d reg(s) lost in %s:%d\n",
+                                j, __FILE__,__LINE__);
+                     }
+                     break;
+                   }
                }
 
                /* if it shares registers with operands make sure
@@ -1215,8 +1220,8 @@ serialRegAssign (eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* rUmaskForOp :- returns register mask for an operand             */
 /*-----------------------------------------------------------------*/
-static bitVect *
-rUmaskForOp (operand * op)
+bitVect *
+mcs51_rUmaskForOp (operand * op)
 {
   bitVect *rumask;
   symbol *sym;
@@ -1256,7 +1261,7 @@ regsUsedIniCode (iCode * ic)
   if (ic->op == IFX)
     {
       rmask = bitVectUnion (rmask,
-                           rUmaskForOp (IC_COND (ic)));
+                           mcs51_rUmaskForOp (IC_COND (ic)));
       goto ret;
     }
 
@@ -1264,7 +1269,7 @@ regsUsedIniCode (iCode * ic)
   if (ic->op == JUMPTABLE)
     {
       rmask = bitVectUnion (rmask,
-                           rUmaskForOp (IC_JTCOND (ic)));
+                           mcs51_rUmaskForOp (IC_JTCOND (ic)));
 
       goto ret;
     }
@@ -1272,16 +1277,16 @@ regsUsedIniCode (iCode * ic)
   /* of all other cases */
   if (IC_LEFT (ic))
     rmask = bitVectUnion (rmask,
-                         rUmaskForOp (IC_LEFT (ic)));
+                         mcs51_rUmaskForOp (IC_LEFT (ic)));
 
 
   if (IC_RIGHT (ic))
     rmask = bitVectUnion (rmask,
-                         rUmaskForOp (IC_RIGHT (ic)));
+                         mcs51_rUmaskForOp (IC_RIGHT (ic)));
 
   if (IC_RESULT (ic))
     rmask = bitVectUnion (rmask,
-                         rUmaskForOp (IC_RESULT (ic)));
+                         mcs51_rUmaskForOp (IC_RESULT (ic)));
 
 ret:
   return rmask;
@@ -1378,6 +1383,11 @@ rematStr (symbol * sym)
          continue;
        }
 
+      /* cast then continue */
+      if (IS_CAST_ICODE(ic)) {
+         ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+         continue;
+      }
       /* we reached the end */
       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
       break;
@@ -1432,12 +1442,14 @@ regTypeNum ()
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
              POINTER_GET (ic) &&
+             !sym->noSpilLoc &&
              !IS_BITVAR (sym->etype))
            {
 
 
              /* if remat in data space */
              if (OP_SYMBOL (IC_LEFT (ic))->remat &&
+                 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
                  DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
                {
 
@@ -1732,9 +1744,9 @@ findAssignToSym (operand * op, iCode * ic)
          /* or in stack space in case of + & - */
 
          /* if assigned to a non-symbol then return
-            true */
+            FALSE */
          if (!IS_SYMOP (IC_RIGHT (dic)))
-           break;
+           return NULL;
 
          /* if the symbol is in far space then
             we should not */
@@ -1793,6 +1805,8 @@ static int
 packRegsForSupport (iCode * ic, eBBlock * ebp)
 {
   int change = 0;
+  iCode *dic, *sic;
+
   /* for the left & right operand :- look to see if the
      left was assigned a true symbol in far space in that
      case replace them */
@@ -1800,8 +1814,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
   if (IS_ITEMP (IC_LEFT (ic)) &&
       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
     {
-      iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
-      iCode *sic;
+      dic = findAssignToSym (IC_LEFT (ic), ic);
 
       if (!dic)
        goto right;
@@ -1811,9 +1824,8 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
       for (sic = dic; sic != ic; sic = sic->next)
        bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
 
-      IC_LEFT (ic)->operand.symOperand =
-       IC_RIGHT (dic)->operand.symOperand;
-      IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+      OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
+      IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
       remiCodeFromeBBlock (ebp, dic);
       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
       change++;
@@ -1874,13 +1886,15 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) &&
-      ic->op != RETURN &&
+  if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
+    return NULL;
+
+  if (ic->op != RETURN &&
       ic->op != SEND &&
       !POINTER_SET (ic) &&
       !POINTER_GET (ic))
     return NULL;
-
+  
   /* this routine will mark the a symbol as used in one 
      instruction use only && if the defintion is local 
      (ie. within the basic block) && has only one definition &&
@@ -2139,6 +2153,10 @@ packRegsForAccUse (iCode * ic)
       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
     return;
 
+#if 0
+  // this is too dangerous and need further restrictions
+  // see bug #447547
+
   /* if one of them is a literal then we can */
   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
@@ -2146,6 +2164,7 @@ packRegsForAccUse (iCode * ic)
       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
       return;
     }
+#endif
 
   /* if the other one is not on stack then we can */
   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
@@ -2274,6 +2293,7 @@ packRegisters (eBBlock * ebp)
          !POINTER_SET (ic) &&
          IS_SYMOP (IC_RIGHT (ic)) &&
          OP_SYMBOL (IC_RIGHT (ic))->remat &&
+         !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
          bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
        {
 
@@ -2283,14 +2303,29 @@ packRegisters (eBBlock * ebp)
            OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
        }
 
+      /* if cast to a generic pointer & the pointer being
+        cast is remat, then we can remat this cast as well */
+      if (ic->op == CAST && 
+         IS_SYMOP(IC_RIGHT(ic)) &&
+         OP_SYMBOL(IC_RIGHT(ic))->remat ) {
+             sym_link *to_type = operandType(IC_LEFT(ic));
+             sym_link *from_type = operandType(IC_RIGHT(ic));
+             if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
+                     OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+                     OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+                     OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+             }
+      }
+
       /* if this is a +/- operation with a rematerizable 
          then mark this as rematerializable as well */
       if ((ic->op == '+' || ic->op == '-') &&
          (IS_SYMOP (IC_LEFT (ic)) &&
           IS_ITEMP (IC_RESULT (ic)) &&
+          IS_OP_LITERAL (IC_RIGHT (ic))) &&
           OP_SYMBOL (IC_LEFT (ic))->remat &&
-          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-          IS_OP_LITERAL (IC_RIGHT (ic))))
+         (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
+          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
        {
          OP_SYMBOL (IC_RESULT (ic))->remat = 1;
          OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
@@ -2452,6 +2487,7 @@ packRegisters (eBBlock * ebp)
          we can leave the result of this operation in acc:b
          combination */
       if ((IS_ARITHMETIC_OP (ic)
+          || IS_CONDITIONAL(ic)
           || IS_BITWISE_OP (ic)
           || ic->op == LEFT_OP || ic->op == RIGHT_OP
           || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))