+/*------------------------------------------------------------------*/
+/* 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)
+ {
+ /* already visited: this branch must have been succesfull, */
+ /* because otherwise the search would have been aborted. */
+ return TRUE;
+ }
+ ebp->visited = 1;
+
+ /* search backward in the current block */
+ for (uic = ic; uic; uic = uic->prev)
+ {
+ if (!POINTER_SET (uic) && IS_AUTOSYM (IC_RESULT (uic)))
+ {
+ if (IC_RESULT (uic)->key == sym->key)
+ {
+ /* Ok, found a definition */
+ return TRUE;
+ }
+ }
+ /* address taken from symbol? */
+ if (uic->op == ADDRESS_OF && IS_AUTOSYM (IC_LEFT (uic)))
+ {
+ if (IC_LEFT (uic)->key == sym->key)
+ {
+ /* Ok, found a definition */
+ return TRUE;
+ }
+ }
+ }
+
+ /* There's no definition in this bblock, */
+ /* let's have a look at all predecessors. */
+ pred = setFirstItem (ebp->predList);
+ if (!pred)
+ {
+ /* 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;
+ }
+ }
+
+ /* Success! Went through all branches with no abort: */
+ /* all branches end with a definition */
+ return TRUE;
+}
+
+/*------------------------------------------------------------------*/
+/* 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);
+
+ if (op->isaddr)
+ OP_SYMBOL (op)->isptr = 1;
+ OP_SYMBOL (op)->key = op->key;
+
+ /* 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);
+ }
+ }
+}
+