mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-22 08:51:13 +00:00
[qfcc] Set a flowvar's minimum size based on usage
But really only for memset and memmove because they need to use an int alias of the variable and it may be only that alias that sets a much larger variable.
This commit is contained in:
parent
73d1044bec
commit
8ec66f118a
2 changed files with 23 additions and 1 deletions
|
@ -49,6 +49,7 @@ typedef struct flowvar_s {
|
||||||
struct operand_s *op; ///< an operand using this var
|
struct operand_s *op; ///< an operand using this var
|
||||||
int number; ///< number of variable in func's ref list
|
int number; ///< number of variable in func's ref list
|
||||||
int flowaddr; ///< psuedo address for local and temp vars
|
int flowaddr; ///< psuedo address for local and temp vars
|
||||||
|
int minsize; ///< minimum size (via memset/move)
|
||||||
} flowvar_t;
|
} flowvar_t;
|
||||||
|
|
||||||
typedef struct udchain_s {
|
typedef struct udchain_s {
|
||||||
|
|
|
@ -572,7 +572,11 @@ clear_operand_chain (operand_t *op)
|
||||||
static void
|
static void
|
||||||
add_var_addrs (set_t *set, flowvar_t *var)
|
add_var_addrs (set_t *set, flowvar_t *var)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < var->op->size; i++) {
|
int size = var->op->size;
|
||||||
|
if (size < var->minsize) {
|
||||||
|
size = var->minsize;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
set_add (set, var->flowaddr + i);
|
set_add (set, var->flowaddr + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -835,6 +839,17 @@ flow_add_op_var (set_t *set, operand_t *op, int ol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flow_set_minsize (operand_t *op, int size)
|
||||||
|
{
|
||||||
|
flowvar_t *var;
|
||||||
|
if (!(var = flow_get_var (op)))
|
||||||
|
return;
|
||||||
|
if (var->minsize < size) {
|
||||||
|
var->minsize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flow_add_op_var_size (set_t *set, operand_t *op, int size, int ol)
|
flow_add_op_var_size (set_t *set, operand_t *op, int size, int ol)
|
||||||
{
|
{
|
||||||
|
@ -1605,6 +1620,12 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
|
||||||
print_type (s->opb->type);
|
print_type (s->opb->type);
|
||||||
internal_error (s->expr, "unexpected type for memset/move");
|
internal_error (s->expr, "unexpected type for memset/move");
|
||||||
}
|
}
|
||||||
|
if (s->type == st_move) {
|
||||||
|
flow_set_minsize (s->opa, size);
|
||||||
|
}
|
||||||
|
if (s->type == st_move || s->type == st_memset) {
|
||||||
|
flow_set_minsize (s->opc, size);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
size = -1;
|
size = -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue