added some optimalizations
This commit is contained in:
parent
9915ed4bc2
commit
2f0275ba3c
4 changed files with 51 additions and 19 deletions
|
@ -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;
|
||||||
|
@ -316,12 +338,11 @@ mk_binop(expp, oper, expr, commutative)
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,12 +68,12 @@ declaration
|
||||||
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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue