mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Delay creation of leaf nodes
Creating leaf nodes early gets in the way of supporting multi-call basic blocks, and never really seemed right anyway.
This commit is contained in:
parent
6d6a387a81
commit
03b2ee2a25
1 changed files with 99 additions and 121 deletions
|
@ -248,6 +248,33 @@ opcode_label (dag_t *dag, const char *opcode, const expr_t *expr)
|
|||
return label;
|
||||
}
|
||||
|
||||
static __attribute__((pure)) dagnode_t *
|
||||
dag_node (operand_t *op)
|
||||
{
|
||||
def_t *def;
|
||||
dagnode_t *node = 0;
|
||||
|
||||
if (!op)
|
||||
return 0;
|
||||
if (op->op_type == op_def) {
|
||||
def = op->def;
|
||||
if (def->daglabel)
|
||||
node = def->daglabel->dagnode;
|
||||
} else if (op->op_type == op_temp) {
|
||||
if (op->tempop.daglabel)
|
||||
node = op->tempop.daglabel->dagnode;
|
||||
} else if (op->op_type == op_value) {
|
||||
if (op->value->daglabel)
|
||||
node = op->value->daglabel->dagnode;
|
||||
} else if (op->op_type == op_label) {
|
||||
if (op->label->daglabel)
|
||||
node = op->label->daglabel->dagnode;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static dagnode_t *leaf_node (dag_t *dag, operand_t *op, const expr_t *expr);
|
||||
|
||||
static daglabel_t *
|
||||
operand_label (dag_t *dag, operand_t *op)
|
||||
{
|
||||
|
@ -266,6 +293,11 @@ operand_label (dag_t *dag, operand_t *op)
|
|||
label = new_label (dag);
|
||||
label->op = op;
|
||||
op->tempop.daglabel = label;
|
||||
if (op->tempop.alias) {
|
||||
if (!dag_node (op->tempop.alias)) {
|
||||
leaf_node (dag, op->tempop.alias, op->expr);
|
||||
}
|
||||
}
|
||||
} else if (op->op_type == op_def) {
|
||||
def = op->def;
|
||||
if (def->daglabel)
|
||||
|
@ -309,31 +341,6 @@ leaf_node (dag_t *dag, operand_t *op, const expr_t *expr)
|
|||
return node;
|
||||
}
|
||||
|
||||
static __attribute__((pure)) dagnode_t *
|
||||
dag_node (operand_t *op)
|
||||
{
|
||||
def_t *def;
|
||||
dagnode_t *node = 0;
|
||||
|
||||
if (!op)
|
||||
return 0;
|
||||
if (op->op_type == op_def) {
|
||||
def = op->def;
|
||||
if (def->daglabel)
|
||||
node = def->daglabel->dagnode;
|
||||
} else if (op->op_type == op_temp) {
|
||||
if (op->tempop.daglabel)
|
||||
node = op->tempop.daglabel->dagnode;
|
||||
} else if (op->op_type == op_value) {
|
||||
if (op->value->daglabel)
|
||||
node = op->value->daglabel->dagnode;
|
||||
} else if (op->op_type == op_label) {
|
||||
if (op->label->daglabel)
|
||||
node = op->label->daglabel->dagnode;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static int
|
||||
dagnode_deref_match (const dagnode_t *n, const dagnode_t *search)
|
||||
{
|
||||
|
@ -387,19 +394,6 @@ dagnode_search (dag_t *dag, const dagnode_t *search)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dag_make_leafs (dag_t *dag, statement_t *s, operand_t *operands[FLOW_OPERANDS])
|
||||
{
|
||||
int i;
|
||||
|
||||
flow_analyze_statement (s, 0, 0, 0, operands);
|
||||
for (i = 1; i < FLOW_OPERANDS; i++) {
|
||||
if (!dag_node (operands[i])) {
|
||||
leaf_node (dag, operands[i], s->expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dagnode_set_reachable (dag_t *dag, dagnode_t *node)
|
||||
{
|
||||
|
@ -414,24 +408,9 @@ dagnode_set_reachable (dag_t *dag, dagnode_t *node)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dag_make_children (dag_t *dag, statement_t *s,
|
||||
operand_t *operands[FLOW_OPERANDS],
|
||||
dagnode_t *children[3])
|
||||
static dagnode_t *
|
||||
dag_make_child (dag_t *dag, operand_t *op, statement_t *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
flow_analyze_statement (s, 0, 0, 0, operands);
|
||||
if (!operands[0] && s->def) {
|
||||
auto op = s->def;
|
||||
while (op && op->op_type == op_pseudo) {
|
||||
op = op->next;
|
||||
}
|
||||
//FIXME hopefully only one non-pseudo op
|
||||
operands[0] = op;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
operand_t *op = operands[i + 1];
|
||||
dagnode_t *node = dag_node (op);
|
||||
dagnode_t *killer = 0;
|
||||
|
||||
|
@ -489,7 +468,28 @@ dag_make_children (dag_t *dag, statement_t *s,
|
|||
// updating the reachable sets of any parent nodes.
|
||||
dagnode_set_reachable (dag, node);
|
||||
}
|
||||
children[i] = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
dag_make_children (dag_t *dag, statement_t *s,
|
||||
operand_t *operands[FLOW_OPERANDS],
|
||||
dagnode_t *children[3])
|
||||
{
|
||||
int i;
|
||||
|
||||
flow_analyze_statement (s, 0, 0, 0, operands);
|
||||
if (!operands[0] && s->def) {
|
||||
auto op = s->def;
|
||||
while (op && op->op_type == op_pseudo) {
|
||||
op = op->next;
|
||||
}
|
||||
//FIXME hopefully only one non-pseudo op
|
||||
operands[0] = op;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
operand_t *op = operands[i + 1];
|
||||
children[i] = dag_make_child (dag, op, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,10 +594,10 @@ dagnode_set_edges (dag_t *dag, dagnode_t *n, statement_t *s)
|
|||
if (use->op_type == op_pseudo) {
|
||||
continue;
|
||||
}
|
||||
daglabel_t *label = operand_label (dag, use);
|
||||
label->live = 1;
|
||||
auto u = dag_make_child (dag, use, s);
|
||||
u->label->live = 1;
|
||||
dag_live_aliases (use);
|
||||
set_add (n->edges, label->dagnode->number);
|
||||
set_add (n->edges, u->number);
|
||||
}
|
||||
if (n->type == st_func) {
|
||||
const char *num_params = 0;
|
||||
|
@ -938,19 +938,6 @@ dag_count_ops (operand_t *op)
|
|||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
dag_make_op_leafs (operand_t *op, dag_t *dag, const expr_t *expr)
|
||||
{
|
||||
for (; op; op = op->next) {
|
||||
if (op->op_type == op_pseudo) {
|
||||
continue;
|
||||
}
|
||||
if (!dag_node (op)) {
|
||||
leaf_node (dag, op, expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dag_free_set (set_t **set)
|
||||
{
|
||||
|
@ -1031,15 +1018,6 @@ dag_create (flownode_t *flownode)
|
|||
dag->labels = alloca (num_lables * sizeof (daglabel_t));
|
||||
dag->roots = set_new ();
|
||||
|
||||
// do a first pass to ensure all operands have an "x_0" leaf node
|
||||
// prior do actual dag creation
|
||||
for (s = block->statements; s; s = s->next) {
|
||||
operand_t *operands[FLOW_OPERANDS];
|
||||
dag_make_leafs (dag, s, operands);
|
||||
// make sure any auxiliary operands are given nodes, too
|
||||
dag_make_op_leafs (s->use, dag, s->expr);
|
||||
dag_make_op_leafs (s->def, dag, s->expr);
|
||||
}
|
||||
// actual dag creation
|
||||
for (s = block->statements; s; s = s->next) {
|
||||
operand_t *operands[FLOW_OPERANDS];
|
||||
|
|
Loading…
Reference in a new issue