From 8ec66f118a8157075694d257a18524bd619ee1ce Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 11 Sep 2023 22:56:37 +0900 Subject: [PATCH] [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. --- tools/qfcc/include/flow.h | 1 + tools/qfcc/source/flow.c | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/include/flow.h b/tools/qfcc/include/flow.h index eb2d4ba20..c66d22413 100644 --- a/tools/qfcc/include/flow.h +++ b/tools/qfcc/include/flow.h @@ -49,6 +49,7 @@ typedef struct flowvar_s { struct operand_s *op; ///< an operand using this var int number; ///< number of variable in func's ref list int flowaddr; ///< psuedo address for local and temp vars + int minsize; ///< minimum size (via memset/move) } flowvar_t; typedef struct udchain_s { diff --git a/tools/qfcc/source/flow.c b/tools/qfcc/source/flow.c index b25425623..25ff5ef69 100644 --- a/tools/qfcc/source/flow.c +++ b/tools/qfcc/source/flow.c @@ -572,7 +572,11 @@ clear_operand_chain (operand_t *op) static void 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); } } @@ -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 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); 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 { size = -1; }