[qfcc] Use statement use chain for v6 calls

Def and kill are still handled in flow_analyze_statement, but this makes
call meta data more consistent between v6 and ruamoko progs, allowing
the statement use chain to be used for call argument analysis. It even
found a bug in the extraction of param counts from the call instruction.
This commit is contained in:
Bill Currie 2023-05-21 10:03:57 +09:00
parent 208359edc6
commit a5943c8a3b
2 changed files with 18 additions and 20 deletions

View file

@ -1289,7 +1289,7 @@ void
flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
operand_t *operands[FLOW_OPERANDS])
{
int i, start, calln = -1;
int i, calln = -1;
operand_t *src_op = 0;
operand_t *res_op = 0;
operand_t *aux_op1 = 0;
@ -1441,33 +1441,23 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
operands[0] = s->opc;
}
} else if (strncmp (s->opcode, "call", 4) == 0) {
start = 0;
calln = s->opcode[5] - '0';
calln = s->opcode[4] - '0';
flow_add_op_var (use, s->opa, 1);
} else if (strncmp (s->opcode, "rcall", 5) == 0) {
start = 2;
calln = s->opcode[6] - '0';
calln = s->opcode[5] - '0';
flow_add_op_var (use, s->opa, 1);
flow_add_op_var (use, s->opb, 1);
if (s->opc)
flow_add_op_var (use, s->opc, 1);
}
if (calln >= 0) {
if (use) {
for (i = start; i < calln; i++) {
flow_add_op_var (use, &flow_params[i + 1].op, 1);
}
}
if (def) {
for (i = 0; i < num_flow_params; i++) {
flow_add_op_var (def, &flow_params[i].op, 6);
}
flow_add_op_var (def, &flow_params[0].op, 6);
}
if (kill) {
for (i = 0; i < num_flow_params; i++) {
flow_kill_aliases (kill,
flow_get_var (&flow_params[i].op),
0);
for (i = 1; i < num_flow_params; i++) {
flowvar_t *var = flow_get_var (&flow_params[i].op);
flow_kill_aliases (kill, var, 0);
}
}
}

View file

@ -1012,6 +1012,7 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
const char *opcode;
const char *pref = "";
statement_t *s;
operand_t *use = 0;
// function arguments are in reverse order
for (a = args; a; a = a->next) {
@ -1037,6 +1038,10 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
sblock = vector_call (sblock, a, param, ind, &arguments[ind]);
else
sblock = statement_subexpr (sblock, a, &arguments[ind]);
operand_t *p;
sblock = statement_subexpr (sblock, param, &p);
p->next = use;
use = p;
continue;
}
if (is_struct (get_type (param))) {
@ -1045,13 +1050,13 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
mov->file = a->file;
sblock = statement_slist (sblock, mov);
} else {
operand_t *p = 0;
sblock = statement_subexpr (sblock, param, &p);
if (options.code.vector_calls && a->type == ex_value
&& a->e.value->lltype == ev_vector) {
sblock = vector_call (sblock, a, param, ind, 0);
} else {
operand_t *p = 0;
operand_t *arg;
sblock = statement_subexpr (sblock, param, &p);
operand_t *arg = p;
arg = p;
sblock = statement_subexpr (sblock, a, &arg);
if (arg != p) {
@ -1059,6 +1064,8 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
sblock_add_statement (sblock, s);
}
}
p->next = use;
use = p;
}
}
opcode = va (0, "%scall%d", pref, count);
@ -1066,6 +1073,7 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
sblock = statement_subexpr (sblock, func, &s->opa);
s->opb = arguments[0];
s->opc = arguments[1];
s->use = use;
if (op) {
*op = return_operand (call->e.branch.ret_type, call);
}