added sdcpp, sdcppa, yacc, conf projects
[fw/sdcc] / src / mcs51 / ralloc.c
index 1578ae1dafbad175a9f4141712c5465058682568..ddfef2de582b8f84101234d245bf5c671056f573 100644 (file)
@@ -191,32 +191,6 @@ useReg (regs * reg)
   reg->isFree = 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range          */
-/*-----------------------------------------------------------------*/
-static bool
-allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
-{
-  int i;
-
-  if (!defs)
-    return TRUE;
-
-  for (i = 0; i < defs->size; i++)
-    {
-      iCode *ic;
-
-      if (bitVectBitValue (defs, i) &&
-         (ic = hTabItemWithKey (iCodehTab, i)) &&
-         (ic->seq >= fseq && ic->seq <= toseq))
-
-       return FALSE;
-
-    }
-
-  return TRUE;
-}
-
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
 /*-----------------------------------------------------------------*/
@@ -293,17 +267,6 @@ rematable (symbol * sym, eBBlock * ebp, iCode * ic)
   return sym->remat;
 }
 
-/*-----------------------------------------------------------------*/
-/* notUsedInBlock - not used in this block                         */
-/*-----------------------------------------------------------------*/
-static int
-notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
-{
-  return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
-         allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
-/*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
-}
-
 /*-----------------------------------------------------------------*/
 /* notUsedInRemaining - not used or defined in remain of the block */
 /*-----------------------------------------------------------------*/
@@ -526,6 +489,7 @@ createStackSpil (symbol * sym)
   SPEC_EXTR (sloc->etype) = 0;
   SPEC_STAT (sloc->etype) = 0;
   SPEC_VOLATILE(sloc->etype) = 0;
+  SPEC_ABSA(sloc->etype) = 0;
 
   /* we don't allow it to be allocated`
      onto the external stack since : so we
@@ -880,6 +844,9 @@ static regs *getRegPtrNoSpil()
     return reg;
 
   assert(0);
+
+  /* just to make the compiler happy */
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -897,6 +864,9 @@ static regs *getRegGprNoSpil()
       return reg;
 
   assert(0);
+
+  /* just to make the compiler happy */
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1240,10 +1210,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    /* if the allocation failed which means
                       this was spilt then break */
                    if (!sym->regs[j]) {
-                     if (j) {
-                       fprintf (stderr, "%d reg(s) lost in %s:%d\n",
-                                j, __FILE__,__LINE__);
-                     }
                      break;
                    }
                }
@@ -1316,6 +1282,9 @@ static void fillGaps()
 
        /* THERE IS HOPE !!!! */
        for (i=0; i < sym->nRegs ; i++ ) {
+           if (sym->regType == REG_PTR)
+               sym->regs[i] = getRegPtrNoSpil ();
+           else
                sym->regs[i] = getRegGprNoSpil ();                
        }
 
@@ -1342,15 +1311,27 @@ static void fillGaps()
                if (pdone > 1) break;
            }
        }
+       for (i = 0 ; i < sym->uses->size ; i++ ) {
+           if (bitVectBitValue(sym->uses,i)) {
+               iCode *ic;
+               if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+               if (SKIP_IC(ic)) continue;
+               if (!IS_ASSIGN_ICODE(ic)) continue ;
+
+               /* if result is assigned to registers */
+               if (IS_SYMOP(IC_RESULT(ic)) && 
+                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+                   pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+               }
+               if (pdone > 1) break;
+           }
+       }
        /* had to position more than once GIVE UP */
        if (pdone > 1) {
            /* UNDO all the changes we made to try this */
-           sym->isspilt = 0;
+           sym->isspilt = 1;
            for (i=0; i < sym->nRegs ; i++ ) {
-               if (sym->regType == REG_PTR)
-                   sym->regs[i] = getRegPtrNoSpil ();
-               else
-                   sym->regs[i] = getRegGprNoSpil ();
+                   sym->regs[i] = NULL;
            }
            freeAllRegs();
            D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
@@ -1581,10 +1562,7 @@ regTypeNum (eBBlock *ebbs)
            }
 
          /* if the symbol has only one definition &
-            that definition is a get_pointer and the
-            pointer we are getting is rematerializable and
-            in "data" space */
-
+            that definition is a get_pointer */
          if (bitVectnBitsOn (sym->defs) == 1 &&
              (ic = hTabItemWithKey (iCodehTab,
                                     bitVectFirstBit (sym->defs))) &&
@@ -1594,10 +1572,10 @@ regTypeNum (eBBlock *ebbs)
            {
 
 
-             /* if remat in data space */
+             /* and that pointer is 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)
+                 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
                {
                  /* create a psuedo symbol & force a spil */
                  symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
@@ -1979,10 +1957,13 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
 
       /* found it we need to remove it from the
          block */
-      for (sic = dic; sic != ic; sic = sic->next)
+      for (sic = dic; sic != ic; sic = sic->next) {
        bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
 
       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
+      OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq;
       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
       remiCodeFromeBBlock (ebp, dic);
       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
@@ -2012,11 +1993,14 @@ packRegsForSupport (iCode * ic, eBBlock * ebp)
        }
       /* found it we need to remove it from the
          block */
-      for (sic = dic; sic != ic; sic = sic->next)
+      for (sic = dic; sic != ic; sic = sic->next) {
        bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
 
       IC_RIGHT (ic)->operand.symOperand =
        IC_RIGHT (dic)->operand.symOperand;
+      OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq;
       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
 
       remiCodeFromeBBlock (ebp, dic);
@@ -2055,6 +2039,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
       !POINTER_GET (ic))
     return NULL;
   
+  if (ic->op == SEND && ic->argreg != 1) 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 &&
@@ -2222,6 +2208,17 @@ packRegsForAccUse (iCode * ic)
     return;
   }
 
+  /* if we are calling a reentrant function that has stack parameters */
+  if (ic->op == CALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
+      return;
+
+  if (ic->op == PCALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
+      return;
+
   /* if + or - then it has to be one byte result */
   if ((ic->op == '+' || ic->op == '-')
       && getSize (operandType (IC_RESULT (ic))) > 1)
@@ -2556,7 +2553,7 @@ packRegisters (eBBlock * ebp)
 
       /* some cases the redundant moves can
          can be eliminated for return statements */
-      if ((ic->op == RETURN || ic->op == SEND) &&
+      if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
          !isOperandInFarSpace (IC_LEFT (ic)) &&
          options.model == MODEL_SMALL) {
        if (0 && options.stackAuto) {