more about genUnpackBits
[fw/sdcc] / src / SDCClrange.c
index 0c6fbc78f449a1c62917ba91020f205a4a73a958..194d37a22bdad0b642bb2adfc8aec7306e9fb9f9 100644 (file)
@@ -321,8 +321,104 @@ 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;
+  eBBlock * pred;
+
+  /* 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 (!ic)
+    {
+      /* We are at the start of a block. If the operand is alive at the */
+      /* end of all predecessors, then a previous call to findNextUse() */
+      /* has already taken care of everything. */
+      
+      pred = setFirstItem (ebp->predList);
+      for (; pred; pred = setNextItem (ebp->predList))
+        if (pred->ech && !bitVectBitValue(pred->ech->rlive, op->key))
+          break;
+      
+      if (!pred)
+        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 +483,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 +498,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 +512,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));
@@ -432,6 +531,8 @@ rlivePoint (eBBlock ** ebbs, int count)
                        }
                    }
                }
+//                fprintf(stderr, "%s:%d IS_SYMOP left\t", __FILE__, __LINE__);printOperand(IC_LEFT(ic), stderr);
+//                fprintf(stderr, "\n");
            }
 
          if (IS_SYMOP(IC_RIGHT(ic)))
@@ -439,10 +540,13 @@ 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));
                }
+//                fprintf(stderr, "%s:%d IS_SYMOP right\t", __FILE__, __LINE__);printOperand(IC_RIGHT(ic), stderr);
+//                fprintf(stderr, "\n");
            }
 
          if (POINTER_SET(ic) && IS_SYMOP(IC_RESULT(ic)))
@@ -450,6 +554,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));