(committed on Frieder's behalf)
[fw/sdcc] / src / mcs51 / ralloc.c
index e6dbda5d701ecb1736334b20222b7dce592adfd1..163c2c54fffca23f890f0245f8650e8a1150b6ee 100644 (file)
@@ -1,9 +1,3 @@
-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
-  #define LRH(x) x
-#else
-  #define LRH(x)
-#endif
 /*------------------------------------------------------------------------
 
   SDCCralloc.c - source file for register allocation. (8051) specific
@@ -356,7 +350,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
@@ -577,7 +571,6 @@ spillThis (symbol * sym)
   if (!(sym->remat || sym->usl.spillLoc))
     createStackSpil (sym);
 
-  LRH(printf("spillThis: %s\n", sym->name));
   /* mark it has spilt & put it in the spilt set */
   sym->isspilt = sym->spillA = 1;
   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
@@ -725,7 +718,6 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
 
   /* get something we can spil */
   ssym = selectSpil (ic, ebp, forSym);
-  LRH(printf("spilSomething: spilled %s for %s\n", ssym->name, forSym->name));
 
   /* mark it as spilt */
   ssym->isspilt = ssym->spillA = 1;
@@ -1115,6 +1107,18 @@ serialRegAssign (eBBlock ** ebbs, int count)
 
        /* of all instructions do */
        for (ic = ebbs[i]->sch; ic; ic = ic->next) {
+#if 1
+           int reg;
+
+           // update the registers in use at the start of this icode
+           for (reg=0; reg<mcs51_nRegs; reg++) {
+             if (regs8051[reg].isFree) {
+               ic->riu &= ~(1<<regs8051[reg].offset);
+             } else {
+               ic->riu |= (1<<regs8051[reg].offset);
+             }
+           }
+#endif
 
            /* if this is an ipop that means some live
               range will have to be assigned again */
@@ -1175,9 +1179,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    continue;                 
                }
 
-               if (strcmp(sym->name,"iTemp121")==0) {
-                 printf ("Oops\n");
-               }
                /* if it has a spillocation & is used less than
                   all other live ranges then spill this */
                if (willCS) {
@@ -1224,19 +1225,21 @@ serialRegAssign (eBBlock ** ebbs, int count)
                    }
                }
 
