Make the returned dag a linked list of root-nodes.

A dag can have mulitple "root" nodes (ie, nodes with no parents).
This commit is contained in:
Bill Currie 2012-07-19 11:38:02 +09:00
parent a22260030a
commit dc9d2a982e
3 changed files with 59 additions and 4 deletions

View file

@ -41,6 +41,7 @@ typedef struct daglabel_s {
struct daglabel_s *next;
struct daglabel_s **prev;
//@}
struct daglabel_s *daglabel_chain; ///< all labels created for a dag
const char *opcode; ///< not if op
struct operand_s *op; ///< not if opcode;
struct dagnode_s *dagnode; ///< node with which this label is associated
@ -49,6 +50,7 @@ typedef struct daglabel_s {
typedef struct dagnode_s {
struct dagnode_s *next;
int print_count; ///< used to avoid double printing nodes
int is_child; ///< true if a child node
daglabel_t *label; ///< ident/const if leaf node, or operator
/// \name child nodes
/// All three child nodes will be null if this node is a leaf

View file

@ -48,11 +48,37 @@
static daglabel_t *free_labels;
static dagnode_t *free_nodes;
static daglabel_t *daglabel_chain;
static void
flush_daglabels (void)
{
while (daglabel_chain) {
operand_t *op;
if ((op = daglabel_chain->op)) {
while (op->op_type == op_alias)
op = op->o.alias;
if (op->op_type == op_symbol)
op->o.symbol->daglabel = 0;
else if (op->op_type == op_temp)
op->o.tempop.daglabel = 0;
else if (op->op_type == op_value || op->op_type == op_pointer)
op->o.value->daglabel = 0;
else
internal_error (0, "unexpected operand type");
}
daglabel_chain = daglabel_chain->daglabel_chain;
}
}
static daglabel_t *
new_label (void)
{
daglabel_t *label;
ALLOC (256, daglabel_t, labels, label);
label->daglabel_chain = daglabel_chain;
daglabel_chain = label;
return label;
}
@ -273,7 +299,9 @@ make_dag (const sblock_t *block)
{
statement_t *s;
dagnode_t *dagnodes = 0;
dagnode_t *dag = 0;
dagnode_t *d;
flush_daglabels ();
for (s = block->statements; s; s = s->next) {
operand_t *x = 0, *y = 0, *z = 0, *w = 0;
@ -282,8 +310,13 @@ make_dag (const sblock_t *block)
int simp;
simp = find_operands (s, &x, &y, &z, &w);
if (!(ny = node (y)))
if (!(ny = node (y))) {
ny = leaf_node (y);
if (simp) {
ny->next = dagnodes;
dagnodes = ny;
}
}
if (!(nz = node (z)))
nz = leaf_node (z);
if (!(nw = node (w)))
@ -302,6 +335,12 @@ make_dag (const sblock_t *block)
n->a = ny;
n->b = nz;
n->c = nw;
if (ny)
ny->is_child = 1;
if (nz)
nz->is_child = 1;
if (nw)
nw->is_child = 1;
n->next = dagnodes;
dagnodes = n;
}
@ -311,7 +350,6 @@ make_dag (const sblock_t *block)
daglabel_detatch (lx);
dagnode_attach_label (n, lx);
}
dag = n;
// c = a * b
// c = ~a
// c = a / b
@ -341,5 +379,17 @@ make_dag (const sblock_t *block)
// c = a ^ b
// c = a (move) b (count)
}
return dag;
while (dagnodes->is_child) {
dagnode_t *n = dagnodes->next;
dagnodes->next = 0;
dagnodes = n;
}
for (d = dagnodes; d && d->next; d = d->next) {
while (d->next && d->next->is_child) {
dagnode_t *n = d->next->next;
d->next->next = 0;
d->next = n;
}
}
return dagnodes;
}

View file

@ -75,6 +75,9 @@ print_node (dstring_t *dstr, dagnode_t *node)
node->c);
print_node (dstr, node->c);
}
if (node->next)
dasprintf (dstr, " \"dag_%p\" -> \"dag_%p\" [style=dashed];\n", node,
node->next);
dasprintf (dstr, " \"dag_%p\" [%slabel=\"%s\"];\n", node,
node->a ? "" : "shape=none,", daglabel_string (node->label));
if (node->identifiers) {