added some optimalizations

This commit is contained in:
eck 1990-09-06 11:32:51 +00:00
parent 9915ed4bc2
commit 2f0275ba3c
4 changed files with 51 additions and 19 deletions

View file

@ -27,8 +27,13 @@ extern char *symbol2str();
depending on the constancy of the operands.
*/
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
/*
* Although the relational operators are generally not commutative, we can
* switch the arguments if the operator is adapted (e.g. < becomes >)
*/
#define non_commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 0)
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
#define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
ch3bin(expp, oper, expr)
register struct expr **expp;
@ -182,7 +187,7 @@ ch3bin(expp, oper, expr)
case EQUAL:
case NOTEQUAL:
relbalance(expp, oper, &expr);
non_commutative_binop(expp, oper, expr);
non_commutative_relop(expp, oper, expr);
(*expp)->ex_type = int_type;
break;
@ -301,6 +306,23 @@ pntminuspnt(expp, oper, expr)
if (int_size != pointer_size) (*expp)->ex_flags |= EX_PTRDIFF;
}
/*
* The function arg_switched() returns the operator that should be used
* when the arguments are switched. This is special for some relational
* operators.
*/
int
arg_switched(oper)
{
switch (oper) {
case '<': return '>';
case '>': return '<';
case LESSEQ: return GREATEREQ;
case GREATEREQ: return LESSEQ;
default: return oper;
}
}
mk_binop(expp, oper, expr, commutative)
struct expr **expp;
register struct expr *expr;
@ -315,14 +337,13 @@ mk_binop(expp, oper, expr, commutative)
cstbin(expp, oper, expr);
else if (is_fp_cst(expr) && is_fp_cst(ex))
fltcstbin(expp, oper, expr);
else {
*expp = (commutative &&
! (ex->ex_flags & EX_VOLATILE) &&
( expr->ex_depth > ex->ex_depth ||
(expr->ex_flags & EX_SIDEEFFECTS) ||
is_cp_cst(ex)))
? new_oper(ex->ex_type, expr, oper, ex)
: new_oper(ex->ex_type, ex, oper, expr);
else {
*expp = (commutative
&& !(ex->ex_flags & EX_VOLATILE)
&& ( expr->ex_depth > ex->ex_depth
|| is_cp_cst(ex)))
? new_oper(ex->ex_type, expr, arg_switched(oper), ex)
: new_oper(ex->ex_type, ex, oper, expr);
}
}

View file

@ -279,14 +279,14 @@ end_proc(fbytes)
DfaEndFunction();
#endif DATAFLOW
C_df_ilb(return2_label);
if (return_expr_occurred) C_asp(-func_size);
if (return_expr_occurred && func_res_label == 0) {
C_asp(-func_size);
}
C_df_ilb(return_label);
prc_exit();
#ifndef LINT
if (return_expr_occurred) {
if (func_res_label != 0) {
C_lae_dlb(func_res_label, (arith)0);
store_block(func_size, func_type->tp_align);
C_lae_dlb(func_res_label, (arith)0);
C_ret(pointer_size);
}
@ -347,6 +347,10 @@ do_return_expr(expr)
*/
ch3cast(&expr, RETURN, func_type);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
if (func_res_label != 0) {
C_lae_dlb(func_res_label, (arith)0);
store_block(func_size, func_type->tp_align);
}
C_bra(return_label);
return_expr_occurred = 1;
}

View file

@ -67,13 +67,13 @@ declaration
short typedef yepp;
makes all hope of writing a specific grammar for typedefs illusory.
*/
/* Accept a single declaration specifier. Then accept zero or more
type-specifiers. There can be a conflict on both TYPE_IDENTIFIER
and IDENTIFIER.
/* Accept a single declaration specifier. Then accept zero or more
declaration specifiers. There can be a conflict on both
TYPE_IDENTIFIER and IDENTIFIER.
The following rule is used:
When we see a TYPE_IDENTIFIER, we accept it if no type-specifier
was given, and it is not directly followed by an identifier.
If no type-dpecifier was given, it is taken as the identifier being
When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was
given, and it is not directly followed by an identifier. If a
type-specifier was given, it is taken as the identifier being
declared. If it is followed by an identifier, we assume that an
error has been made, (e.g. unsigned typedeffed_int x;) and that
this will be detected later on.

View file

@ -383,6 +383,13 @@ new_oper(tp, e1, oper, e2)
expr->ex_flags = (e1_flags | e2->ex_flags)
& ~(EX_PARENS | EX_READONLY | EX_VOLATILE );
}
/*
* A function call should be evaluated first when possible. Just say
* that the expression tree is very deep.
*/
if (oper == '(') {
expr->ex_depth = 50;
}
op = &expr->ex_object.ex_oper;
op->op_type = tp;
op->op_oper = oper;