[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:
Bill Currie 2024-02-21 17:42:52 +09:00
parent 6d6a387a81
commit 03b2ee2a25

View file

@ -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];