mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
[qfcc] Add killer node to replacement node's edges
When an operand refers to a killed node, it needs to be evaluated AFTER the killing node is evaluated. This fixes the double-alias bug.
This commit is contained in:
parent
4c79c9ffaf
commit
199b3e82d9
2 changed files with 19 additions and 10 deletions
|
@ -59,7 +59,7 @@ typedef struct dagnode_s {
|
|||
int topo; ///< topological sort order
|
||||
struct set_s *parents; ///< empty if root node
|
||||
int cost; ///< cost of this node in temp vars
|
||||
unsigned killed:1; ///< node is unavailable for cse
|
||||
struct dagnode_s *killed; ///< node is unavailable for cse (by node)
|
||||
st_type_t type; ///< type of node (st_none = leaf)
|
||||
daglabel_t *label; ///< ident/const if leaf node, or operator
|
||||
struct type_s *tl;
|
||||
|
|
|
@ -239,8 +239,6 @@ dag_node (operand_t *op)
|
|||
if (op->o.label->daglabel)
|
||||
node = op->o.label->daglabel->dagnode;
|
||||
}
|
||||
if (node && node->killed)
|
||||
node = 0;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -266,8 +264,19 @@ dag_make_children (dag_t *dag, statement_t *s,
|
|||
|
||||
flow_analyze_statement (s, 0, 0, 0, operands);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!(children[i] = dag_node (operands[i + 1])))
|
||||
children[i] = leaf_node (dag, operands[i + 1], s->expr);
|
||||
dagnode_t *node = dag_node (operands[i + 1]);
|
||||
dagnode_t *killer = 0;
|
||||
if (node && node->killed) {
|
||||
killer = node->killed;
|
||||
node = 0;
|
||||
}
|
||||
if (!node) {
|
||||
node = leaf_node (dag, operands[i + 1], s->expr);
|
||||
}
|
||||
if (killer) {
|
||||
set_add (node->edges, killer->number);
|
||||
}
|
||||
children[i] = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,7 +482,7 @@ static int
|
|||
dag_tempop_kill_aliases_visit (tempop_t *tempop, void *_l)
|
||||
{
|
||||
daglabel_t *l = (daglabel_t *) _l;
|
||||
dagnode_t *node = l->dagnode;;
|
||||
dagnode_t *node = l->dagnode;
|
||||
daglabel_t *label;
|
||||
|
||||
if (tempop == &l->op->o.tempop)
|
||||
|
@ -482,7 +491,7 @@ dag_tempop_kill_aliases_visit (tempop_t *tempop, void *_l)
|
|||
if (label && label->dagnode) {
|
||||
set_add (node->edges, label->dagnode->number);
|
||||
set_remove (node->edges, node->number);
|
||||
label->dagnode->killed = 1;
|
||||
label->dagnode->killed = node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -500,7 +509,7 @@ dag_def_kill_aliases_visit (def_t *def, void *_l)
|
|||
if (label && label->dagnode) {
|
||||
set_add (node->edges, label->dagnode->number);
|
||||
set_remove (node->edges, node->number);
|
||||
label->dagnode->killed = 1;
|
||||
label->dagnode->killed = node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -584,7 +593,7 @@ dagnode_attach_label (dagnode_t *n, daglabel_t *l)
|
|||
// if the node is a leaf, then kill its value so no attempt is made
|
||||
// to reuse it.
|
||||
if (l->dagnode->type == st_none) {
|
||||
l->dagnode->killed = 1;
|
||||
l->dagnode->killed = n;
|
||||
}
|
||||
dagnode_t *node = l->dagnode;
|
||||
set_union (n->edges, node->parents);
|
||||
|
@ -707,7 +716,7 @@ dag_kill_nodes (dag_t *dag, dagnode_t *n)
|
|||
// operations.
|
||||
continue;
|
||||
}
|
||||
node->killed = 1;
|
||||
node->killed = n;
|
||||
}
|
||||
n->killed = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue