+ /*
+ * We now traverse the call tree depth first, assigning indices > startIdx
+ * to the registers of all called functions before assigning indices to
+ * the registers of the calling function, starting with one greater than
+ * the max. index used by any child function.
+ * This approach guarantees that, if f calls g, all registers of f have
+ * greater indices than those of g (also holds transitively).
+ *
+ * XXX: If a function f calls a function g in a different module,
+ * we should handle the case that g could call a function h
+ * in f's module.
+ * The consequence of this is that even though f and h might
+ * share registers (they do not call each other locally) when
+ * looking only at f's module, they actually must not do so!
+ *
+ * For a non-static function f, let ES(f) be the set of functions
+ * (including f) that can only be reached via f in the module-local
+ * call graph (ES(f) will hence be a subgraph).
+ * Let further REG(ES(f)) be the set of registers assigned to
+ * functions in ES(f).
+ * Then we should make sure that REG(ES(f)) and REG(ES(g)) are
+ * disjoint for all non-static functions f and g.
+ *
+ * Unfortunately, determining the sets ES(f) is non-trivial,
+ * so we ignore this problem and declare all modules non-reentrant.
+ * This is a bug.
+ */
+ pb->visited = 1;
+
+ DFPRINTF((stderr,
+ "%*s(%u) reassigning registers for functions called by \"%s\":base idx = %04x\n",
+ 4 * level, "", level, PCF(pc)->fname, startIdx));
+
+ for (pc = setFirstItem(pb->function_calls); pc; pc = setNextItem(pb->function_calls))
+ {
+ if (pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL)
+ {
+ char *dest = get_op_from_instruction(PCI(pc));
+ pCode *pcn = findFunction(dest);
+
+ if (pcn)
+ {
+ /*
+ * Reassign the registers of all called functions and record
+ * the max. index I used by any child function --> I+1 will be
+ * the first index available to this function.
+ * (Problem shown with regression test src/regression/sub2.c)
+ */
+ unsigned childsMaxIdx;
+ childsMaxIdx = register_reassign(pcn->pb,startIdx,level+1);
+ if (childsMaxIdx > idx)
+ idx = childsMaxIdx;
+ } // if
+ } // if
+ } // for