From 90051e16b4f20a16a4c59e8fc706cbfff6f4c484 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 30 Jun 2004 17:14:43 -0700 Subject: [PATCH] gimplify.c (gimplify_compound_lval): Take fallback argument instead of want_lvalue. * gimplify.c (gimplify_compound_lval): Take fallback argument instead of want_lvalue. (gimplify_call_expr): Take want_value argument instead of test function. Gimplify arguments to val only if reg_type; otherwise allow lvalue forms. (gimplify_expr): Update gimplify_compound_lval and gimplify_call_expr calls. * tree-gimple.c: Update GIMPLE grammer. Use true/false not 1/0. Tidy commentary globally. (get_call_expr_in): Remove RETURN_EXPR handling. Tidy. * tree-gimple.h (is_gimple_call_addr): Mark extern. * gimplify.c (gimplify_modify_expr_to_memcpy): Fix typo. From-SVN: r83941 --- gcc/ChangeLog | 16 ++ gcc/gimplify.c | 53 +++---- gcc/tree-gimple.c | 371 +++++++++++++++++++--------------------------- gcc/tree-gimple.h | 2 +- 4 files changed, 197 insertions(+), 245 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ea91872bf5..b013dd69bd3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-06-30 Richard Henderson + + * gimplify.c (gimplify_compound_lval): Take fallback argument + instead of want_lvalue. + (gimplify_call_expr): Take want_value argument instead of test + function. Gimplify arguments to val only if reg_type; otherwise + allow lvalue forms. + (gimplify_expr): Update gimplify_compound_lval and gimplify_call_expr + calls. + * tree-gimple.c: Update GIMPLE grammer. Use true/false not 1/0. + Tidy commentary globally. + (get_call_expr_in): Remove RETURN_EXPR handling. Tidy. + * tree-gimple.h (is_gimple_call_addr): Mark extern. + + * gimplify.c (gimplify_modify_expr_to_memcpy): Fix typo. + 2004-06-30 Richard Henderson * tree-gimple.c (right_assocify_expr): Kill diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 276c1990f14..e8fdbe9001f 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1563,7 +1563,7 @@ gimplify_array_ref_to_plus (tree *expr_p, tree *pre_p, tree *post_p) static enum gimplify_status gimplify_compound_lval (tree *expr_p, tree *pre_p, - tree *post_p, bool want_lvalue) + tree *post_p, fallback_t fallback) { tree *p; varray_type stack; @@ -1669,8 +1669,7 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p, } /* Step 2 is to gimplify the base expression. */ - tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, - want_lvalue ? fb_lvalue : fb_rvalue); + tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback); ret = MIN (ret, tret); /* And finally, the indices and operands to BIT_FIELD_REF. */ @@ -1713,12 +1712,11 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p, VARRAY_POP (stack); } - tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, - want_lvalue ? fb_lvalue : fb_rvalue); + tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback); ret = MIN (ret, tret); /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */ - if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF) + if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF) { canonicalize_component_ref (expr_p); ret = MIN (ret, GS_OK); @@ -1806,20 +1804,12 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p, } } -/* Gimplify the CALL_EXPR node pointed by EXPR_P. - - call_expr - : ID '(' arglist ')' - - arglist - : arglist ',' val - | val - - PRE_P points to the list where side effects that must happen before - *EXPR_P should be stored. */ +/* Gimplify the CALL_EXPR node pointed by EXPR_P. PRE_P points to the + list where side effects that must happen before *EXPR_P should be stored. + WANT_VALUE is true if the result of the call is desired. */ static enum gimplify_status -gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree)) +gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value) { tree decl; tree arglist; @@ -1863,7 +1853,7 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree)) if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_RESTORE) gimplify_ctxp->save_stack = false; - new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt); + new = simplify_builtin (*expr_p, !want_value); if (new && new != *expr_p) { @@ -1887,13 +1877,24 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree)) arglist = TREE_CHAIN (arglist)) { enum gimplify_status t; + bool (*test) (tree); + fallback_t fb; + + /* In general, we allow lvalues for function arguments to avoid + extra overhead of copying large aggregates out of even larger + aggregates into temporaries only to copy the temporaries to + the argument list. Make optimizers happy by pulling out to + temporaries those types that fit in registers. */ + if (is_gimple_reg_type (TREE_TYPE (TREE_VALUE (arglist)))) + test = is_gimple_val, fb = fb_rvalue; + else + test = is_gimple_lvalue, fb = fb_either; /* There is a sequence point before a function call. Side effects in the argument list must occur before the actual call. So, when gimplifying arguments, force gimplify_expr to use an internal post queue which is then appended to the end of PRE_P. */ - t = gimplify_expr (&TREE_VALUE (arglist), pre_p, NULL, is_gimple_val, - fb_rvalue); + t = gimplify_expr (&TREE_VALUE (arglist), pre_p, NULL, test, fb); if (t == GS_ERROR) ret = GS_ERROR; @@ -1904,7 +1905,7 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree)) /* Try this again in case gimplification exposed something. */ if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl)) { - tree new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt); + tree new = simplify_builtin (*expr_p, !want_value); if (new && new != *expr_p) { @@ -2334,7 +2335,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, bool want_value) args = tree_cons (NULL, t, args); to_ptr = build_fold_addr_expr (to); - args = tree_cons (NULL, to, args); + args = tree_cons (NULL, to_ptr, args); t = implicit_built_in_decls[BUILT_IN_MEMCPY]; t = build_function_call_expr (t, args); @@ -3508,7 +3509,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, case IMAGPART_EXPR: case COMPONENT_REF: ret = gimplify_compound_lval (expr_p, pre_p, post_p, - fallback & fb_lvalue); + fallback ? fallback : fb_rvalue); break; case COND_EXPR: @@ -3516,7 +3517,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, break; case CALL_EXPR: - ret = gimplify_call_expr (expr_p, pre_p, gimple_test_f); + ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); break; case TREE_LIST: @@ -3717,7 +3718,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, enum gimplify_status r0, r1, r2; r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, - is_gimple_min_lval, fb_either); + is_gimple_lvalue, fb_either); r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, is_gimple_val, fb_rvalue); r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p, diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 4d209ec8c8e..7e4c14b5348 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -38,175 +38,141 @@ Boston, MA 02111-1307, USA. */ http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html - function: - FUNCTION_DECL - DECL_SAVED_TREE -> block - block: - BIND_EXPR - BIND_EXPR_VARS -> DECL chain - BIND_EXPR_BLOCK -> BLOCK - BIND_EXPR_BODY -> compound-stmt - compound-stmt: - COMPOUND_EXPR - op0 -> non-compound-stmt - op1 -> stmt - | EXPR_VEC - (or other alternate solution) - stmt: compound-stmt | non-compound-stmt - non-compound-stmt: - block - | if-stmt - | switch-stmt - | jump-stmt - | label-stmt - | try-stmt - | modify-stmt - | call-stmt - if-stmt: - COND_EXPR - op0 -> condition - op1 -> stmt - op2 -> stmt - switch-stmt: - SWITCH_EXPR - op0 -> val - op1 -> stmt - op2 -> array of case labels (as LABEL_DECLs?) - FIXME: add case value info - The SWITCH_LABELS (op2) are sorted in ascending order, and the - last label in the vector is always the default case. - jump-stmt: - GOTO_EXPR - op0 -> LABEL_DECL | '*' ID - | RETURN_EXPR - op0 -> NULL_TREE - | RESULT_DECL - | MODIFY_EXPR -> RESULT_DECL, varname - | THROW_EXPR? do we need/want such a thing for opts, perhaps - to generate an ERT_THROW region? I think so. - Hmm...this would only work at the GIMPLE level, where we know that - the call args don't have any EH impact. Perhaps - annotation of the CALL_EXPR would work better. - | RESX_EXPR - label-stmt: - LABEL_EXPR - op0 -> LABEL_DECL - | CASE_LABEL_EXPR - CASE_LOW -> val | NULL_TREE - CASE_HIGH -> val | NULL_TREE - CASE_LABEL -> LABEL_DECL FIXME - try-stmt: - TRY_CATCH_EXPR - op0 -> stmt - op1 -> handler - | TRY_FINALLY_EXPR - op0 -> stmt - op1 -> stmt - handler: - catch-seq - | EH_FILTER_EXPR - | stmt - modify-stmt: - MODIFY_EXPR - op0 -> lhs - op1 -> rhs - call-stmt: CALL_EXPR - op0 -> ID | '&' ID | OBJ_TYPE_REF - op1 -> arglist - - addr-expr-arg : compref | ID - lhs: addr-expr-arg | '*' ID | bitfieldref - min-lval: ID | '*' ID - bitfieldref : - BIT_FIELD_REF - op0 -> inner_compref - op1 -> CONST - op2 -> var - compref : - COMPONENT_REF - op0 -> inner_compref - | ARRAY_REF - op0 -> inner_compref - op1 -> val - op2 -> val - op3 -> val - | ARRAY_RANGE_REF - op0 -> inner_compref - op1 -> val - op2 -> val - op3 -> val - | REALPART_EXPR - op0 -> inner_compref - | IMAGPART_EXPR - op0 -> inner_compref - - inner_compref : compref | min_lval - | VIEW_CONVERT_EXPR - op0 -> inner_compref - | NOP_EXPR - op0 -> inner_compref - | CONVERT_EXPR - op0 -> inner_compref - - condition : val | val relop val - val : ID | CONST - - rhs : varname | CONST - | '*' ID - | '&' addr-expr-arg - | call_expr - | unop val - | val binop val - | '(' cast ')' val - | method_ref - - (cast here stands for all valid C typecasts) - - unop - : '+' - | '-' - | '!' - | '~' - - binop - : relop | '-' - | '+' - | '/' - | '*' - | '%' - | '&' - | '|' - | '<<' - | '>>' - | '^' - - relop - : '<' - | '<=' - | '>' - | '>=' - | '==' - | '!=' - + function : FUNCTION_DECL + DECL_SAVED_TREE -> compound-stmt + + compound-stmt: STATEMENT_LIST + members -> stmt + + stmt : block + | if-stmt + | switch-stmt + | goto-stmt + | return-stmt + | resx-stmt + | label-stmt + | try-stmt + | modify-stmt + | call-stmt + + block : BIND_EXPR + BIND_EXPR_VARS -> chain of DECLs + BIND_EXPR_BLOCK -> BLOCK + BIND_EXPR_BODY -> compound-stmt + + if-stmt : COND_EXPR + op0 -> condition + op1 -> compound-stmt + op2 -> compound-stmt + + switch-stmt : SWITCH_EXPR + op0 -> val + op1 -> NULL + op2 -> TREE_VEC of CASE_LABEL_EXPRs + The CASE_LABEL_EXPRs are sorted by CASE_LOW, + and default is last. + + goto-stmt : GOTO_EXPR + op0 -> LABEL_DECL | val + + return-stmt : RETURN_EXPR + op0 -> return-value + + return-value : NULL + | RESULT_DECL + | MODIFY_EXPR + op0 -> RESULT_DECL + op1 -> lhs + + resx-stmt : RESX_EXPR + + label-stmt : LABEL_EXPR + op0 -> LABEL_DECL + + try-stmt : TRY_CATCH_EXPR + op0 -> compound-stmt + op1 -> handler + | TRY_FINALLY_EXPR + op0 -> compound-stmt + op1 -> compound-stmt + + handler : catch-seq + | EH_FILTER_EXPR + | compound-stmt + + catch-seq : STATEMENT_LIST + members -> CATCH_EXPR + + modify-stmt : MODIFY_EXPR + op0 -> lhs + op1 -> rhs + + call-stmt : CALL_EXPR + op0 -> val | OBJ_TYPE_REF + op1 -> call-arg-list + + call-arg-list: TREE_LIST + members -> lhs + + addr-expr-arg: ID + | compref + + lhs : addr-expr-arg + | '*' val + | bitfieldref + + min-lval : ID + | '*' val + + bitfieldref : BIT_FIELD_REF + op0 -> inner-compref + op1 -> CONST + op2 -> var + + compref : inner-compref + | REALPART_EXPR + op0 -> inner-compref + | IMAGPART_EXPR + op0 -> inner-compref + + inner-compref: min-lval + | COMPONENT_REF + op0 -> inner-compref + op1 -> FIELD_DECL + op2 -> val + | ARRAY_REF + op0 -> inner-compref + op1 -> val + op2 -> val + op3 -> val + | ARRAY_RANGE_REF + op0 -> inner-compref + op1 -> val + op2 -> val + op3 -> val + | VIEW_CONVERT_EXPR + op0 -> inner-compref + + condition : val + | val RELOP val + + val : ID + | CONST + + rhs : lhs + | CONST + | '&' addr-expr-arg + | call_expr + | UNOP val + | val BINOP val + | val RELOP val */ static inline bool is_gimple_id (tree); /* Validation of GIMPLE expressions. */ -/* Return nonzero if T is a GIMPLE RHS: - - rhs : varname | CONST - | '*' ID - | '&' varname_or_temp - | call_expr - | unop val - | val binop val - | '(' cast ')' val - | > - - The last option is only valid GIMPLE for vector and complex types; - aggregate types should have their constructors decomposed. */ +/* Return true if T is a GIMPLE RHS. */ bool is_gimple_rhs (tree t) @@ -218,7 +184,7 @@ is_gimple_rhs (tree t) case '1': case '2': case '<': - return 1; + return true; default: break; @@ -242,19 +208,16 @@ is_gimple_rhs (tree t) case COMPLEX_CST: case VECTOR_CST: case OBJ_TYPE_REF: - return 1; + return true; default: break; } - if (is_gimple_lvalue (t) || is_gimple_val (t)) - return 1; - - return 0; + return is_gimple_lvalue (t) || is_gimple_val (t); } -/* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either +/* Returns true if T is a valid CONSTRUCTOR component in GIMPLE, either a val or another CONSTRUCTOR. */ bool @@ -264,7 +227,7 @@ is_gimple_constructor_elt (tree t) || TREE_CODE (t) == CONSTRUCTOR); } -/* Return nonzero if T is a valid LHS for a GIMPLE assignment expression. */ +/* Return true if T is a valid LHS for a GIMPLE assignment expression. */ bool is_gimple_lvalue (tree t) @@ -276,12 +239,7 @@ is_gimple_lvalue (tree t) || TREE_CODE (t) == BIT_FIELD_REF); } - -/* Return nonzero if T is a GIMPLE condition: - - condexpr - : val - | val relop val */ +/* Return true if T is a GIMPLE condition. */ bool is_gimple_condexpr (tree t) @@ -290,13 +248,7 @@ is_gimple_condexpr (tree t) || TREE_CODE_CLASS (TREE_CODE (t)) == '<'); } - -/* Return nonzero if T is a valid operand for '&': - - varname - : arrayref - | compref - | ID */ +/* Return true if T is a valid operand for ADDR_EXPR. */ bool is_gimple_addr_expr_arg (tree t) @@ -310,7 +262,7 @@ is_gimple_addr_expr_arg (tree t) || TREE_CODE (t) == INDIRECT_REF); } -/* Return nonzero if T is function invariant. Or rather a restricted +/* Return true if T is function invariant. Or rather a restricted form of function invariant. */ bool @@ -333,7 +285,7 @@ is_gimple_min_invariant (tree t) } } -/* Return nonzero if T looks like a valid GIMPLE statement. */ +/* Return true if T looks like a valid GIMPLE statement. */ bool is_gimple_stmt (tree t) @@ -364,25 +316,23 @@ is_gimple_stmt (tree t) case PHI_NODE: case STATEMENT_LIST: /* These are always void. */ - return 1; + return true; case VA_ARG_EXPR: /* FIXME this should be lowered. */ - return 1; + return true; - case COMPOUND_EXPR: - /* FIXME should we work harder to make COMPOUND_EXPRs void? */ case CALL_EXPR: case MODIFY_EXPR: /* These are valid regardless of their type. */ - return 1; + return true; default: - return 0; + return false; } } -/* Return nonzero if T is a variable. */ +/* Return true if T is a variable. */ bool is_gimple_variable (tree t) @@ -393,7 +343,7 @@ is_gimple_variable (tree t) || TREE_CODE (t) == SSA_NAME); } -/* Return nonzero if T is a GIMPLE identifier (something with an address). */ +/* Return true if T is a GIMPLE identifier (something with an address). */ static inline bool is_gimple_id (tree t) @@ -405,8 +355,7 @@ is_gimple_id (tree t) || TREE_CODE (t) == STRING_CST); } -/* Return nonzero if TYPE is a suitable type for a scalar register - variable. */ +/* Return true if TYPE is a suitable type for a scalar register variable. */ bool is_gimple_reg_type (tree type) @@ -416,7 +365,7 @@ is_gimple_reg_type (tree type) } -/* Return nonzero if T is a scalar register variable. */ +/* Return true if T is a scalar register variable. */ bool is_gimple_reg (tree t) @@ -433,7 +382,7 @@ is_gimple_reg (tree t) && ! needs_to_live_in_memory (t)); } -/* Return nonzero if T is a GIMPLE variable whose address is not needed. */ +/* Return true if T is a GIMPLE variable whose address is not needed. */ bool is_gimple_non_addressable (tree t) @@ -446,8 +395,7 @@ is_gimple_non_addressable (tree t) && ! needs_to_live_in_memory (t)); } -/* Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a - constant. */ +/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */ bool is_gimple_val (tree t) @@ -456,7 +404,7 @@ is_gimple_val (tree t) if (is_gimple_variable (t) && is_gimple_reg_type (TREE_TYPE (t)) && !is_gimple_reg (t)) - return 0; + return false; /* FIXME make these decls. That can happen only when we expose the entire landing-pad construct at the tree level. */ @@ -467,12 +415,7 @@ is_gimple_val (tree t) } -/* Return true if T is a GIMPLE minimal lvalue, of the form - - min_lval: ID | '(' '*' ID ')' - - This never actually appears in the original SIMPLE grammar, but is - repeated in several places. */ +/* Return true if T is a GIMPLE minimal lvalue. */ bool is_gimple_min_lval (tree t) @@ -481,8 +424,7 @@ is_gimple_min_lval (tree t) || TREE_CODE (t) == INDIRECT_REF); } -/* Return nonzero if T is a typecast operation of the form - '(' cast ')' val. */ +/* Return true if T is a typecast operation. */ bool is_gimple_cast (tree t) @@ -510,17 +452,10 @@ is_gimple_call_addr (tree t) tree get_call_expr_in (tree t) { + if (TREE_CODE (t) == MODIFY_EXPR) + t = TREE_OPERAND (t, 1); if (TREE_CODE (t) == CALL_EXPR) return t; - else if (TREE_CODE (t) == MODIFY_EXPR - && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR) - return TREE_OPERAND (t, 1); - else if (TREE_CODE (t) == RETURN_EXPR - && TREE_OPERAND (t, 0) - && TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR - && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == CALL_EXPR) - return TREE_OPERAND (TREE_OPERAND (t, 0), 1); - return NULL_TREE; } diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h index 8fb22710516..5395c67667c 100644 --- a/gcc/tree-gimple.h +++ b/gcc/tree-gimple.h @@ -74,7 +74,7 @@ extern bool is_gimple_constructor_elt (tree); extern bool is_gimple_non_addressable (tree t); /* Returns true iff T is a valid call address expression. */ -bool is_gimple_call_addr (tree); +extern bool is_gimple_call_addr (tree); /* If T makes a function call, returns the CALL_EXPR operand. */ extern tree get_call_expr_in (tree t); -- 2.30.2