* Makefile.in, configure.in, configure,
[fw/sdcc] / src / SDCClrange.c
index 26e4e97c72d76c3c8e2bdf21122832c3eee1b59d..c4a5bcc2959a180b2a67d7b7e5499682aa854551 100644 (file)
@@ -8,19 +8,19 @@
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 #include "common.h"
 -------------------------------------------------------------------------*/
 
 #include "common.h"
@@ -31,10 +31,31 @@ hTab *liveRanges = NULL;
 hTab *iCodehTab = NULL;
 hTab *iCodeSeqhTab = NULL;
 
 hTab *iCodehTab = NULL;
 hTab *iCodeSeqhTab = NULL;
 
+/* all symbols, for which the previous definition is searched
+   and warning is emitted if there's none. */
+#define IS_AUTOSYM(op) (IS_ITEMP(op) || \
+                        (IS_SYMOP(op) && IS_AUTO(op->operand.symOperand) && !IS_PARM(op)))
+
+/*-----------------------------------------------------------------*/
+/* hashiCodeKeys - add all iCodes to the hash table                */
+/*-----------------------------------------------------------------*/
+void
+hashiCodeKeys (eBBlock ** ebbs, int count)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        hTabAddItem (&iCodehTab, ic->key, ic);
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* sequenceiCode - creates a sequence number for the iCode & add   */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* sequenceiCode - creates a sequence number for the iCode & add   */
 /*-----------------------------------------------------------------*/
-void 
+static void
 sequenceiCode (eBBlock ** ebbs, int count)
 {
   int i;
 sequenceiCode (eBBlock ** ebbs, int count)
 {
   int i;
@@ -48,128 +69,18 @@ sequenceiCode (eBBlock ** ebbs, int count)
        {
          ic->seq = ++iCodeSeq;
          ic->depth = ebbs[i]->depth;
        {
          ic->seq = ++iCodeSeq;
          ic->depth = ebbs[i]->depth;
-         hTabAddItem (&iCodehTab, ic->key, ic);
+         //hTabAddItem (&iCodehTab, ic->key, ic);
          hTabAddItem (&iCodeSeqhTab, ic->seq, ic);
        }
       ebbs[i]->lSeq = iCodeSeq;
     }
 }
 
          hTabAddItem (&iCodeSeqhTab, ic->seq, ic);
        }
       ebbs[i]->lSeq = iCodeSeq;
     }
 }
 
-/*-----------------------------------------------------------------*/
-/* markVisited - will set the visited flag for the given Block     */
-/*-----------------------------------------------------------------*/
-DEFSETFUNC (markVisited)
-{
-  eBBlock *ebp = item;
-
-  if (ebp->visited)
-    return 0;
-  ebp->visited = 1;
-  applyToSet (ebp->succList, markVisited);
-  return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* isOpAlive - checks to see if the usage in this block is the     */
-/*             uses the same definitions as this one               */
-/*-----------------------------------------------------------------*/
-DEFSETFUNC (isOpAlive)
-{
-  eBBlock *ebp = item;
-  V_ARG (operand *, op);
-  V_ARG (eBBlock *, orig);
-  V_ARG (iCode *, ic);
-
-  if (ebp->visited)
-    return 0;
-
-  ebp->visited = 1;
-
-  /* if we have reached the originating block */
-  /* or this block has some definiton for it  */
-  /* then check if it is used between start & */
-  /* this point */
-  if (ebp == orig ||
-      bitVectBitsInCommon (OP_DEFS (op), ebp->defSet))
-    if (usedBetweenPoints (op, ebp->sch, ic))
-      return 1;
-    else
-      {
-       applyToSet (ebp->succList, markVisited);
-       return 0;
-      }
-  else
-    /* choosing this more expensive one since 
-       killDeadCode will take away some definitions
-       but there is not way right now to take away
-       the usage information for the corresponding
-       usages, this will lead to longer live ranges */
-  if (usedInRemaining (op, ebp->sch))
-    return 1;
-
-
-  return (applyToSet (ebp->succList, isOpAlive, op, orig, ic));
-}
-
-/*-----------------------------------------------------------------*/
-/* isLastUse - return TRUE if no usage of this operand after this  */
-/*-----------------------------------------------------------------*/
-int 
-isLastUse (operand * op, eBBlock * ebp, iCode * ic,
-          eBBlock ** ebbs, int count)
-{
-  int i;
-
-  /* if this is used in the remaining */
-  if (usedInRemaining (op, ic))
-    return 0;
-
-  if (getenv ("SDCC_LRKLAUS"))
-    {
-      /* if not then check any of the following blocks use it */
-      for (i = 0; i < count; i++)
-        {
-          if (ebbs[i]->fSeq <= ebp->fSeq)
-           continue;
-          if (usedInRemaining (op, ebbs[i]->sch))
-           return 0;
-        }
-    }
-  else
-    {
-      /* if not then check any of the successor blocks use it */
-      for (i = 0; i < count;)
-        ebbs[i++]->visited = 0;
-      if (applyToSet (ebp->succList, isOpAlive, op, ebp, ic))
-        return 0;
-    }
-
-  /* this is the last use */
-  return 1;
-}
-
-/*-----------------------------------------------------------------*/
-/* unionDefsUsed - unions the defsUsed in a block                  */
-/*-----------------------------------------------------------------*/
-DEFSETFUNC (unionDefsUsed)
-{
-  eBBlock *ebp = item;
-  V_ARG (bitVect **, bvp);
-
-  if (ebp->visited)
-    return 0;
-
-  ebp->visited = 1;
-
-  *bvp = bitVectUnion (*bvp, ebp->usesDefs);
-  applyToSet (ebp->succList, unionDefsUsed, bvp);
-  return 0;
-}
-
 /*-----------------------------------------------------------------*/
 /* setFromRange - sets the from range of a given operand           */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* setFromRange - sets the from range of a given operand           */
 /*-----------------------------------------------------------------*/
-void 
+#if 0
+static void
 setFromRange (operand * op, int from)
 {
   /* only for compiler defined temporaries */
 setFromRange (operand * op, int from)
 {
   /* only for compiler defined temporaries */
@@ -185,11 +96,12 @@ setFromRange (operand * op, int from)
       OP_LIVEFROM (op) > from)
     OP_LIVEFROM (op) = from;
 }
       OP_LIVEFROM (op) > from)
     OP_LIVEFROM (op) = from;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* setToRange - set the range to for an operand                    */
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /* setToRange - set the range to for an operand                    */
 /*-----------------------------------------------------------------*/
