Remove unnecessary temps from function return values. This has one

*/CRITICAL/* implication: DO NOT /EVER/ RELY ON EVALUATION ORDER. This
isn't /really/ that bad: evaluation order will be consistent for similar
expressions, but for (eg) foo() + bar()*2, bar will be called first.
This commit is contained in:
Bill Currie 2001-08-24 21:47:52 +00:00
parent 08f73bed78
commit ea451ab02d
3 changed files with 22 additions and 9 deletions

View file

@ -27,6 +27,7 @@ typedef struct {
struct expr_s *head;
struct expr_s **tail;
struct expr_s *result;
int is_call;
} block_t;
typedef struct {

View file

@ -156,6 +156,8 @@ emit_assign_expr (expr_t *e)
emit_statement (e->line, op, def_b, def_a, 0);
}
}
if (def_a->type->type != ev_pointer)
return def_a;
return def_b;
}
@ -187,8 +189,14 @@ emit_sub_expr (expr_t *e, def_t *dest)
d = emit_assign_expr (e);
break;
}
def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = emit_sub_expr (e->e.expr.e2, 0);
if (e->e.expr.e1->type == ex_block
&& e->e.expr.e1->e.block.is_call) {
def_b = emit_sub_expr (e->e.expr.e2, 0);
def_a = emit_sub_expr (e->e.expr.e1, 0);
} else {
def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = emit_sub_expr (e->e.expr.e2, 0);
}
switch (e->e.expr.op) {
case AND:
operator = "&&";

View file

@ -762,6 +762,14 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
type_t *type = 0;
expr_t *e;
if (e1->type == ex_block && e1->e.block.is_call
&& e2->type == ex_block && e2->e.block.is_call
&& e1->e.block.result) {
e = new_temp_def_expr (e1->e.block.result->e.def->type);
e1 = binary_expr ('=', e, e1);
print_expr(e1);puts("");
}
if (op == '.')
return field_expr (e1, e2);
@ -1009,6 +1017,8 @@ has_function_call (expr_t *e)
{
switch (e->type) {
case ex_block:
if (e->e.block.is_call)
return 1;
for (e = e->e.block.head; e; e = e->next)
if (has_function_call (e))
return 1;
@ -1107,6 +1117,7 @@ function_expr (expr_t *e1, expr_t *e2)
return err;
call = new_block_expr ();
call->e.block.is_call = 1;
for (e = e2, i = 0; e; e = e->next, i++) {
if (has_function_call (e)) {
*a = new_temp_def_expr (arg_types[i]);
@ -1127,16 +1138,9 @@ function_expr (expr_t *e1, expr_t *e2)
if (ftype->aux_type != &type_void) {
expr_t *ret = new_expr ();
ret->type = ex_def;
#if 0
ret->e.def = memcpy (malloc (sizeof (def_t)), &def_ret, sizeof (def_t));
ret->e.def->type = ftype->aux_type;
call->e.block.result = ret;
#else
ret->e.def = &def_ret;
e = new_temp_def_expr (ftype->aux_type);
append_expr (call, new_binary_expr ('=', e, ret));
call->e.block.result = e;
#endif
}
return call;
}