mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-13 11:01:12 +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 *next;
|
||||||
struct daglabel_s **prev;
|
struct daglabel_s **prev;
|
||||||
//@}
|
//@}
|
||||||
|
struct daglabel_s *daglabel_chain; ///< all labels created for a dag
|
||||||
const char *opcode; ///< not if op
|
const char *opcode; ///< not if op
|
||||||
struct operand_s *op; ///< not if opcode;
|
struct operand_s *op; ///< not if opcode;
|
||||||
struct dagnode_s *dagnode; ///< node with which this label is associated
|
struct dagnode_s *dagnode; ///< node with which this label is associated
|
||||||
|
@ -49,6 +50,7 @@ typedef struct daglabel_s {
|
||||||
typedef struct dagnode_s {
|
typedef struct dagnode_s {
|
||||||
struct dagnode_s *next;
|
struct dagnode_s *next;
|
||||||
int print_count; ///< used to avoid double printing nodes
|
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
|
daglabel_t *label; ///< ident/const if leaf node, or operator
|
||||||
/// \name child nodes
|
/// \name child nodes
|
||||||
/// All three child nodes will be null if this node is a leaf
|
/// All three child nodes will be null if this node is a leaf
|
||||||
|
|
|
@ -48,11 +48,37 @@
|
||||||
static daglabel_t *free_labels;
|
static daglabel_t *free_labels;
|
||||||
static dagnode_t *free_nodes;
|
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 *
|
static daglabel_t *
|
||||||
new_label (void)
|
new_label (void)
|
||||||
{
|
{
|
||||||
daglabel_t *label;
|
daglabel_t *label;
|
||||||
ALLOC (256, daglabel_t, labels, label);
|
ALLOC (256, daglabel_t, labels, label);
|
||||||
|
label->daglabel_chain = daglabel_chain;
|
||||||
|
daglabel_chain = label;
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +299,9 @@ make_dag (const sblock_t *block)
|
||||||
{
|
{
|
||||||
statement_t *s;
|
statement_t *s;
|
||||||
dagnode_t *dagnodes = 0;
|
dagnode_t *dagnodes = 0;
|
||||||
dagnode_t *dag = 0;
|
dagnode_t *d;
|
||||||
|
|
||||||
|
flush_daglabels ();
|
||||||
|
|
||||||
for (s = block->statements; s; s = s->next) {
|
for (s = block->statements; s; s = s->next) {
|
||||||
operand_t *x = 0, *y = 0, *z = 0, *w = 0;
|
operand_t *x = 0, *y = 0, *z = 0, *w = 0;
|
||||||
|
@ -282,8 +310,13 @@ make_dag (const sblock_t *block)
|
||||||
int simp;
|
int simp;
|
||||||
|
|
||||||
simp = find_operands (s, &x, &y, &z, &w);
|
simp = find_operands (s, &x, &y, &z, &w);
|
||||||
if (!(ny = node (y)))
|
if (!(ny = node (y))) {
|
||||||
ny = leaf_node (y);
|
ny = leaf_node (y);
|
||||||
|
if (simp) {
|
||||||
|
ny->next = dagnodes;
|
||||||
|
dagnodes = ny;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(nz = node (z)))
|
if (!(nz = node (z)))
|
||||||
nz = leaf_node (z);
|
nz = leaf_node (z);
|
||||||
if (!(nw = node (w)))
|
if (!(nw = node (w)))
|
||||||
|
@ -302,6 +335,12 @@ make_dag (const sblock_t *block)
|
||||||
n->a = ny;
|
n->a = ny;
|
||||||
n->b = nz;
|
n->b = nz;
|
||||||
n->c = nw;
|
n->c = nw;
|
||||||
|
if (ny)
|
||||||
|
ny->is_child = 1;
|
||||||
|
if (nz)
|
||||||
|
nz->is_child = 1;
|
||||||
|
if (nw)
|
||||||
|
nw->is_child = 1;
|
||||||
n->next = dagnodes;
|
n->next = dagnodes;
|
||||||
dagnodes = n;
|
dagnodes = n;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +350,6 @@ make_dag (const sblock_t *block)
|
||||||
daglabel_detatch (lx);
|
daglabel_detatch (lx);
|
||||||
dagnode_attach_label (n, lx);
|
dagnode_attach_label (n, lx);
|
||||||
}
|
}
|
||||||
dag = n;
|
|
||||||
// c = a * b
|
// c = a * b
|
||||||
// c = ~a
|
// c = ~a
|
||||||
// c = a / b
|
// c = a / b
|
||||||
|
@ -341,5 +379,17 @@ make_dag (const sblock_t *block)
|
||||||
// c = a ^ b
|
// c = a ^ b
|
||||||
// c = a (move) b (count)
|
// 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);
|
node->c);
|
||||||
print_node (dstr, 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,
|
dasprintf (dstr, " \"dag_%p\" [%slabel=\"%s\"];\n", node,
|
||||||
node->a ? "" : "shape=none,", daglabel_string (node->label));
|
node->a ? "" : "shape=none,", daglabel_string (node->label));
|
||||||
if (node->identifiers) {
|
if (node->identifiers) {
|
||||||
|
|
Loading…
Reference in a new issue