-void 
+void
 setToRange (operand * op, int to, bool check)
 {
   /* only for compiler defined temps */
 setToRange (operand * op, int to, bool check)
 {
   /* only for compiler defined temps */
@@ -211,484 +123,649 @@ setToRange (operand * op, int to, bool check)
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* firstDeOf - finds the first definition in seq for op            */
+/* setFromRange - sets the from range of a given operand           */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static iCode *
-firstDefOf (operand * op)
+static void
+setLiveFrom (symbol * sym, int from)
 {
 {
-  int i;
-  iCode *ric = NULL, *lic = NULL;
-  int fSeq = INT_MAX;
+  if (!sym->liveFrom || sym->liveFrom > from)
+    sym->liveFrom = from;
+}
+
+/*-----------------------------------------------------------------*/
+/* setToRange - set the range to for an operand                    */
+/*-----------------------------------------------------------------*/
+static void
+setLiveTo (symbol * sym, int to)
+{
+  if (!sym->liveTo || sym->liveTo < to)
+    sym->liveTo = to;
+}
 
 
-  if (!OP_DEFS (op))
-    return NULL;
+/*-----------------------------------------------------------------*/
+/* markLiveRanges - for each operand mark the liveFrom & liveTo    */
+/*-----------------------------------------------------------------*/
+static void
+markLiveRanges (eBBlock ** ebbs, int count)
+{
+  int i, key;
+  symbol *sym;
 
 
-  for (i = 0; i < OP_DEFS (op)->size; i++)
+  for (i = 0; i < count; i++)
     {
     {
-      if (bitVectBitValue (OP_DEFS (op), i) &&
-         (lic = hTabItemWithKey (iCodehTab, i)) &&
-         lic->seq < fSeq)
-       {
+      iCode *ic;
+
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
+         if (ic->op == CALL || ic->op == PCALL)
+           if (bitVectIsZero (OP_SYMBOL (IC_RESULT (ic))->uses))
+              bitVectUnSetBit (ebbs[i]->defSet, ic->key);
+
+         /* for all iTemps alive at this iCode */
+         for (key = 1; key < ic->rlive->size; key++)
+           {
+             if (!bitVectBitValue(ic->rlive, key))
+               continue;
+
+             sym = hTabItemWithKey(liveRanges, key);
+             setLiveTo(sym, ic->seq);
+             setLiveFrom(sym, ic->seq);
+           }
 
 
-         fSeq = lic->seq;
-         ric = lic;
        }
     }
        }
     }
-  return ric;
 }
 }
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-/* useDefLoopCheck - check for uses before init inside loops       */
+/* markAlive - marks the operand as alive between sic and eic      */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static void 
-useDefLoopCheck (operand * op, iCode * ic)
+static void
+markAlive (iCode * sic, iCode * eic, int key)
 {
 {
-  /* this is for situations like the following
-     int a,b;
-
-     while (...) {
-     a = ... ;
-     ...
-     _some_usage_of_b_;
-     ...
-     b = ... ;
-     } 
-     in this case the definition of 'b' will flow to the usages
-     but register allocator cannot handle these situations.so
-     will mark as spilt */
-
-  int i = 0, fdSeq;
-  int er = 0;
-  iCode *tic;
-
-  /* get the first definition */
-  if (!(tic = firstDefOf (op)))
-    return;
+  iCode *dic;
 
 
-  fdSeq = tic->seq;
-  /* now go thru the usages & make sure they follow
-     the first definition */
-  for (i = 0; i <= OP_USES (op)->size; i++)
+  for (dic = sic; dic != eic->next; dic = dic->next)
     {
     {
-      if (bitVectBitValue (OP_USES (op), i) &&
-         (tic = hTabItemWithKey (iCodehTab, i)) &&
-         tic->seq < fdSeq)
-       {
-         er = 1;
-         break;
-       }
+      dic->rlive = bitVectSetBit (dic->rlive, key);
     }
     }
+}
+
+/*-----------------------------------------------------------------*/
+/* findNextUseSym - finds the next use of the symbol and marks it  */
+/*                  alive in between                               */
+/*-----------------------------------------------------------------*/
+static int
+findNextUseSym (eBBlock *ebp, iCode *ic, symbol * sym)
+{
+  int retval = 0;
+  iCode *uic;
+  eBBlock *succ;
+
+  hTabAddItemIfNotP (&liveRanges, sym->key, sym);
 
 
-  /* found a usage without definition */
-  if (er)
+  if (!ic)
+    goto check_successors;
+
+  /* if we check a complete block and the symbol */
+  /* is alive at the beginning of the block */
+  /* and not defined in the first instructions */
+  /* then a next use exists (return 1) */
+  if ((ic == ebp->sch) && bitVectBitValue(ic->rlive, sym->key))
     {
     {
-      if (OP_SYMBOL (op)->isreqv && SPIL_LOC (op))
-       {
+      /* check if the first instruction is a def of this op */
+      if (ic->op == JUMPTABLE || ic->op == IFX || SKIP_IC2(ic))
+        return 1;
+
+      if (IS_ITEMP(IC_RESULT(ic)))
+        if (IC_RESULT(ic)->key == sym->key)
+         return 0;
+
+      return 1;
+    }
+
+  if (ebp->visited)
+    return 0;
+
+  if (ic == ebp->sch)
+    ebp->visited = 1;
+
+  /* for all remaining instructions in current block */
+  for (uic = ic; uic; uic = uic->next)
+    {
+
+      if (SKIP_IC2(uic))
+        continue;
 
 
-         werror (W_LOCAL_NOINIT,
-                 SPIL_LOC (op)->name,
-                 ic->filename, ic->lineno);
+      if (uic->op == JUMPTABLE)
+        {
+          if (IS_ITEMP(IC_JTCOND(uic)) && IC_JTCOND(uic)->key == sym->key)
+            {
+             markAlive(ic, uic, sym->key);
+             return 1;
+           }
+          continue;
        }
        }
-      else
-       {
 
 
-         werror (W_LOCAL_NOINIT,
-                 OP_SYMBOL (op)->name,
-                 ic->filename, ic->lineno);
+      if (uic->op == IFX)
+        {
+          if (IS_ITEMP(IC_COND(uic)) && IC_COND(uic)->key == sym->key)
+            {
+             markAlive(ic, uic, sym->key);
+             return 1;
+           }
+          continue;
        }
        }
-#if 0 // this will create a segfault: bug #498971
-      OP_SYMBOL (op)->isspilt = 1;
-#endif
+
+      if (IS_ITEMP (IC_LEFT (uic)))
+        if (IC_LEFT (uic)->key == sym->key)
+          {
+           markAlive(ic, uic, sym->key);
+           return 1;
+         }
+
+      if (IS_ITEMP (IC_RIGHT (uic)))
+        if (IC_RIGHT (uic)->key == sym->key)
+         {
+           markAlive (ic, uic, sym->key);
+           return 1;
+         }
+
+      if (IS_ITEMP (IC_RESULT (uic)))
+        if (IC_RESULT (uic)->key == sym->key)
+         {
+           if (POINTER_SET (uic))
+             {
+               markAlive (ic, uic, sym->key);
+                return 1;
+             }
+           else
+             return 0;
+         }
+
     }
     }
+
+  /* check all successors */
+check_successors:
+
+  succ = setFirstItem (ebp->succList);
+  for (; succ; succ = setNextItem (ebp->succList))
+    {
+      retval += findNextUseSym (succ, succ->sch, sym);
+    }
+
+  if (retval)
+    {
+      if (ic) markAlive (ic, ebp->ech, sym->key);
+      return 1;
+    }
+
+  return 0;
 }
 
 }
 
+/*-----------------------------------------------------------------*/
+/* findNextUse - finds the next use of the operand and marks it    */
+/*               alive in between                                  */
+/*-----------------------------------------------------------------*/
+static int
+findNextUse (eBBlock *ebp, iCode *ic, operand *op)
+{
+  if (op->isaddr)
+    OP_SYMBOL (op)->isptr = 1;
+
+  OP_SYMBOL (op)->key = op->key;
+
+  return findNextUseSym (ebp, ic, OP_SYMBOL(op));
+}
 
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
-/* operandLUse - check and set the last use for a given operand    */
+/* unvisitBlocks - clears visited in all blocks                    */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-operand *
-operandLUse (operand * op, eBBlock ** ebbs,
-            int count, iCode * ic, eBBlock * ebp)
+static void
+unvisitBlocks (eBBlock ** ebbs, int count)
 {
 {
-  setFromRange (op, ic->seq);
-  if (ic->depth)
-    OP_SYMBOL (op)->used += (((unsigned int) 1 << ic->depth) + 1);
-  else
-    OP_SYMBOL (op)->used += 1;
+  int i;
 
 
-  if (isLastUse (op, ebp, ic->next, ebbs, count) ||
-      (OP_LIVETO (op) && OP_LIVETO (op) < ic->seq))
+  for (i = 0; i < count; i++)
+    ebbs[i]->visited = 0;
+}
+
+/*------------------------------------------------------------------*/
+/* markWholeLoop - mark the symbol 'key' alive in all blocks        */
+/*                 included by the outermost loop                   */
+/*------------------------------------------------------------------*/
+static void
+markWholeLoop (eBBlock *ebp, int key)
+{
+  eBBlock *ebpi;
+
+  /* avoid endless loops */
+  ebp->visited = 1;
+
+  /* recurse through all predecessors */
+  for (ebpi = setFirstItem (ebp->predList);
+       ebpi;
+       ebpi = setNextItem (ebp->predList))
+    {
+      if (ebpi->visited)
+        continue;
+      /* is the predecessor still in the loop? */
+      if (ebpi->depth == 0)
+        continue;
+      markWholeLoop (ebpi, key);
+    }
+
+  /* recurse through all successors */
+  for (ebpi = setFirstItem (ebp->succList);
+       ebpi;
+       ebpi = setNextItem (ebp->succList))
+    {
+      if (ebpi->visited)
+        continue;
+      if (ebpi->depth == 0)
+        continue;
+      markWholeLoop (ebpi, key);
+    }
+
+  markAlive (ebp->sch, ebp->ech, key);
+}
+
+/*------------------------------------------------------------------*/
+/* findPrevUseSym - search for a previous definition of a symbol in */
+/*                  - the previous icodes                           */
+/*                  - all branches of predecessors                  */
+/*------------------------------------------------------------------*/
+static bool
+findPrevUseSym  (eBBlock *ebp, iCode *ic, symbol * sym)
+{
+  eBBlock * pred;
+  iCode * uic;
+
+  if (ebp->visited)
     {
     {
-      int torange = ic->seq;
+     /* already visited: this branch must have been succesfull, */
+     /* because otherwise the search would have been aborted. */
+      return TRUE;
+    }
+  ebp->visited = 1;
 
 
-      /* if this is a SEND then the toRange should be extended
-         to the call */
-      if (ic->op == SEND)
+  /* search backward in the current block */
+  for (uic = ic; uic; uic = uic->prev)
+    {
+      if (!POINTER_SET (uic) && IS_AUTOSYM (IC_RESULT (uic)))
         {
         {
-          iCode *lic ;
-          for (lic = ic->next ; lic ; lic = lic->next)
+          if (IC_RESULT (uic)->key == sym->key)
             {
             {
-              if (lic->op == CALL || lic->op == PCALL)
-                break;
+              /* Ok, found a definition */
+              return TRUE;
             }
             }
-          /* found it : mark */
-          if (lic)
-            torange = lic->prev->seq;
         }
         }
-      /* if this is the last use then if this block belongs
-         to a  loop &  some definition  comes into the loop
-         then extend the live range to  the end of the loop */
-      if (getenv ("SDCC_LRKLAUS"))
+      /* address taken from symbol? */
+      if (uic->op == ADDRESS_OF && IS_AUTOSYM (IC_LEFT (uic)))
         {
         {
-         if (ebp->KpartOfLoop)
+          if (IC_LEFT (uic)->key == sym->key)
             {
             {
-              region *aloop;
-
-              aloop = setFirstItem (ebp->KpartOfLoop);
-              for (; aloop; aloop = setNextItem (ebp->KpartOfLoop))
-                {
-                  if (hasIncomingDefs (aloop, op))
-                    torange = findLoopEndSeq (aloop);
-                }
+              /* Ok, found a definition */
+              return TRUE;
             }
             }
-       }
-      else
-        {
-          if (ebp->partOfLoop
-             && hasIncomingDefs (ebp->partOfLoop, op))
-           {
-             torange = findLoopEndSeq (ebp->partOfLoop);
-           }
-       }
-
-      op = operandFromOperand (op);
-      setToRange (op, torange, FALSE);
+        }
     }
     }
-  ic->uses = bitVectSetBit (ic->uses, op->key);
 
 
-  if (!OP_SYMBOL (op)->udChked)
+  /* There's no definition in this bblock, */
+  /* let's have a look at all predecessors. */
+  pred = setFirstItem (ebp->predList);
+  if (!pred)
     {
     {
-      sym_link *type = operandType (op);
-      sym_link *etype = getSpec (type);
-
-      OP_SYMBOL (op)->udChked = 1;
-      /* good place to check if unintialised */
-      if ((IS_TRUE_SYMOP (op) || OP_SYMBOL (op)->isreqv) &&
-         OP_SYMBOL (op)->islocal &&
-         !IS_AGGREGATE (type) &&
-         !IS_FUNC (type) &&
-         ic->op != ADDRESS_OF &&
-         !IS_STATIC (etype))
-       {
+      /* no more predecessors and nothing found yet :-( */
+      return FALSE;
+    }
+  for (; pred; pred = setNextItem (ebp->predList))
+    {
+      /* recurse into all predecessors */
+      if (!findPrevUseSym (pred, pred->ech, sym))
+        {
+          /* found nothing: abort */
+          return FALSE;
+        }
+    }
 
 
-         if (bitVectIsZero (op->usesDefs) && OP_SYMBOL(op)->ival==NULL)
-           {
-             OP_SYMBOL (op)->isspilt = 1;
+  /* Success! Went through all branches with no abort: */
+  /* all branches end with a definition */
+  return TRUE;
+}
 
 
-             if (OP_SYMBOL (op)->isreqv &&
-                 !OP_SYMBOL (op)->_isparm && SPIL_LOC (op))
-               {
+/*------------------------------------------------------------------*/
+/* findPrevUse - search for a previous definition of an operand     */
+/*                  If there's no definition let's:                 */
+/*                  - emit a warning                                */
+/*                  - fix the life range, if the symbol is used in  */
+/*                    a loop                                        */
+/*------------------------------------------------------------------*/
+static void
+findPrevUse (eBBlock *ebp, iCode *ic, operand *op,
+             eBBlock ** ebbs, int count,
+             bool emitWarnings)
+{
+  unvisitBlocks (ebbs, count);
 
 
-                 werror (W_LOCAL_NOINIT,
-                         SPIL_LOC (op)->name,
-                         ic->filename, ic->lineno);
-               }
-             else
-               {
+  if (op->isaddr)
+    OP_SYMBOL (op)->isptr = 1;
+  OP_SYMBOL (op)->key = op->key;
 
 
-                 werror (W_LOCAL_NOINIT,
-                         OP_SYMBOL (op)->name,
-                         ic->filename, ic->lineno);
-               }
-           }
-         else
-           {
-             if (ebp->depth && op->usesDefs &&
-                 !OP_SYMBOL (op)->_isparm)
-               {
-                 /* check non-inits inside loops */
-                 useDefLoopCheck (op, ic);
-               }
-           }
-       }
+  /* There must be a definition in each branch of predecessors */
+  if (!findPrevUseSym (ebp, ic->prev, OP_SYMBOL(op)))
+    {
+      /* computeLiveRanges() is called twice */
+      if (emitWarnings)
+        {
+          if (IS_ITEMP (op))
+            {
+              if (OP_SYMBOL (op)->prereqv)
+                {
+                  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+                            OP_SYMBOL (op)->prereqv->name);
+                  OP_SYMBOL (op)->prereqv->reqv = NULL;
+                  OP_SYMBOL (op)->prereqv->allocreq = 1;
+                }
+            }
+          else
+            {
+              werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+                        OP_SYMBOL (op)->name);
+            }
+        }
+      /* is this block part of a loop? */
+      if (IS_ITEMP (op) && ebp->depth != 0)
+        {
+          /* extend the life range to the outermost loop */
+          unvisitBlocks(ebbs, count);
+          markWholeLoop (ebp, op->key);
+        }
     }
     }
-  return op;
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* killAllAlive - mark all the definitions living with this seq    */
+/* incUsed - increment a symbol's usage count                      */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-void 
-killAllAlive (int seq)
+static void
+incUsed (iCode *ic, operand *op)
 {
 {
-  symbol *sym;
-  int k;
-
-  for (sym = hTabFirstItem (liveRanges, &k); sym;
-       sym = hTabNextItem (liveRanges, &k))
-    if (!sym->liveTo || (sym->liveTo < sym->liveFrom))
-      sym->liveTo = seq;
+  if (ic->depth)
+    OP_SYMBOL (op)->used += (((unsigned int) 1 << ic->depth) + 1);
+  else
+    OP_SYMBOL (op)->used += 1;
 }
 }
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-/* defUsedAfterLoop - all definitions & usages before sequence num */
+/* rliveClear - clears the rlive bitVectors                        */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-bool 
-defUsedAfterLoop (operand * op, int seq)
+static void
+rliveClear (eBBlock ** ebbs, int count)
 {
   int i;
 {
   int i;
-  iCode *ic;
 
 
-  /* check for the usages first */
-  if (OP_SYMBOL (op)->uses && !bitVectIsZero (OP_SYMBOL (op)->uses))
+  /* for all blocks do */
+  for (i = 0; i < count; i++)
     {
     {
-      for (i = 0; i < OP_SYMBOL (op)->uses->size; i++)
-       {
+      iCode *ic;
 
 
-         if (bitVectBitValue (OP_SYMBOL (op)->uses, i) &&      /* usage found */
-             (ic = hTabItemWithKey (iCodehTab, i)) &&  /*    ""       */
-             ic->seq > seq)    /* & is after the seq */
-           return TRUE;
+      /* for all instructions in this block do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
+         freeBitVect (ic->rlive);
+         ic->rlive = NULL;
        }
     }
        }
     }
-
-  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* markLiveRanges - for each operand mark the liveFrom & liveTo    */
+/* rlivePoint - for each point compute the ranges that are alive   */
+/* The live range is only stored for ITEMPs; the same code is used */
+/* to find use of unitialized AUTOSYMs (an ITEMP is an AUTOSYM).   */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-void 
-markLiveRanges (eBBlock * ebp, eBBlock ** ebbs, int count)
+static void
+rlivePoint (eBBlock ** ebbs, int count, bool emitWarnings)
 {
 {
-  iCode *ic;
-  bitVect *defsUsed = NULL;
-  bitVect *defsNotUsed = NULL;
-  int i;
+  int i, key;
+  eBBlock *succ;
+  bitVect *alive;
 
 
-  /* for all the instructions */
-  for (ic = ebp->sch; ic; ic = ic->next)
+  /* for all blocks do */
+  for (i = 0; i < count; i++)
     {
     {
-      if (ic->op == CALL || ic->op == PCALL)
-       {
-         setFromRange (IC_RESULT (ic), ic->seq);
-         /* if the result has no usage then 
-            mark this as the end of its life too 
-            and take it away from the defs for the block */
-         if (bitVectIsZero (OP_SYMBOL (IC_RESULT (ic))->uses))
-           {
-             setToRange (IC_RESULT (ic), ic->seq, FALSE);
-             bitVectUnSetBit (ebp->defSet, ic->key);
-           }
-       }
-
-      if (SKIP_IC2 (ic))
-       continue;
+      iCode *ic;
 
 
-      /* take care of the special icodes first */
-      if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
-       {
-         operandLUse (IC_JTCOND (ic), ebbs, count, ic, ebp);
-         continue;
-       }
+      /* for all instructions in this block do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
 
 
-      if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
-       {
-         operandLUse (IC_COND (ic), ebbs, count, ic, ebp);
-         continue;
-       }
+         if (!ic->rlive)
+           ic->rlive = newBitVect (operandKey);
 
 
-      if (IS_SYMOP (IC_LEFT (ic)))
-       operandLUse (IC_LEFT (ic), ebbs, count, ic, ebp);
+         if (SKIP_IC2(ic))
+           continue;
 
 
-      if (IS_SYMOP (IC_RIGHT (ic)))
-       operandLUse (IC_RIGHT (ic), ebbs, count, ic, ebp);
+         if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
+           {
+             incUsed (ic, IC_JTCOND(ic));
 
 
-      if (POINTER_SET (ic))
-       operandLUse (IC_RESULT (ic), ebbs, count, ic, ebp);
-      else if (IC_RESULT (ic))
-       ic->defKey = IC_RESULT (ic)->key;
-    }
+             if (!IS_AUTOSYM(IC_JTCOND(ic)))
+               continue;
 
 
+             findPrevUse (ebbs[i], ic, IC_JTCOND(ic), ebbs, count, emitWarnings);
+              if (IS_ITEMP(IC_JTCOND(ic)))
+                {
+                  unvisitBlocks(ebbs, count);
+                  ic->rlive = bitVectSetBit (ic->rlive, IC_JTCOND(ic)->key);
+                  findNextUse (ebbs[i], ic->next, IC_JTCOND(ic));
+                }
 
 
-  /* for all the definitions in the block */
-  /* compute and set the live from        */
-  if (ebp->ldefs && !bitVectIsZero (ebp->ldefs))
-    {
-      for (i = 0; i < ebp->ldefs->size; i++)
-       {
-         iCode *dic;
+             continue;
+           }
 
 
-         if (bitVectBitValue (ebp->ldefs, i) &&
-             (dic = hTabItemWithKey (iCodehTab, i)))
+         if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
            {
            {
+             incUsed (ic, IC_COND(ic));
+
+             if (!IS_AUTOSYM(IC_COND(ic)))
+               continue;
+
+             findPrevUse (ebbs[i], ic, IC_COND(ic), ebbs, count, emitWarnings);
+              if (IS_ITEMP(IC_COND(ic)))
+                {
+                  unvisitBlocks (ebbs, count);
+                  ic->rlive = bitVectSetBit (ic->rlive, IC_COND(ic)->key);
+                  findNextUse (ebbs[i], ic->next, IC_COND(ic));
+                }
 
 
-             /* if the definition has a from & it is greater */
-             /* than the defininng iCode->seq then change it */
-             setFromRange (IC_RESULT (dic), dic->seq);
+             continue;
            }
            }
-       }
-    }
 
 
-  /* special case for lastBlock in a loop: here we
-     mark the end of all the induction variables for the
-     loop */
-  if (ebp->isLastInLoop && !bitVectIsZero (ebp->linds))
-    {
-      for (i = 0; i <= ebp->linds->size; i++)
-       {
-         iCode *dic;
+         if (IS_SYMOP(IC_LEFT(ic)))
+           {
+             incUsed (ic, IC_LEFT(ic));
+             if (IS_AUTOSYM(IC_LEFT(ic)) &&
+                 ic->op != ADDRESS_OF)
+               {
+                 findPrevUse (ebbs[i], ic, IC_LEFT(ic), ebbs, count, emitWarnings);
+                  if (IS_ITEMP(IC_LEFT(ic)))
+                    {
+                      unvisitBlocks(ebbs, count);
+                      ic->rlive = bitVectSetBit (ic->rlive, IC_LEFT(ic)->key);
+                      findNextUse (ebbs[i], ic->next, IC_LEFT(ic));
+
+                      /* if this is a send extend the LR to the call */
+                      if (ic->op == SEND)
+                        {
+                          iCode *lic;
+                          for (lic = ic; lic; lic = lic->next)
+                            {
+                              if (lic->op == CALL || lic->op == PCALL)
+                                {
+                                  markAlive (ic, lic->prev, IC_LEFT (ic)->key);
+                                  break;
+                                }
+                            }
+                        }
+                    }
+               }
+           }
 
 
-         if (bitVectBitValue (ebp->linds, i) &&
-             (dic = hTabItemWithKey (iCodehTab, i)))
+         if (IS_SYMOP(IC_RIGHT(ic)))
            {
            {
+             incUsed (ic, IC_RIGHT(ic));
+              if (IS_AUTOSYM(IC_RIGHT(ic)))
+               {
+                 findPrevUse (ebbs[i], ic, IC_RIGHT(ic), ebbs, count, emitWarnings);
+                  if (IS_ITEMP(IC_RIGHT(ic)))
+                    {
+                      unvisitBlocks(ebbs, count);
+                      ic->rlive = bitVectSetBit (ic->rlive, IC_RIGHT(ic)->key);
+                      findNextUse (ebbs[i], ic->next, IC_RIGHT(ic));
+                    }
+               }
+           }
 
 
-             /* if this is a register equvalent make sure
-                it is not defined or used anywhere after the loop */
-             if (OP_SYMBOL (IC_RESULT (dic))->isreqv &&
-                 defUsedAfterLoop (IC_RESULT (dic), ebp->lSeq))
-               continue;
+         if (POINTER_SET(ic) && IS_SYMOP(IC_RESULT(ic)))
+           incUsed (ic, IC_RESULT(ic));
 
 
-             setToRange (IC_RESULT (dic), (ebp->lSeq), FALSE);
+          if (IS_AUTOSYM(IC_RESULT(ic)))
+           {
+             if (POINTER_SET(ic))
+               {
+                 findPrevUse (ebbs[i], ic, IC_RESULT(ic), ebbs, count, emitWarnings);
+               }
+              if (IS_ITEMP(IC_RESULT(ic)))
+                {
+                  unvisitBlocks(ebbs, count);
+                  ic->rlive = bitVectSetBit (ic->rlive, IC_RESULT(ic)->key);
+                  findNextUse (ebbs[i], ic->next, IC_RESULT(ic));
+                }
            }
            }
+
+         if (!POINTER_SET(ic) && IC_RESULT(ic))
+           ic->defKey = IC_RESULT(ic)->key;
+
        }
        }
-    }
 
 
-  /* for defnitions coming into the block if they */
-  /* not used by itself & any of its successors   */
-  /* they are dead */
-  /* first union the definitions used in all successors
-     and itself */
-  for (i = 0; i < count; ebbs[i++]->visited = 0);
-  applyToSet (ebp->succList, unionDefsUsed, &defsUsed);
-  defsUsed = bitVectUnion (defsUsed, ebp->usesDefs);
-
-  /* now subract the result of these unions from */
-  /* the incoming definitions this will give the */
-  /* definitions that are never used in the future */
-  defsNotUsed = bitVectCplAnd (bitVectCopy (ebp->inDefs),
-                              defsUsed);
-
-  /* mark the end of the defintions */
-  if (!bitVectIsZero (defsNotUsed) && ebp->sch)
-    {
-      for (i = 0; i < defsNotUsed->size; i++)
-       {
-         iCode *dic;
+      /* check all symbols that are alive in the last instruction */
+      /* but are not alive in all successors */
 
 
-         if (bitVectBitValue (defsNotUsed, i) &&
-             (dic = hTabItemWithKey (iCodehTab, i)))
-           {
-             setToRange (IC_RESULT (dic), (ebp->fSeq - 1), TRUE);
-           }
+      succ = setFirstItem (ebbs[i]->succList);
+      if (!succ)
+        continue;
+
+      alive = succ->sch->rlive;
+      while ((succ = setNextItem (ebbs[i]->succList)))
+        {
+         if (succ->sch)
+            alive = bitVectIntersect (alive, succ->sch->rlive);
        }
        }
-    }
 
 
+      if (ebbs[i]->ech)
+        alive = bitVectCplAnd ( bitVectCopy (ebbs[i]->ech->rlive), alive);
 
 
-  /* if we reach a lock with noPath to it then kill all
-     the live ranges alive at this point */
-/*     if (ebp->noPath || ebp->entryLabel == returnLabel) */
-  if (ebp->entryLabel == returnLabel)
-    killAllAlive (ebp->fSeq);
-}
+      if(!alive)
+        continue;
+      for (key = 1; key < alive->size; key++)
+        {
+         if (!bitVectBitValue (alive, key))
+           continue;
 
 
-/*-----------------------------------------------------------------*/
-/* rlivePoint - for each point compute the ranges that are alive   */
-/*-----------------------------------------------------------------*/
-void 
-rlivePoint (eBBlock ** ebbs, int count)
-{
-    int i;
-    
-    /* for all blocks do */
-    for (i = 0; i < count; i++) {
-       iCode *ic;
-       
-       /* for all instruction in the block do */
-       for (ic = ebbs[i]->sch; ic; ic = ic->next) {
-           symbol *lrange;
-           int k;
-           
-           ic->rlive = newBitVect (operandKey);
-           /* for all symbols in the liverange table */
-           for (lrange = hTabFirstItem (liveRanges, &k); lrange;
-                lrange = hTabNextItem (liveRanges, &k)) {
-               
-               /* if it is live then add the lrange to ic->rlive */
-               if (lrange->liveFrom <= ic->seq &&
-                   lrange->liveTo >= ic->seq) {
-                   lrange->isLiveFcall |= ((lrange->liveFrom < ic->seq) && 
-                                           (ic->op == CALL || ic->op == PCALL || ic->op == SEND));
-                   if (ic->op == CALL && lrange->liveFrom == ic->seq) continue;
-                   ic->rlive = bitVectSetBit (ic->rlive, lrange->key);
-               }
-           }
-#if 0
-           /* overlapping live ranges should be eliminated */
-           if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
-               if (SPIL_LOC(IC_RIGHT(ic)) == SPIL_LOC(IC_RESULT(ic))   && /* left & right share the same spil location */
-                   OP_SYMBOL(IC_RESULT(ic))->isreqv                    && /* left of assign is a register requivalent */
-                   !OP_SYMBOL(IC_RIGHT(ic))->isreqv                    && /* right side is not */
-                   OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->key           && /* right side live beyond this point */
-                   bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1 )        {  /* left has multiple definitions */
-                   SPIL_LOC(IC_RIGHT(ic)) = NULL; /* then cannot share */
-               }
-           }
-#endif
+         unvisitBlocks(ebbs, count);
+         findNextUseSym (ebbs[i], NULL, hTabItemWithKey (liveRanges, key));
        }
        }
+
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* computeClash - find out which live ranges collide with others   */
 /*-----------------------------------------------------------------*/
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* computeClash - find out which live ranges collide with others   */
 /*-----------------------------------------------------------------*/
-static void computeClash ()
+static void
+computeClash (eBBlock ** ebbs, int count)
 {
 {
-    hTab *lRangeCopy = newHashTable(hTabMaxKey(liveRanges));
-    void *item;
-    symbol *outer, *inner;
-    int key, key1;
-
-    /* have to make a copy of the liveRanges hashTable :: UGHH .*/
-    for (item = hTabFirstItem(liveRanges,&key); item ; 
-        item = hTabNextItem(liveRanges,&key)) {
-       hTabAddItem(&lRangeCopy,key,item);
-    }
-   
-    /* outerloop : for each liverange do */
-    for (outer = hTabFirstItem(liveRanges,&key); outer ; 
-        outer = hTabNextItem(liveRanges,&key)) {
-
-       /* if the liveFrom & To are the same then skip, 
-          could happen for unused return values from functions */
-       if (outer->liveFrom == outer->liveTo) continue;
-
-       /* innerloop : for the inner loop we can start from the
-          item after the outer loop */
-       inner = hTabFirstItemWK (lRangeCopy,outer->key);
-       inner = hTabNextItem (lRangeCopy,&key1 );
-       for (; inner ; inner = hTabNextItem( lRangeCopy ,&key1)) {
-
-           if (inner->liveFrom == inner->liveTo) continue;
-           if (inner->liveTo < outer->liveFrom)  continue;
-           if (inner->liveFrom > outer->liveTo)  continue;
-           
-           /* if one of them are being defined where the other
-              one end , then no overlap (i.e. they can goto same registers */
-           if (inner->liveFrom == outer->liveTo ||
-               outer->liveFrom == inner->liveTo) continue;
-
-           /* so they overlap : set both their clashes */
-           inner->clashes = bitVectSetBit(inner->clashes,outer->key);
-           outer->clashes = bitVectSetBit(outer->clashes,inner->key);
-
-           /* check if they share the same spillocation */
-           if (SYM_SPIL_LOC(inner) && SYM_SPIL_LOC(outer) && 
-               SYM_SPIL_LOC(inner) == SYM_SPIL_LOC(outer)) {
-               if (inner->reqv && !outer->reqv) SYM_SPIL_LOC(outer)=NULL;
-               else if (outer->reqv && !inner->reqv) SYM_SPIL_LOC(inner)=NULL;
-               else if (inner->used > outer->used) SYM_SPIL_LOC(outer)=NULL;
-               else SYM_SPIL_LOC(inner)=NULL;
-           }
+  int i;
+
+  /* for all blocks do */
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
 
 
+      /* for every iCode do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+       {
+         symbol *sym1, *sym2;
+         int key1, key2;
+
+         /* for all iTemps alive at this iCode */
+         for (key1 = 1; key1 < ic->rlive->size; key1++)
+           {
+             if (!bitVectBitValue(ic->rlive, key1))
+               continue;
+
+             sym1 = hTabItemWithKey(liveRanges, key1);
+
+             if (!sym1->isitmp)
+               continue;
+
+             /* for all other iTemps alive at this iCode */
+             for (key2 = key1+1; key2 < ic->rlive->size; key2++)
+               {
+                 if (!bitVectBitValue(ic->rlive, key2))
+                   continue;
+
+                 sym2 = hTabItemWithKey(liveRanges, key2);
+
+                 if (!sym2->isitmp)
+                   continue;
+
+                 /* if the result and left or right is an iTemp */
+                 /* than possibly the iTemps do not clash */
+                 if ((ic->op != JUMPTABLE) && (ic->op != IFX) &&
+                     IS_ITEMP(IC_RESULT(ic)) &&
+                     (IS_ITEMP(IC_LEFT(ic)) || IS_ITEMP(IC_RIGHT(ic))))
+                   {
+                     if (OP_SYMBOL(IC_RESULT(ic))->key == key1
+                         && sym1->liveFrom == ic->seq
+                         && sym2->liveTo == ic->seq)
+                       {
+                         if (IS_SYMOP(IC_LEFT(ic)))
+                           if (OP_SYMBOL(IC_LEFT(ic))->key == key2)
+                             continue;
+                         if (IS_SYMOP(IC_RIGHT(ic)))
+                           if (OP_SYMBOL(IC_RIGHT(ic))->key == key2)
+                             continue;
+                       }
+
+                     if (OP_SYMBOL(IC_RESULT(ic))->key == key2
+                         && sym2->liveFrom == ic->seq
+                         && sym1->liveTo == ic->seq)
+                       {
+                         if (IS_SYMOP(IC_LEFT(ic)))
+                           if (OP_SYMBOL(IC_LEFT(ic))->key == key1)
+                             continue;
+                         if (IS_SYMOP(IC_RIGHT(ic)))
+                           if (OP_SYMBOL(IC_RIGHT(ic))->key == key1)
+                             continue;
+                       }
+                   }
+
+                 /* the iTemps do clash. set the bits in clashes */
+                 sym1->clashes = bitVectSetBit (sym1->clashes, key2);
+                 sym2->clashes = bitVectSetBit (sym2->clashes, key1);
+
+                 /* check if they share the same spill location */
+                 /* what is this good for? */
+                 if (SYM_SPIL_LOC(sym1) && SYM_SPIL_LOC(sym2) &&
+                     SYM_SPIL_LOC(sym1) == SYM_SPIL_LOC(sym2))
+                   {
+                     if (sym1->reqv && !sym2->reqv) SYM_SPIL_LOC(sym2)=NULL;
+                     else if (sym2->reqv && !sym1->reqv) SYM_SPIL_LOC(sym1)=NULL;
+                     else if (sym1->used > sym2->used) SYM_SPIL_LOC(sym2)=NULL;
+                     else SYM_SPIL_LOC(sym1)=NULL;
+                   }
+               }
+           }
        }
     }
 }
        }
     }
 }
@@ -711,7 +788,6 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
       if (bitVectBitValue (defs, i) &&
          (ic = hTabItemWithKey (iCodehTab, i)) &&
          (ic->seq >= fseq && ic->seq <= toseq))
       if (bitVectBitValue (defs, i) &&
          (ic = hTabItemWithKey (iCodehTab, i)) &&
          (ic->seq >= fseq && ic->seq <= toseq))
-
        return FALSE;
 
     }
        return FALSE;
 
     }
@@ -730,40 +806,131 @@ notUsedInBlock (symbol * sym, eBBlock * ebp, iCode *ic)
          allDefsOutOfRange (sym->uses, ebp->fSeq, ebp->lSeq));
 }
 
          allDefsOutOfRange (sym->uses, ebp->fSeq, ebp->lSeq));
 }
 
