mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[qfcc] Handle aliases when setting use and def
As expected, this does not fix the mangled pointer problem in struct-init-param.r, but it does improve the ud-chains. There's still a problem with .return, but it's handling in flow_analyze_statement is a bit "special" :P.
This commit is contained in:
parent
a2f203c840
commit
8696e76a25
1 changed files with 57 additions and 23 deletions
|
@ -541,7 +541,12 @@ flow_build_vars (function_t *func)
|
||||||
flow_analyze_statement (s, 0, 0, 0, operands);
|
flow_analyze_statement (s, 0, 0, 0, operands);
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
add_operand (func, operands[j]);
|
add_operand (func, operands[j]);
|
||||||
|
}
|
||||||
|
// and set the use/def sets for the vars (has to be a separate pass
|
||||||
|
// because the allias handling reqruires the flow address to be valid
|
||||||
|
// (ie, not -1)
|
||||||
|
for (i = 0; i < func->num_statements; i++) {
|
||||||
|
s = func->statements[i];
|
||||||
flow_analyze_statement (s, stuse, stdef, 0, 0);
|
flow_analyze_statement (s, stuse, stdef, 0, 0);
|
||||||
for (var_i = set_first (stdef); var_i; var_i = set_next (var_i)) {
|
for (var_i = set_first (stdef); var_i; var_i = set_next (var_i)) {
|
||||||
var = func->vars[var_i->element];
|
var = func->vars[var_i->element];
|
||||||
|
@ -977,16 +982,45 @@ flow_generate (flowgraph_t *graph)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
flow_tempop_add_aliases (tempop_t *tempop, void *_set)
|
||||||
|
{
|
||||||
|
set_t *set = (set_t *) _set;
|
||||||
|
flowvar_t *var;
|
||||||
|
var = tempop->flowvar;
|
||||||
|
if (var)
|
||||||
|
set_add (set, var->number);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
flow_def_add_aliases (def_t *def, void *_set)
|
||||||
|
{
|
||||||
|
set_t *set = (set_t *) _set;
|
||||||
|
flowvar_t *var;
|
||||||
|
var = def->flowvar;
|
||||||
|
if (var)
|
||||||
|
set_add (set, var->number);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flow_add_op_var (set_t *set, operand_t *op)
|
flow_add_op_var (set_t *set, operand_t *op, int is_use)
|
||||||
{
|
{
|
||||||
flowvar_t *var;
|
flowvar_t *var;
|
||||||
|
int ol = is_use ? 2 : 1;
|
||||||
|
|
||||||
if (!set)
|
if (!set)
|
||||||
return;
|
return;
|
||||||
if (!(var = flow_get_var (op)))
|
if (!(var = flow_get_var (op)))
|
||||||
return;
|
return;
|
||||||
set_add (set, var->number);
|
set_add (set, var->number);
|
||||||
|
|
||||||
|
if (op->op_type == op_temp) {
|
||||||
|
tempop_visit_all (&op->o.tempop, ol, flow_tempop_add_aliases, set);
|
||||||
|
} else {
|
||||||
|
def_visit_all (op->o.def, ol, flow_def_add_aliases, set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1010,10 +1044,10 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
case st_none:
|
case st_none:
|
||||||
internal_error (s->expr, "not a statement");
|
internal_error (s->expr, "not a statement");
|
||||||
case st_expr:
|
case st_expr:
|
||||||
flow_add_op_var (def, s->opc);
|
flow_add_op_var (def, s->opc, 0);
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
if (s->opb)
|
if (s->opb)
|
||||||
flow_add_op_var (use, s->opb);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[0] = s->opc;
|
operands[0] = s->opc;
|
||||||
operands[1] = s->opa;
|
operands[1] = s->opa;
|
||||||
|
@ -1021,8 +1055,8 @@ 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->opb);
|
flow_add_op_var (def, s->opb, 0);
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[0] = s->opb;
|
operands[0] = s->opb;
|
||||||
operands[1] = s->opa;
|
operands[1] = s->opa;
|
||||||
|
@ -1030,12 +1064,12 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
break;
|
break;
|
||||||
case st_ptrassign:
|
case st_ptrassign:
|
||||||
case st_move:
|
case st_move:
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
flow_add_op_var (use, s->opb);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
if (!strcmp (s->opcode, "<MOVE>")) {
|
if (!strcmp (s->opcode, "<MOVE>")) {
|
||||||
flow_add_op_var (def, s->opc);
|
flow_add_op_var (def, s->opc, 0);
|
||||||
} else if (!strcmp (s->opcode, "<MOVEP>")) {
|
} else if (!strcmp (s->opcode, "<MOVEP>")) {
|
||||||
flow_add_op_var (use, s->opc);
|
flow_add_op_var (use, s->opc, 0);
|
||||||
if (s->opc->op_type == op_value
|
if (s->opc->op_type == op_value
|
||||||
&& s->opc->o.value->lltype == ev_pointer
|
&& s->opc->o.value->lltype == ev_pointer
|
||||||
&& s->opc->o.value->v.pointer.def) {
|
&& s->opc->o.value->v.pointer.def) {
|
||||||
|
@ -1044,7 +1078,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
ex_pointer_t *ptr = &s->opc->o.value->v.pointer;
|
ex_pointer_t *ptr = &s->opc->o.value->v.pointer;
|
||||||
alias = alias_def (ptr->def, ptr->type, ptr->val);
|
alias = alias_def (ptr->def, ptr->type, ptr->val);
|
||||||
op = def_operand (alias, ptr->type);
|
op = def_operand (alias, ptr->type);
|
||||||
flow_add_op_var (def, op);
|
flow_add_op_var (def, op, 0);
|
||||||
if (operands)
|
if (operands)
|
||||||
operands[0] = op;
|
operands[0] = op;
|
||||||
else
|
else
|
||||||
|
@ -1055,7 +1089,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (s->opc)
|
if (s->opc)
|
||||||
flow_add_op_var (use, s->opc);
|
flow_add_op_var (use, s->opc, 1);
|
||||||
}
|
}
|
||||||
if (kill) {
|
if (kill) {
|
||||||
set_everything (kill);
|
set_everything (kill);
|
||||||
|
@ -1070,10 +1104,10 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case st_state:
|
case st_state:
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
flow_add_op_var (use, s->opb);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
if (s->opc)
|
if (s->opc)
|
||||||
flow_add_op_var (use, s->opc);
|
flow_add_op_var (use, s->opc, 1);
|
||||||
//FIXME entity members
|
//FIXME entity members
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[1] = s->opa;
|
operands[1] = s->opa;
|
||||||
|
@ -1084,7 +1118,7 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
case st_func:
|
case st_func:
|
||||||
if (strcmp (s->opcode, "<RETURN>") == 0
|
if (strcmp (s->opcode, "<RETURN>") == 0
|
||||||
|| strcmp (s->opcode, "<DONE>") == 0) {
|
|| strcmp (s->opcode, "<DONE>") == 0) {
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
} else if (strcmp (s->opcode, "<RETURN_V>") == 0) {
|
} else if (strcmp (s->opcode, "<RETURN_V>") == 0) {
|
||||||
if (use)
|
if (use)
|
||||||
set_add (use, 0); //FIXME assumes .return location
|
set_add (use, 0); //FIXME assumes .return location
|
||||||
|
@ -1092,14 +1126,14 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
if (strncmp (s->opcode, "<CALL", 5) == 0) {
|
if (strncmp (s->opcode, "<CALL", 5) == 0) {
|
||||||
start = 0;
|
start = 0;
|
||||||
calln = s->opcode[5] - '0';
|
calln = s->opcode[5] - '0';
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
} else if (strncmp (s->opcode, "<RCALL", 6) == 0) {
|
} else if (strncmp (s->opcode, "<RCALL", 6) == 0) {
|
||||||
start = 2;
|
start = 2;
|
||||||
calln = s->opcode[6] - '0';
|
calln = s->opcode[6] - '0';
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
flow_add_op_var (use, s->opb);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
if (s->opc)
|
if (s->opc)
|
||||||
flow_add_op_var (use, s->opc);
|
flow_add_op_var (use, s->opc, 1);
|
||||||
}
|
}
|
||||||
if (calln >= 0) {
|
if (calln >= 0) {
|
||||||
if (use) {
|
if (use) {
|
||||||
|
@ -1117,9 +1151,9 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
break;
|
break;
|
||||||
case st_flow:
|
case st_flow:
|
||||||
if (strcmp (s->opcode, "<GOTO>") != 0) {
|
if (strcmp (s->opcode, "<GOTO>") != 0) {
|
||||||
flow_add_op_var (use, s->opa);
|
flow_add_op_var (use, s->opa, 1);
|
||||||
if (strcmp (s->opcode, "<JUMPB>") == 0)
|
if (strcmp (s->opcode, "<JUMPB>") == 0)
|
||||||
flow_add_op_var (use, s->opb);
|
flow_add_op_var (use, s->opb, 1);
|
||||||
}
|
}
|
||||||
if (operands) {
|
if (operands) {
|
||||||
operands[1] = s->opa;
|
operands[1] = s->opa;
|
||||||
|
|
Loading…
Reference in a new issue