[qfcc] Correctly check for constant op

Identifiers can be constants. I don't remember quite what it fixed other
than some bogus kill relations in the dags (which might have caused
issues later).
This commit is contained in:
Bill Currie 2021-06-28 20:25:26 +09:00
parent 38a6ccdc85
commit d50f2c3145

View file

@ -467,6 +467,8 @@ dagnode_set_edges (dag_t *dag, dagnode_t *n)
static int static int
op_is_identifier (operand_t *op) op_is_identifier (operand_t *op)
{ {
if (!op)
return 0;
if (op->op_type == op_label) if (op->op_type == op_label)
return 0; return 0;
if (op->op_type == op_value) if (op->op_type == op_value)
@ -478,6 +480,28 @@ op_is_identifier (operand_t *op)
return 1; return 1;
} }
static int
op_is_constant (operand_t *op)
{
if (!op)
return 0;
if (op->op_type == op_label)
return 1;
if (op->op_type == op_value)
return 1;
if (op->op_type == op_label)
return op->o.def->constant;
return 0;
}
static int
op_is_temp (operand_t *op)
{
if (!op)
return 0;
return op->op_type == op_temp;
}
static int static int
dag_tempop_kill_aliases_visit (tempop_t *tempop, void *_l) dag_tempop_kill_aliases_visit (tempop_t *tempop, void *_l)
{ {
@ -488,7 +512,7 @@ dag_tempop_kill_aliases_visit (tempop_t *tempop, void *_l)
if (tempop == &l->op->o.tempop) if (tempop == &l->op->o.tempop)
return 0; return 0;
label = tempop->daglabel; label = tempop->daglabel;
if (label && label->dagnode) { if (label && label->dagnode && !label->dagnode->killed) {
set_add (node->edges, label->dagnode->number); set_add (node->edges, label->dagnode->number);
set_remove (node->edges, node->number); set_remove (node->edges, node->number);
label->dagnode->killed = node; label->dagnode->killed = node;
@ -506,7 +530,7 @@ dag_def_kill_aliases_visit (def_t *def, void *_l)
if (def == l->op->o.def) if (def == l->op->o.def)
return 0; return 0;
label = def->daglabel; label = def->daglabel;
if (label && label->dagnode) { if (label && label->dagnode && !label->dagnode->killed) {
set_add (node->edges, label->dagnode->number); set_add (node->edges, label->dagnode->number);
set_remove (node->edges, node->number); set_remove (node->edges, node->number);
label->dagnode->killed = node; label->dagnode->killed = node;
@ -703,19 +727,28 @@ dag_kill_nodes (dag_t *dag, dagnode_t *n)
for (i = 0; i < dag->num_nodes; i++) { for (i = 0; i < dag->num_nodes; i++) {
node = dag->nodes[i]; node = dag->nodes[i];
if (node->killed) {
//the node is already killed
continue;
}
if (node == n->children[1]) { if (node == n->children[1]) {
// assume the pointer does not point to itself. This should be // assume the pointer does not point to itself. This should be
// reasonable because without casting, only a void pointer can // reasonable because without casting, only a void pointer can
// point to itself (the required type is recursive). // point to itself (the required type is recursive).
continue; continue;
} }
if (node->label->op && !op_is_identifier (node->label->op)) { if (op_is_constant (node->label->op)) {
// While constants in the Quake VM can be changed via a pointer, // While constants in the Quake VM can be changed via a pointer,
// doing so would cause much more fun than a simple // doing so would cause much more fun than a simple
// mis-optimization would, so consider them safe from pointer // mis-optimization would, so consider them safe from pointer
// operations. // operations.
continue; continue;
} }
if (op_is_temp (node->label->op)) {
// Assume that the pointer cannot point to a temporary variable.
// This is reasonable as there is no programmer access to temps.
continue;
}
node->killed = n; node->killed = n;
} }
n->killed = 0; n->killed = 0;