Avoid creating a struct temp for ivar struct return

This fixed the uninitialized temp warning in HUD.r. The problem was
caused by the flow analyzer not being able to detect that the struct
temp was being initialized by the move statement due to the address of
the temp being in a pointer temp. While it would be good to use a
constant pointer for the address of the struct temp or improving the
flow analyzer to track actual data, avoiding the temp in the first place
results in nicer code as it removes a move statement.
This commit is contained in:
Bill Currie 2020-02-15 22:10:46 +09:00
parent 9c996df7b4
commit 1985b6d4fd
3 changed files with 18 additions and 14 deletions

View file

@ -116,6 +116,7 @@ struct dstring_s;
const char *optype_str (op_type_e type) __attribute__((const));
operand_t *def_operand (struct def_s *def, struct type_s *type);
operand_t *return_operand (struct type_s *type);
operand_t *value_operand (struct ex_value_s *value);
int tempop_overlap (tempop_t *t1, tempop_t *t2) __attribute__((pure));
operand_t *temp_operand (struct type_s *type);

View file

@ -318,6 +318,15 @@ def_operand (def_t *def, type_t *type)
return op;
}
operand_t *
return_operand (type_t *type)
{
symbol_t *return_symbol;
return_symbol = make_symbol (".return", &type_param, pr.symtab->space,
sc_extern);
return def_operand (return_symbol->s.def, type);
}
operand_t *
value_operand (ex_value_t *value)
{
@ -394,7 +403,7 @@ alias_operand (type_t *type, operand_t *op)
operand_t *aop;
if (type_size (type) != type_size (op->type)) {
internal_error (0, "\naliasing operand with type of diffent size"
internal_error (0, "\naliasing operand with type of different size"
" (%d, %d)", type_size (type), type_size (op->type));
}
aop = new_operand (op_alias);
@ -1387,8 +1396,10 @@ statement_uexpr (sblock_t *sblock, expr_t *e)
}
}
s = new_statement (st_func, opcode, e);
if (e->e.expr.e1)
if (e->e.expr.e1) {
s->opa = return_operand (get_type (e->e.expr.e1));
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
}
sblock_add_statement (sblock, s);
sblock->next = new_sblock ();
sblock = sblock->next;
@ -1667,10 +1678,6 @@ static void
check_final_block (sblock_t *sblock)
{
statement_t *s = 0;
symbol_t *return_symbol = 0;
def_t *return_def = 0;
operand_t *return_operand = 0;
const char *return_opcode = "<RETURN_V>";
if (!sblock)
return;
@ -1691,16 +1698,11 @@ check_final_block (sblock_t *sblock)
sblock->next = new_sblock ();
sblock = sblock->next;
}
s = new_statement (st_func, "<RETURN_V>", 0);
if (options.traditional || options.code.progsversion == PROG_ID_VERSION) {
return_symbol = make_symbol (".return", &type_param, pr.symtab->space,
sc_extern);
return_def = return_symbol->s.def;
return_opcode = "<RETURN>";
s->opcode = save_string ("<RETURN>");
s->opa = return_operand (&type_void);
}
if (return_symbol)
return_operand = def_operand (return_def, &type_void);
s = new_statement (st_func, return_opcode, 0);
s->opa = return_operand;
sblock_add_statement (sblock, s);
}

View file

@ -8,6 +8,7 @@ typedef struct Point Point;
@interface Object
{
int foo;
Point origin;
}
-(Point) origin;