mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
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:
parent
a22260030a
commit
dc9d2a982e
3 changed files with 59 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue