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. 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 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) ch3bin(expp, oper, expr)
register struct expr **expp; register struct expr **expp;
@ -182,7 +187,7 @@ ch3bin(expp, oper, expr)
case EQUAL: case EQUAL:
case NOTEQUAL: case NOTEQUAL:
relbalance(expp, oper, &expr); relbalance(expp, oper, &expr);
non_commutative_binop(expp, oper, expr); non_commutative_relop(expp, oper, expr);
(*expp)->ex_type = int_type; (*expp)->ex_type = int_type;
break; break;
@ -301,6 +306,23 @@ pntminuspnt(expp, oper, expr)
if (int_size != pointer_size) (*expp)->ex_flags |= EX_PTRDIFF; 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) mk_binop(expp, oper, expr, commutative)
struct expr **expp; struct expr **expp;
register struct expr *expr; register struct expr *expr;
@ -315,14 +337,13 @@ mk_binop(expp, oper, expr, commutative)
cstbin(expp, oper, expr); cstbin(expp, oper, expr);
else if (is_fp_cst(expr) && is_fp_cst(ex)) else if (is_fp_cst(expr) && is_fp_cst(ex))
fltcstbin(expp, oper, expr); fltcstbin(expp, oper, expr);
else { else {
*expp = (commutative && *expp = (commutative
! (ex->ex_flags & EX_VOLATILE) && && !(ex->ex_flags & EX_VOLATILE)
( expr->ex_depth > ex->ex_depth || && ( expr->ex_depth > ex->ex_depth
(expr->ex_flags & EX_SIDEEFFECTS) || || is_cp_cst(ex)))
is_cp_cst(ex))) ? new_oper(ex->ex_type, expr, arg_switched(oper), ex)
? new_oper(ex->ex_type, expr, oper, ex) : new_oper(ex->ex_type, ex, oper, expr);
: new_oper(ex->ex_type, ex, oper, expr);
} }
} }

View file

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

View file

@ -67,13 +67,13 @@ declaration
short typedef yepp; short typedef yepp;
makes all hope of writing a specific grammar for typedefs illusory. makes all hope of writing a specific grammar for typedefs illusory.
*/ */
/* Accept a single declaration specifier. Then accept zero or more /* Accept a single declaration specifier. Then accept zero or more
type-specifiers. There can be a conflict on both TYPE_IDENTIFIER declaration specifiers. There can be a conflict on both
and IDENTIFIER. TYPE_IDENTIFIER and IDENTIFIER.
The following rule is used: The following rule is used:
When we see a TYPE_IDENTIFIER, we accept it if no type-specifier When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was
was given, and it is not directly followed by an identifier. given, and it is not directly followed by an identifier. If a
If no type-dpecifier was given, it is taken as the identifier being type-specifier was given, it is taken as the identifier being
declared. If it is followed by an identifier, we assume that an declared. If it is followed by an identifier, we assume that an
error has been made, (e.g. unsigned typedeffed_int x;) and that error has been made, (e.g. unsigned typedeffed_int x;) and that
this will be detected later on. 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) expr->ex_flags = (e1_flags | e2->ex_flags)
& ~(EX_PARENS | EX_READONLY | EX_VOLATILE ); & ~(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 = &expr->ex_object.ex_oper;
op->op_type = tp; op->op_type = tp;
op->op_oper = oper; op->op_oper = oper;