+/*-----------------------------------------------------------------*/
+/* adjustIChain - correct the sch and ech pointers                 */
+/*-----------------------------------------------------------------*/
+static void
+adjustIChain (eBBlock ** ebbs, int count)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
+
+      if (ebbs[i]->noPath)
+        continue;
+
+      ic = ebbs[i]->sch;
+
+      /* is there any code for this eBBlock? (e.g. ROM assignment) */
+      if(!ic)continue;
+
+      while (ic->prev)
+        ic = ic->prev;
+      ebbs[i]->sch = ic;
+
+      ic = ebbs[i]->ech;
+      while (ic->next)
+        ic = ic->next;
+      ebbs[i]->ech = ic;
+    }
+}
 
 /*-----------------------------------------------------------------*/
 /* computeLiveRanges - computes the live ranges for variables      */
 /*-----------------------------------------------------------------*/
 void
 
 /*-----------------------------------------------------------------*/
 /* computeLiveRanges - computes the live ranges for variables      */
 /*-----------------------------------------------------------------*/
 void
-computeLiveRanges (eBBlock ** ebbs, int count)
+computeLiveRanges (eBBlock ** ebbs, int count, bool emitWarnings)
 {
 {
-  int i = 0;
+  /* first look through all blocks and adjust the
+     sch and ech pointers */
+  adjustIChain (ebbs, count);
+
   /* sequence the code the live ranges are computed
      in terms of this sequence additionally the
      routine will also create a hashtable of instructions */
   iCodeSeq = 0;
   /* sequence the code the live ranges are computed
      in terms of this sequence additionally the
      routine will also create a hashtable of instructions */
   iCodeSeq = 0;
-  setToNull ((void **) &iCodehTab);
+  setToNull ((void *) &iCodehTab);
   iCodehTab = newHashTable (iCodeKey);
   iCodehTab = newHashTable (iCodeKey);
-  setToNull ((void **) &iCodeSeqhTab);
+  hashiCodeKeys (ebbs, count);
+  setToNull ((void *) &iCodeSeqhTab);
   iCodeSeqhTab = newHashTable (iCodeKey);
   sequenceiCode (ebbs, count);
 
   iCodeSeqhTab = newHashTable (iCodeKey);
   sequenceiCode (ebbs, count);
 
-  if (getenv ("SDCC_LRKLAUS"))
+  /* mark the ranges live for each point */
+  setToNull ((void *) &liveRanges);
+  rlivePoint (ebbs, count, emitWarnings);
+
+  /* mark the from & to live ranges for variables used */
+  markLiveRanges (ebbs, count);
+
+  /* compute which overlaps with what */
+  computeClash(ebbs, count);
+}
+
+/*-----------------------------------------------------------------*/
+/* recomputeLiveRanges - recomputes the live ranges for variables  */
+/*-----------------------------------------------------------------*/
+void
+recomputeLiveRanges (eBBlock ** ebbs, int count)
+{
+  symbol * sym;
+  int key;
+
+  /* clear all rlive bitVectors */
+  rliveClear (ebbs, count);
+
+  sym = hTabFirstItem (liveRanges, &key);
+  if (sym)
     {
     {
-      /* add blocks between loop blocks as part of that loop */
-      addLoopBlocks (ebbs, count);
+      do {
+        sym->used = 0;
+        sym->liveFrom = 0;
+        sym->liveTo = 0;
+        freeBitVect (sym->clashes);
+        sym->clashes = NULL;
+      } while ( (sym = hTabNextItem (liveRanges, &key)));
     }
 
     }
 
-  /* call routine to mark the from & to live ranges for
-     variables used */
-  setToNull ((void **) &liveRanges);
+  /* do the LR computation again */
+  computeLiveRanges (ebbs, count, FALSE);
+}
+
+/*-----------------------------------------------------------------*/
+/* dump icode->rlive in all blocks                                 */
+/*-----------------------------------------------------------------*/
+#if 0
+void
+dumpIcRlive (eBBlock ** ebbs, int count)
+{
+  int i, j;
+  iCode *ic;
+
+  /* for all blocks do */
   for (i = 0; i < count; i++)
   for (i = 0; i < count; i++)
-    markLiveRanges (ebbs[i], ebbs, count);
+    {
+      printf ("bb %d %s alive symbols:\n", i, ebbs[i]->entryLabel->name);
+      /* for all instructions in this block do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+        {
+          printf ("\tic->key %d\n", ic->key);
 
 
-  /* mark the ranges live for each point */
-  rlivePoint (ebbs, count);
+          if (!ic->rlive)
+            continue;
+          /* for all live Ranges alive at this point */
+          for (j = 1; j < ic->rlive->size; j++)
+            {
+              symbol *sym;
 
 
-  /* compute which overlaps with what */
-  computeClash();
-}
+              if (!bitVectBitValue (ic->rlive, j))
+                continue;
 
 
+              /* find the live range we are interested in */
+              if ((sym = hTabItemWithKey (liveRanges, j)))
+                printf ("\t\tsym->key %2d: %s\n", sym->key, sym->rname[0] ? sym->rname : sym->name);
+            }
+        }
+    }
+}
+#endif