From 2f0275ba3c6edab5345a938eb79d90926e4ee5b8 Mon Sep 17 00:00:00 2001 From: eck Date: Thu, 6 Sep 1990 11:32:51 +0000 Subject: [PATCH] added some optimalizations --- lang/cem/cemcom.ansi/ch3bin.c | 41 ++++++++++++++++++++++++++--------- lang/cem/cemcom.ansi/code.c | 10 ++++++--- lang/cem/cemcom.ansi/declar.g | 12 +++++----- lang/cem/cemcom.ansi/expr.c | 7 ++++++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/lang/cem/cemcom.ansi/ch3bin.c b/lang/cem/cemcom.ansi/ch3bin.c index 247ec27ae..72bd477c1 100644 --- a/lang/cem/cemcom.ansi/ch3bin.c +++ b/lang/cem/cemcom.ansi/ch3bin.c @@ -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); } } diff --git a/lang/cem/cemcom.ansi/code.c b/lang/cem/cemcom.ansi/code.c index 30a1939f3..a6be75a16 100644 --- a/lang/cem/cemcom.ansi/code.c +++ b/lang/cem/cemcom.ansi/code.c @@ -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; } diff --git a/lang/cem/cemcom.ansi/declar.g b/lang/cem/cemcom.ansi/declar.g index c15f2043a..6d3b5712d 100644 --- a/lang/cem/cemcom.ansi/declar.g +++ b/lang/cem/cemcom.ansi/declar.g @@ -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. diff --git a/lang/cem/cemcom.ansi/expr.c b/lang/cem/cemcom.ansi/expr.c index 7b6d562b6..e3b7b70b7 100644 --- a/lang/cem/cemcom.ansi/expr.c +++ b/lang/cem/cemcom.ansi/expr.c @@ -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; -- 2.34.1