* src/mcs51/ralloc.c (deassignLR),
[fw/sdcc] / src / SDCClrange.c
index 0c6fbc78f449a1c62917ba91020f205a4a73a958..31a678b2d86f8ee48ff0487dc112bb835fe357b5 100644 (file)
@@ -321,8 +321,88 @@ void unvisitBlocks (eBBlock ** ebbs, int count)
     ebbs[i]->visited = 0;
 }
 
+/*------------------------------------------------------------------*/
+/* findRecursiveSucc - build a bit vector of recursive successors   */
+/*------------------------------------------------------------------*/
+DEFSETFUNC (findRecursiveSucc)
+{
+  eBBlock *ebp = item;
+  V_ARG (bitVect *, succVect);
+  
+  if (ebp->visited)
+    return 0;
+  
+  ebp->visited = 1;
+  bitVectSetBit (succVect, ebp->bbnum);
+  applyToSet (ebp->succList, findRecursiveSucc, succVect);
+  return 0;
+}
+
+
+/*------------------------------------------------------------------*/
+/* findRecursivePred - build a bit vector of recursive predecessors */
+/*------------------------------------------------------------------*/
+DEFSETFUNC (findRecursivePred)
+{
+  eBBlock *ebp = item;
+  V_ARG (bitVect *, predVect);
+  
+  if (ebp->visited)
+    return 0;
+  
+  ebp->visited = 1;
+  bitVectSetBit (predVect, ebp->bbnum);
+  applyToSet (ebp->predList, findRecursivePred, predVect);
+  return 0;
+}
+
+
+/*------------------------------------------------------------------*/
+/* findPrevUse - handle degenerate case of a symbol used prior to   */
+/*               findNextUse() marking any definition.              */
+/*------------------------------------------------------------------*/
+void
+findPrevUse (eBBlock *ebp, iCode *ic, operand *op, eBBlock **ebbs, int count)
+{
+  int i;
+  bitVect * succVect;
+  bitVect * predVect;
+  
+  /* If liveness is already known, then a previous call to findNextUse() */
+  /* has already taken care of everything. */
+  if (ic && bitVectBitValue(ic->rlive, op->key))
+    return;
+  
+  if (op->isaddr)
+    OP_SYMBOL (op)->isptr = 1;
+
+  OP_SYMBOL (op)->key = op->key;
+  
+  /* Otherwise, it appears that this symbol was used prior to definition.     */
+  /* Just fix the live range; we'll deal with a diagnostic message elsewhere. */
+  /* If the symbol use was in a loop, we need to extend the live range to the */
+  /* outermost loop. */
+  unvisitBlocks (ebbs, count);
+  succVect = newBitVect (count);
+  applyToSet (ebp->succList, findRecursiveSucc, succVect);
+  unvisitBlocks (ebbs, count);
+  predVect = newBitVect (count);
+  applyToSet (ebp->predList, findRecursivePred, predVect);
+  
+  /* Blocks that are both recursively predecessors and successors are in */
+  /* a loop with the current iCode. Mark the operand as alive in them.   */
+  for (i = 0; i < count; i++)
+    {
+      if (bitVectBitValue(succVect, i) && bitVectBitValue(predVect, i))
+        markAlive (ebbs[i]->sch, ebbs[i]->ech, op->key);
+    }
+  
+  freeBitVect (succVect);
+  freeBitVect (predVect);
+}
+
 /*-----------------------------------------------------------------*/
-/* unvisitBlocks - clears visited in all blocks                    */
+/* incUsed - increment a symbol's usage count                      */
 /*-----------------------------------------------------------------*/
 void
 incUsed (iCode *ic, operand *op)
@@ -387,6 +467,7 @@ rlivePoint (eBBlock ** ebbs, int count)
              if (!IS_ITEMP(IC_JTCOND(ic)))
                continue;
 
+             findPrevUse (ebbs[i], ic->prev, IC_JTCOND(ic), ebbs, count);
              unvisitBlocks(ebbs, count);
              ic->rlive = bitVectSetBit (ic->rlive, IC_JTCOND(ic)->key);
              findNextUse (ebbs[i], ic->next, IC_JTCOND(ic));
@@ -401,6 +482,7 @@ rlivePoint (eBBlock ** ebbs, int count)
              if (!IS_ITEMP(IC_COND(ic)))
                continue;
 
+             findPrevUse (ebbs[i], ic->prev, IC_COND(ic), ebbs, count);
              unvisitBlocks (ebbs, count);
              ic->rlive = bitVectSetBit (ic->rlive, IC_COND(ic)->key);
              findNextUse (ebbs[i], ic->next, IC_COND(ic));
@@ -414,6 +496,7 @@ rlivePoint (eBBlock ** ebbs, int count)
              if (IS_ITEMP(IC_LEFT(ic)))
                {
 
+                 findPrevUse (ebbs[i], ic->prev, IC_LEFT(ic), ebbs, count);
                  unvisitBlocks(ebbs, count);
                  ic->rlive = bitVectSetBit (ic->rlive, IC_LEFT(ic)->key);
                  findNextUse (ebbs[i], ic->next, IC_LEFT(ic));
@@ -439,6 +522,7 @@ rlivePoint (eBBlock ** ebbs, int count)
              incUsed (ic, IC_RIGHT(ic));
              if (IS_ITEMP(IC_RIGHT(ic)))
                {
+                 findPrevUse (ebbs[i], ic->prev, IC_RIGHT(ic), ebbs, count);
                  unvisitBlocks(ebbs, count);
                  ic->rlive = bitVectSetBit (ic->rlive, IC_RIGHT(ic)->key);
                  findNextUse (ebbs[i], ic->next, IC_RIGHT(ic));
@@ -450,6 +534,10 @@ rlivePoint (eBBlock ** ebbs, int count)
 
          if (IS_ITEMP(IC_RESULT(ic)))
            {
+             if (POINTER_SET(ic))
+               {
+                 findPrevUse (ebbs[i], ic->prev, IC_RESULT(ic), ebbs, count);
+               }
              unvisitBlocks(ebbs, count);
              ic->rlive = bitVectSetBit (ic->rlive, IC_RESULT(ic)->key);
              findNextUse (ebbs[i], ic->next, IC_RESULT(ic));