-               /* if it shares registers with operands make sure
-                  that they are in the same position */
-               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
-                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
-                   positionRegs (OP_SYMBOL (IC_RESULT (ic)),
-                                 OP_SYMBOL (IC_LEFT (ic)));
-               }
-               /* do the same for the right operand */
-               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
-                   OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
-                   positionRegs (OP_SYMBOL (IC_RESULT (ic)),
-                                 OP_SYMBOL (IC_RIGHT (ic)));
-               }
+               if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
+                    /* if it shares registers with operands make sure
+                      that they are in the same position */
+                   if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+                       OP_SYMBOL (IC_LEFT (ic))->nRegs) {
+                       positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                     OP_SYMBOL (IC_LEFT (ic)));
+                   }
+                   /* do the same for the right operand */
+                   if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+                       OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
+                       positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                     OP_SYMBOL (IC_RIGHT (ic)));
+                   }
+                }
 
                if (ptrRegSet) {
                    mcs51_ptrRegReq--;
@@ -1254,7 +1257,8 @@ serialRegAssign (eBBlock ** ebbs, int count)
 static void fillGaps()
 {
     symbol *sym =NULL;
-    int key =0;    
+    int key =0;
+    int pass;
     
     if (getenv("DISABLE_FILL_GAPS")) return;
     
@@ -1291,52 +1295,89 @@ static void fillGaps()
            continue ;
        }
 
+        D(printf("Atemping fillGaps on %s: [",sym->name));
        /* THERE IS HOPE !!!! */
        for (i=0; i < sym->nRegs ; i++ ) {
            if (sym->regType == REG_PTR)
                sym->regs[i] = getRegPtrNoSpil ();
            else
                sym->regs[i] = getRegGprNoSpil ();                
+            D(printf("%s ", sym->regs[i]->name));
        }
+        D(printf("]\n"));
 
-       /* for all its definitions check if the registers
+       /* For all its definitions check if the registers
           allocated needs positioning NOTE: we can position
           only ONCE if more than One positioning required 
-          then give up */
+          then give up.
+          We may need to perform the checks twice; once to
+          position the registers as needed, the second to
+          verify any register repositioning is still
+          compatible.
+          */
        sym->isspilt = 0;
-       for (i = 0 ; i < sym->defs->size ; i++ ) {
-           if (bitVectBitValue(sym->defs,i)) {
-               iCode *ic;
-               if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
-               if (SKIP_IC(ic)) continue;
-               assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
-               /* if left is assigned to registers */
-               if (IS_SYMOP(IC_LEFT(ic)) && 
-                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
-                   pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
-               }
-               if (IS_SYMOP(IC_RIGHT(ic)) && 
-                   bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
-                   pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
+        for (pass=0; pass<2; pass++) {
+            D(printf(" checking definitions\n"));
+           for (i = 0 ; i < sym->defs->size ; i++ ) {
+               if (bitVectBitValue(sym->defs,i)) {
+                   iCode *ic;
+                   if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                    D(printf("  ic->seq = %d\n", ic->seq));
+                   if (SKIP_IC(ic)) continue;
+                   assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+                    /* if left is assigned to registers */
+                   if (IS_SYMOP(IC_LEFT(ic)))
+                      {
+                        D(printf("   left = "));
+                        D(printOperand(IC_LEFT(ic),NULL));
+                      }
+                    if (IS_SYMOP(IC_LEFT(ic)) && 
+                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+                       pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+                   }
+                   if (IS_SYMOP(IC_RIGHT(ic)))
+                      {
+                        D(printf("   right = "));
+                        D(printOperand(IC_RIGHT(ic),NULL));
+                      }
+                   if (IS_SYMOP(IC_RIGHT(ic)) && 
+                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+                       pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+                   }
+                    D(printf("   pdone = %d\n", pdone));
+                   if (pdone > 1) break;
                }
-               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)));
+            D(printf(" checking uses\n"));
+           for (i = 0 ; i < sym->uses->size ; i++ ) {
+               if (bitVectBitValue(sym->uses,i)) {
+                   iCode *ic;
+                   if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                    D(printf("  ic->seq = %d\n", ic->seq));
+                   if (SKIP_IC(ic)) continue;
+                   if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
+
+                   /* if result is assigned to registers */
+                   if (IS_SYMOP(IC_RESULT(ic)))
+                      {
+                        D(printf("   result = "));
+                        D(printOperand(IC_RESULT(ic),NULL));
+                      }
+                   if (IS_SYMOP(IC_RESULT(ic)) && 
+                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+                       pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+                   }
+                    D(printf("   pdone = %d\n", pdone));
+                   if (pdone > 1) break;
                }
-               if (pdone > 1) break;
            }
-       }
+            if (pdone == 0) break; /* second pass only if regs repositioned */
+           if (pdone > 1) break;
+        }
+        D(printf(" sym->regs = ["));
+       for (i=0; i < sym->nRegs ; i++ )
+          D(printf("%s ", sym->regs[i]->name));
+        D(printf("]\n"));
        /* had to position more than once GIVE UP */
        if (pdone > 1) {
            /* UNDO all the changes we made to try this */
@@ -1569,34 +1610,10 @@ regTypeNum (eBBlock *ebbs)
          if (sym->ruonly || sym->accuse)
            {
              if (IS_AGGREGATE (sym->type) || sym->isptr)
-               sym->type = aggrToPtr (sym->type, FALSE);
+               sym->type = aggrToPtr (sym->type, FALSE);
              continue;
            }
 
-#ifdef RANGEHUNT
-         /* if this symbol has only one usage and that is an assignment
-            to a ruonly, we don't need registers */
-         // if this symbol has only one def
-         if (bitVectnBitsOn (sym->defs)==1) {
-           printf ("sym: %s has only one usage", sym->name);
-           // find that usage
-           if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
-             if (ic->op==CALL) {
-               printf (" for a call ");
-               // if this is only assigned to a ruonly
-               if ((ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs)))) {
-                 if (ic->op=='=') {
-                   if (OP_SYMBOL(IC_RESULT(ic))->ruonly) {
-                     printf("regTypeNum: %s assigned to %s\n", \
-                            sym->name, OP_SYMBOL(IC_RESULT(ic))->name); 
-                   }
-                 }
-               }
-             }
-           }
-         }
-#endif
-
          /* if the symbol has only one definition &
             that definition is a get_pointer */
          if (bitVectnBitsOn (sym->defs) == 1 &&
@@ -1609,7 +1626,8 @@ regTypeNum (eBBlock *ebbs)
 
 
              /* and that pointer is remat in data space */
-             if (OP_SYMBOL (IC_LEFT (ic))->remat &&
+              if (IS_SYMOP (IC_LEFT (ic)) &&
+                 OP_SYMBOL (IC_LEFT (ic))->remat &&
                  !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
                  DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
                {
@@ -1617,6 +1635,7 @@ regTypeNum (eBBlock *ebbs)
                  symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
                  psym->type = sym->type;
                  psym->etype = sym->etype;
+                  
                  strcpy (psym->rname, psym->name);
                  sym->isspilt = 1;
                  sym->usl.spillLoc = psym;
@@ -1725,23 +1744,40 @@ farSpacePackable (iCode * ic)
          getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
        return NULL;
 
-      /* if any three is a true symbol in far space */
-      if (IC_RESULT (dic) &&
-         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
-         isOperandInFarSpace (IC_RESULT (dic)))
-       return NULL;
+      if (dic->op == IFX)
+        {
+          if (IC_COND (dic) &&
+             IS_TRUE_SYMOP (IC_COND (dic)) &&
+             isOperandInFarSpace (IC_COND (dic)))
+           return NULL;
+        }
+      else if (dic->op == JUMPTABLE)
+        {
+          if (IC_JTCOND (dic) &&
+             IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
+             isOperandInFarSpace (IC_JTCOND (dic)))
+           return NULL;
+        }
+      else
+        {
+          /* if any three is a true symbol in far space */
+          if (IC_RESULT (dic) &&
+             IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+             isOperandInFarSpace (IC_RESULT (dic)))
+           return NULL;
 
-      if (IC_RIGHT (dic) &&
-         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
-         isOperandInFarSpace (IC_RIGHT (dic)) &&
-         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
-       return NULL;
+          if (IC_RIGHT (dic) &&
+             IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+             isOperandInFarSpace (IC_RIGHT (dic)) &&
+             !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+           return NULL;
 
-      if (IC_LEFT (dic) &&
-         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
-         isOperandInFarSpace (IC_LEFT (dic)) &&
-         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
-       return NULL;
+          if (IC_LEFT (dic) &&
+             IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+             isOperandInFarSpace (IC_LEFT (dic)) &&
+             !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+           return NULL;
+        }
 
       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
        {
@@ -1785,53 +1821,73 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
      we cannot */
   for (dic = ic->prev; dic; dic = dic->prev)
     {
+
+#if 0 /* jwk: This collides with 1.43 but I really see no need for
+        this anymore. It fixes bug #716790 and substantially improves 
+        redundant register usage around function calls.
+      */
+
       /* if there is a function call then don't pack it */
       if ((dic->op == CALL || dic->op == PCALL))
        {
          dic = NULL;
          break;
        }
+#endif
 
       if (SKIP_IC2 (dic))
        continue;
 
-      if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
-         IS_OP_VOLATILE (IC_RESULT (dic)))
-       {
-         dic = NULL;
-         break;
-       }
+      if (dic->op == IFX)
+        {
+          if (IS_SYMOP (IC_COND (dic)) &&
+             (IC_COND (dic)->key == IC_RESULT (ic)->key ||
+              IC_COND (dic)->key == IC_RIGHT (ic)->key))
+           {
+             dic = NULL;
+             break;
+           }
+        }
+      else
+        {
+          if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+             IS_OP_VOLATILE (IC_RESULT (dic)))
+           {
+             dic = NULL;
+             break;
+           }
 
-      if (IS_SYMOP (IC_RESULT (dic)) &&
-         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
-       {
-         if (POINTER_SET (dic))
-           dic = NULL;
+          if (IS_SYMOP (IC_RESULT (dic)) &&
+             IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+           {
+             if (POINTER_SET (dic))
+               dic = NULL;
 
-         break;
-       }
+             break;
+           }
 
-      if (IS_SYMOP (IC_RIGHT (dic)) &&
-         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
-          IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
-       {
-         dic = NULL;
-         break;
-       }
+          if (IS_SYMOP (IC_RIGHT (dic)) &&
+             (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+              IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+           {
+             dic = NULL;
+             break;
+           }
 
-      if (IS_SYMOP (IC_LEFT (dic)) &&
-         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
-          IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
-       {
-         dic = NULL;
-         break;
-       }
+          if (IS_SYMOP (IC_LEFT (dic)) &&
+             (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+              IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+           {
+             dic = NULL;
+             break;
+           }
 
-      if (POINTER_SET (dic) &&
-         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
-       {
-         dic = NULL;
-         break;
+          if (POINTER_SET (dic) &&
+             IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+           {
+             dic = NULL;
+             break;
+           }
        }
     }
 
@@ -1843,7 +1899,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
     {
       sym_link *etype = operandType (IC_RIGHT (dic));
       if (IS_BITFIELD (etype))
-       return 0;
+        {
+          /* if result is a bit too then it's ok */
+         etype = operandType (IC_RESULT (dic));
+          if (!IS_BITFIELD (etype))
+           return 0;
+       }
     }
   /* if the result is on stack or iaccess then it must be
      the same atleast one of the operands */
@@ -1874,7 +1935,7 @@ pack:
     {
       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
     }
-  // jwk: and the otherway around?
+  // TODO: and the otherway around?
 
   /* delete from liverange table also 
      delete from all the points inbetween and the new
@@ -1889,7 +1950,7 @@ pack:
   remiCodeFromeBBlock (ebp, ic);
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-  OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+  OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
   return 1;
 }
 
@@ -1923,20 +1984,33 @@ findAssignToSym (operand * op, iCode * ic)
        break;  /* found where this temp was defined */
 
       /* if we find an usage then we cannot delete it */
-      if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
-       return NULL;
+      
+      if (dic->op == IFX)
+        {
+          if (IC_COND (dic) && IC_COND (dic)->key == op->key)
+            return NULL;
+        }
+      else if (dic->op == JUMPTABLE)
+        {
+          if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
+            return NULL;
+        }
+      else
+        {
+          if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+           return NULL;
 
-      if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
-       return NULL;
+          if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+           return NULL;
 
-      if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
-       return NULL;
+          if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+           return NULL;
+       }
     }
 
   if (!dic)
     return NULL;   /* didn't find any assignment to op */
 
-  LRH(printf ("findAssignToSym: %s\n", OP_SYMBOL(IC_RESULT(dic))->name));
   /* we are interested only if defined in far space */
   /* or in stack space in case of + & - */
   
@@ -2124,7 +2198,6 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
                         bitVectFirstBit (OP_DEFS (op)))))
     return NULL;
 
-  LRH(printf ("packRegsForOneUse: %s\n", OP_SYMBOL(op)->name));
   /* if that only usage is a cast */
   if (dic->op == CAST) {
     /* to a bigger type */
@@ -2505,6 +2578,7 @@ packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
        return ;
     }
     /* make sure they have the same type */
+    if (IS_SPEC(operandType(IC_LEFT(ic))))
     {
       sym_link *itype=operandType(IC_LEFT(ic));
       sym_link *ditype=operandType(IC_RIGHT(dic));
@@ -2595,7 +2669,8 @@ packRegisters (eBBlock ** ebpp, int blockno)
         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 ) {
+         OP_SYMBOL(IC_RIGHT(ic))->remat &&
+         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
              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)) {                  
@@ -2624,7 +2699,8 @@ packRegisters (eBBlock ** ebpp, int blockno)
       if (POINTER_SET (ic))
        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
 
-      if (POINTER_GET (ic))
+      if (POINTER_GET (ic) &&
+         IS_SYMOP(IC_LEFT (ic)))
        OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
 
       if (!SKIP_IC2 (ic))
@@ -2689,6 +2765,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
 
       /* if pointer get */
       if (POINTER_GET (ic) &&
+         IS_SYMOP (IC_LEFT (ic)) &&
          !isOperandInFarSpace (IC_RESULT (ic)) &&
          !OP_SYMBOL (IC_LEFT (ic))->remat &&
          !IS_OP_RUONLY (IC_RESULT (ic)) &&
@@ -2721,7 +2798,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
                      remiCodeFromeBBlock (ebp, ic);
                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
                      hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+                     OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
                      ic = ic->prev;
                    }
                  else
@@ -2744,7 +2821,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
                      remiCodeFromeBBlock (ebp, ic);
                      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
                      hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
+                     OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
                      ic = ic->prev;
                    }
                }
@@ -2794,15 +2871,21 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   int i;
 
   setToNull ((void *) &_G.funcrUsed);
+  setToNull ((void *) &_G.regAssigned);
   setToNull ((void *) &_G.totRegAssigned);
   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
   mcs51_nRegs = 8;
 
   /* change assignments this will remove some
      live ranges reducing some register pressure */
+  
   for (i = 0; i < count; i++)
     packRegisters (ebbs, i);
 
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
+
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
@@ -2814,6 +2897,8 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   serialRegAssign (ebbs, count);
 
   freeAllRegs ();
+  //setToNull ((void *) &_G.regAssigned);
+  //setToNull ((void *) &_G.totRegAssigned);
   fillGaps();
 
   /* if stack was extended then tell the user */
@@ -2836,7 +2921,9 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   createRegMask (ebbs, count);
 
   /* redo that offsets for stacked automatic variables */
-  redoStackOffsets ();
+  if (currFunc) {
+    redoStackOffsets ();
+  }
 
   if (options.dump_rassgn)
     {
@@ -2855,8 +2942,8 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count)
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
-  setToNull ((void **) &_G.stackSpil);
-  setToNull ((void **) &_G.spiltSet);
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
   freeAllRegs ();