mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[qfcc] Avoid defining whole def via alias
A partial write to a def should not define the whole def, thus def_visit_all's overlap parameter now has a flag that prevents a visit to the main def when accessing the def from an alias def. This prevents a lot of spurious kills and defines in flow analysis.
This commit is contained in:
parent
008a64ee9b
commit
95dd63cd68
2 changed files with 15 additions and 19 deletions
|
@ -732,8 +732,9 @@ def_visit_all (def_t *def, int overlap,
|
||||||
return ret;
|
return ret;
|
||||||
if (def->alias) {
|
if (def->alias) {
|
||||||
def = def->alias;
|
def = def->alias;
|
||||||
if ((ret = visit (def, data)))
|
if (!(overlap & 4) && (ret = visit (def, data)))
|
||||||
return ret;
|
return ret;
|
||||||
|
overlap &= ~4;
|
||||||
} else {
|
} else {
|
||||||
overlap = 0;
|
overlap = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -760,7 +760,7 @@ flow_kill_aliases (set_t *kill, flowvar_t *var, const set_t *uninit)
|
||||||
if (op->op_type == op_temp) {
|
if (op->op_type == op_temp) {
|
||||||
tempop_visit_all (&op->tempop, 1, flow_tempop_kill_aliases, tmp);
|
tempop_visit_all (&op->tempop, 1, flow_tempop_kill_aliases, tmp);
|
||||||
} else if (op->op_type == op_def) {
|
} else if (op->op_type == op_def) {
|
||||||
def_visit_all (op->def, 1, flow_def_kill_aliases, tmp);
|
def_visit_all (op->def, 4 | 1, flow_def_kill_aliases, tmp);
|
||||||
}
|
}
|
||||||
// don't allow aliases to kill definitions in the entry dummy block
|
// don't allow aliases to kill definitions in the entry dummy block
|
||||||
if (uninit) {
|
if (uninit) {
|
||||||
|
@ -1153,10 +1153,9 @@ flow_def_add_aliases (def_t *def, void *_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flow_add_op_var (set_t *set, operand_t *op, int is_use)
|
flow_add_op_var (set_t *set, operand_t *op, int ol)
|
||||||
{
|
{
|
||||||
flowvar_t *var;
|
flowvar_t *var;
|
||||||
int ol = is_use ? 1 : 2;
|
|
||||||
|
|
||||||
if (!set)
|
if (!set)
|
||||||
return;
|
return;
|
||||||
|
@ -1164,10 +1163,6 @@ flow_add_op_var (set_t *set, operand_t *op, int is_use)
|
||||||
return;
|
return;
|
||||||
set_add (set, var->number);
|
set_add (set, var->number);
|
||||||
|
|
||||||
// FIXME XXX I think the curent implementation will have problems
|
|
||||||
// for the def set when assigning to an alias as right now the real
|
|
||||||
// var is being treated as assigned as well. Want to handle partial
|
|
||||||
// defs properly, but I am as yet uncertain of how.
|
|
||||||
if (op->op_type == op_temp) {
|
if (op->op_type == op_temp) {
|
||||||
tempop_visit_all (&op->tempop, ol, flow_tempop_add_aliases, set);
|
tempop_visit_all (&op->tempop, ol, flow_tempop_add_aliases, set);
|
||||||
} else if (op->op_type == op_def) {
|
} else if (op->op_type == op_def) {
|
||||||
|
@ -1191,7 +1186,7 @@ flow_analyze_pointer_operand (operand_t *ptrop, set_t *def)
|
||||||
op = ptrop->value->v.pointer.tempop;
|
op = ptrop->value->v.pointer.tempop;
|
||||||
}
|
}
|
||||||
if (op) {
|
if (op) {
|
||||||
flow_add_op_var (def, op, 0);
|
flow_add_op_var (def, op, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return op;
|
return op;
|
||||||
|
@ -1217,13 +1212,13 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
if (def) {
|
if (def) {
|
||||||
set_empty (def);
|
set_empty (def);
|
||||||
for (operand_t *op = s->def; op; op = op->next) {
|
for (operand_t *op = s->def; op; op = op->next) {
|
||||||
flow_add_op_var (def, op, 0);
|
flow_add_op_var (def, op, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kill) {
|
if (kill) {
|
||||||
set_empty (kill);
|
set_empty (kill);
|
||||||
for (operand_t *op = s->kill; op; op = op->next) {
|
for (operand_t *op = s->kill; op; op = op->next) {
|
||||||
flow_add_op_var (kill, op, 0);
|
flow_add_op_var (kill, op, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (operands) {
|
if (operands) {
|
||||||
|
@ -1239,7 +1234,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
flow_add_op_var (use, s->opa, 1);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
flow_add_op_var (use, s->opb, 1);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
}
|
}
|
||||||
flow_add_op_var (def, s->opc, 0);
|
flow_add_op_var (def, s->opc, 6);
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[0] = s->opc;
|
operands[0] = s->opc;
|
||||||
operands[1] = s->opa;
|
operands[1] = s->opa;
|
||||||
|
@ -1247,7 +1242,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case st_expr:
|
case st_expr:
|
||||||
flow_add_op_var (def, s->opc, 0);
|
flow_add_op_var (def, s->opc, 6);
|
||||||
flow_add_op_var (use, s->opa, 1);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
if (s->opb)
|
if (s->opb)
|
||||||
flow_add_op_var (use, s->opb, 1);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
|
@ -1258,7 +1253,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case st_assign:
|
case st_assign:
|
||||||
flow_add_op_var (def, s->opa, 0);
|
flow_add_op_var (def, s->opa, 6);
|
||||||
flow_add_op_var (use, s->opc, 1);
|
flow_add_op_var (use, s->opc, 1);
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[0] = s->opa;
|
operands[0] = s->opa;
|
||||||
|
@ -1275,17 +1270,17 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
aux_op1 = s->opb;
|
aux_op1 = s->opb;
|
||||||
if (!strcmp (s->opcode, "move")
|
if (!strcmp (s->opcode, "move")
|
||||||
|| !strcmp (s->opcode, "memset")) {
|
|| !strcmp (s->opcode, "memset")) {
|
||||||
flow_add_op_var (def, s->opc, 0);
|
flow_add_op_var (def, s->opc, 6);
|
||||||
src_op = s->opa;
|
src_op = s->opa;
|
||||||
res_op = s->opc;
|
res_op = s->opc;
|
||||||
} else if (!strcmp (s->opcode, "movep")) {
|
} else if (!strcmp (s->opcode, "movep")) {
|
||||||
flow_add_op_var (use, s->opc, 0);
|
flow_add_op_var (use, s->opc, 6);
|
||||||
aux_op3 = flow_analyze_pointer_operand (s->opa, use);
|
aux_op3 = flow_analyze_pointer_operand (s->opa, use);
|
||||||
res_op = flow_analyze_pointer_operand (s->opc, def);
|
res_op = flow_analyze_pointer_operand (s->opc, def);
|
||||||
src_op = s->opa;
|
src_op = s->opa;
|
||||||
aux_op2 = s->opc;
|
aux_op2 = s->opc;
|
||||||
} else if (!strcmp (s->opcode, "memsetp")) {
|
} else if (!strcmp (s->opcode, "memsetp")) {
|
||||||
flow_add_op_var (use, s->opc, 0);
|
flow_add_op_var (use, s->opc, 6);
|
||||||
res_op = flow_analyze_pointer_operand (s->opc, def);
|
res_op = flow_analyze_pointer_operand (s->opc, def);
|
||||||
src_op = s->opa;
|
src_op = s->opa;
|
||||||
aux_op2 = s->opc;
|
aux_op2 = s->opc;
|
||||||
|
@ -1346,7 +1341,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
// call uses opc to specify the destination of the return value
|
// call uses opc to specify the destination of the return value
|
||||||
// parameter usage is taken care of by the statement's use
|
// parameter usage is taken care of by the statement's use
|
||||||
// list
|
// list
|
||||||
flow_add_op_var (def, s->opc, 0);
|
flow_add_op_var (def, s->opc, 6);
|
||||||
// don't want old argument processing
|
// don't want old argument processing
|
||||||
calln = -1;
|
calln = -1;
|
||||||
if (operands && s->opc->op_type != op_value) {
|
if (operands && s->opc->op_type != op_value) {
|
||||||
|
@ -1372,7 +1367,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
}
|
}
|
||||||
if (def) {
|
if (def) {
|
||||||
for (i = 0; i < num_flow_params; i++) {
|
for (i = 0; i < num_flow_params; i++) {
|
||||||
flow_add_op_var (def, &flow_params[i].op, 0);
|
flow_add_op_var (def, &flow_params[i].op, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kill) {
|
if (kill) {
|
||||||
|
|
Loading…
Reference in a new issue