diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-25 13:33:54 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-25 13:33:54 +0000 |
commit | 2c02962cf935ac329a5069f6721839c3c1a3d331 (patch) | |
tree | 21065dda4814644807909923e74947363f96ca60 | |
parent | 588e1cc345332f6d464f2de3aa43692535094ab5 (diff) | |
download | gcc-2c02962cf935ac329a5069f6721839c3c1a3d331.tar.gz |
* expr.h (struct separate_ops, sepops): New type for passing
around an exploded simple expression.
* optabs.c (expand_widen_pattern_expr, expand_vec_shift_expr):
Use this structure instead of expression tree.
(get_vcond_icode, expand_vec_cond_expr_p): Don't take whole
expression, only its type.
(expand_vec_cond_expr): Take type and individual operands instead
of full expression.
* optabs.h (expand_widen_pattern_expr, expand_vec_cond_expr,
expand_vec_shift_expr): Change prototype accordingly.
* tree-vect-stmts.c (vectorizable_condition): Change call of
expand_vec_cond_expr_p to pass only type.
* expr.c (do_store_flags): Change prototype and implementation
to take an exploded expression.
(expand_expr_real_1): New local ops initialized with details
of the full expression. Use it instead of full
expression in calls to do_store_flags, expand_vec_cond_expr,
expand_widen_pattern_expr and expand_vec_shift_expr.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151079 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/expr.c | 52 | ||||
-rw-r--r-- | gcc/expr.h | 11 | ||||
-rw-r--r-- | gcc/optabs.c | 54 | ||||
-rw-r--r-- | gcc/optabs.h | 7 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 2 |
6 files changed, 95 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb5e0b11eaf..e99500ba514 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,26 @@ 2009-08-25 Michael Matz <matz@suse.de> + * expr.h (struct separate_ops, sepops): New type for passing + around an exploded simple expression. + * optabs.c (expand_widen_pattern_expr, expand_vec_shift_expr): + Use this structure instead of expression tree. + (get_vcond_icode, expand_vec_cond_expr_p): Don't take whole + expression, only its type. + (expand_vec_cond_expr): Take type and individual operands instead + of full expression. + * optabs.h (expand_widen_pattern_expr, expand_vec_cond_expr, + expand_vec_shift_expr): Change prototype accordingly. + * tree-vect-stmts.c (vectorizable_condition): Change call of + expand_vec_cond_expr_p to pass only type. + * expr.c (do_store_flags): Change prototype and implementation + to take an exploded expression. + (expand_expr_real_1): New local ops initialized with details + of the full expression. Use it instead of full + expression in calls to do_store_flags, expand_vec_cond_expr, + expand_widen_pattern_expr and expand_vec_shift_expr. + +2009-08-25 Michael Matz <matz@suse.de> + * expr.c (expand_expr_real_1): New local treeop0, treeop1, treeop2 initialized with first three operands of the full expression. Substitute all TREE_OPERAND (exp, [012]) calls with them. diff --git a/gcc/expr.c b/gcc/expr.c index 7e316b547ad..12d0dc99856 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -152,7 +152,7 @@ static int is_aligning_offset (const_tree, const_tree); static void expand_operands (tree, tree, rtx, rtx*, rtx*, enum expand_modifier); static rtx reduce_to_bit_field_precision (rtx, rtx, tree); -static rtx do_store_flag (tree, rtx, enum machine_mode); +static rtx do_store_flag (sepops, rtx, enum machine_mode); #ifdef PUSH_ROUNDING static void emit_single_push_insn (enum machine_mode, rtx, tree); #endif @@ -7220,6 +7220,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, gimple subexp0_def, subexp1_def; tree top0, top1; location_t loc = EXPR_LOCATION (exp); + struct separate_ops ops; tree treeop0, treeop1, treeop2; #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \ ? reduce_to_bit_field_precision ((expr), \ @@ -7241,6 +7242,12 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case 1: treeop0 = TREE_OPERAND (exp, 0); case 0: break; } + ops.code = code; + ops.type = type; + ops.op0 = treeop0; + ops.op1 = treeop1; + ops.op2 = treeop2; + ops.location = loc; ignore = (target == const0_rtx || ((CONVERT_EXPR_CODE_P (code) @@ -8187,6 +8194,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, modifier); result = copy_rtx (result); + /* BLA */ set_mem_attributes (result, exp, 0); return result; } @@ -9133,7 +9141,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case UNGE_EXPR: case UNEQ_EXPR: case LTGT_EXPR: - temp = do_store_flag (exp, + temp = do_store_flag (&ops, modifier != EXPAND_STACK_PARM ? target : NULL_RTX, tmode != VOIDmode ? tmode : mode); if (temp) @@ -9161,6 +9169,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, emit_move_insn (target, const0_rtx); op1 = gen_label_rtx (); + /* BLA */ jumpifnot (exp, op1); if (target) @@ -9247,8 +9256,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, return temp; case VEC_COND_EXPR: - target = expand_vec_cond_expr (exp, target); - return target; + target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target); + return target; case MODIFY_EXPR: { @@ -9403,7 +9412,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); op2 = expand_normal (oprnd2); - target = expand_widen_pattern_expr (exp, op0, op1, op2, + target = expand_widen_pattern_expr (&ops, op0, op1, op2, target, unsignedp); return target; } @@ -9414,7 +9423,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, tree oprnd1 = treeop1; expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); - target = expand_widen_pattern_expr (exp, op0, NULL_RTX, op1, + target = expand_widen_pattern_expr (&ops, op0, NULL_RTX, op1, target, unsignedp); return target; } @@ -9457,7 +9466,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case VEC_LSHIFT_EXPR: case VEC_RSHIFT_EXPR: { - target = expand_vec_shift_expr (exp, target); + target = expand_vec_shift_expr (&ops, target); return target; } @@ -9466,7 +9475,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, { op0 = expand_normal (treeop0); this_optab = optab_for_tree_code (code, type, optab_default); - temp = expand_widen_pattern_expr (exp, op0, NULL_RTX, NULL_RTX, + temp = expand_widen_pattern_expr (&ops, op0, NULL_RTX, NULL_RTX, target, unsignedp); gcc_assert (temp); return temp; @@ -9481,7 +9490,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, TREE_TYPE (treeop0), optab_default); temp = expand_widen_pattern_expr - (exp, op0, NULL_RTX, NULL_RTX, + (&ops, op0, NULL_RTX, NULL_RTX, target, TYPE_UNSIGNED (TREE_TYPE (treeop0))); gcc_assert (temp); @@ -9495,7 +9504,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, tree oprnd1 = treeop1; expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); - target = expand_widen_pattern_expr (exp, op0, op1, NULL_RTX, + target = expand_widen_pattern_expr (&ops, op0, op1, NULL_RTX, target, unsignedp); gcc_assert (target); return target; @@ -9740,8 +9749,9 @@ string_constant (tree arg, tree *ptr_offset) return 0; } -/* Generate code to calculate EXP using a store-flag instruction - and return an rtx for the result. EXP is a comparison. +/* Generate code to calculate OPS, and exploded expression + using a store-flag instruction and return an rtx for the result. + OPS reflects a comparison. If TARGET is nonzero, store the result there if convenient. @@ -9757,7 +9767,7 @@ string_constant (tree arg, tree *ptr_offset) set/jump/set sequence. */ static rtx -do_store_flag (tree exp, rtx target, enum machine_mode mode) +do_store_flag (sepops ops, rtx target, enum machine_mode mode) { enum rtx_code code; tree arg0, arg1, type; @@ -9766,10 +9776,10 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode) int unsignedp; rtx op0, op1; rtx subtarget = target; - location_t loc = EXPR_LOCATION (exp); + location_t loc = ops->location; - arg0 = TREE_OPERAND (exp, 0); - arg1 = TREE_OPERAND (exp, 1); + arg0 = ops->op0; + arg1 = ops->op1; /* Don't crash if the comparison was erroneous. */ if (arg0 == error_mark_node || arg1 == error_mark_node) @@ -9788,11 +9798,11 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode) when function pointers must be canonicalized before comparisons. */ #ifdef HAVE_canonicalize_funcptr_for_compare if (HAVE_canonicalize_funcptr_for_compare - && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))) + && ((TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == FUNCTION_TYPE)) - || (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1)))) + || (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == FUNCTION_TYPE)))) return 0; #endif @@ -9807,7 +9817,7 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode) tests will not catch constants in the first operand, but constants are rarely passed as the first operand. */ - switch (TREE_CODE (exp)) + switch (ops->code) { case EQ_EXPR: code = EQ; diff --git a/gcc/expr.h b/gcc/expr.h index 7058354a866..228a34597be 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -267,6 +267,17 @@ do { \ #define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100) #endif +/* This structure is used to pass around information about exploded + unary, binary and trinary expressions between expand_expr_real_1 and + friends. */ +typedef struct separate_ops +{ + enum tree_code code; + tree type; + tree op0, op1, op2; + location_t location; +} *sepops; + /* Functions from optabs.c, commonly used, and without need for the optabs tables: */ diff --git a/gcc/optabs.c b/gcc/optabs.c index fcc1649caf3..61d8bcfe298 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -530,8 +530,8 @@ optab_for_tree_code (enum tree_code code, const_tree type, type-promotion (vec-unpack) 1 oprnd0 - - */ rtx -expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target, - int unsignedp) +expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op, + rtx target, int unsignedp) { tree oprnd0, oprnd1, oprnd2; enum machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode; @@ -541,19 +541,19 @@ expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target, rtx temp; rtx pat; rtx xop0, xop1, wxop; - int nops = TREE_OPERAND_LENGTH (exp); + int nops = TREE_CODE_LENGTH (ops->code); - oprnd0 = TREE_OPERAND (exp, 0); + oprnd0 = ops->op0; tmode0 = TYPE_MODE (TREE_TYPE (oprnd0)); widen_pattern_optab = - optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0), optab_default); + optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default); icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code; gcc_assert (icode != CODE_FOR_nothing); xmode0 = insn_data[icode].operand[1].mode; if (nops >= 2) { - oprnd1 = TREE_OPERAND (exp, 1); + oprnd1 = ops->op1; tmode1 = TYPE_MODE (TREE_TYPE (oprnd1)); xmode1 = insn_data[icode].operand[2].mode; } @@ -568,7 +568,7 @@ expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target, { gcc_assert (tmode1 == tmode0); gcc_assert (op1); - oprnd2 = TREE_OPERAND (exp, 2); + oprnd2 = ops->op2; wmode = TYPE_MODE (TREE_TYPE (oprnd2)); wxmode = insn_data[icode].operand[3].mode; } @@ -777,19 +777,19 @@ force_expand_binop (enum machine_mode mode, optab binoptab, /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */ rtx -expand_vec_shift_expr (tree vec_shift_expr, rtx target) +expand_vec_shift_expr (sepops ops, rtx target) { enum insn_code icode; rtx rtx_op1, rtx_op2; enum machine_mode mode1; enum machine_mode mode2; - enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr)); - tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0); - tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1); + enum machine_mode mode = TYPE_MODE (ops->type); + tree vec_oprnd = ops->op0; + tree shift_oprnd = ops->op1; optab shift_optab; rtx pat; - switch (TREE_CODE (vec_shift_expr)) + switch (ops->code) { case VEC_RSHIFT_EXPR: shift_optab = vec_shr_optab; @@ -6835,14 +6835,14 @@ vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode) return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1); } -/* Return insn code for VEC_COND_EXPR EXPR. */ +/* Return insn code for TYPE, the type of a VEC_COND_EXPR. */ static inline enum insn_code -get_vcond_icode (tree expr, enum machine_mode mode) +get_vcond_icode (tree type, enum machine_mode mode) { enum insn_code icode = CODE_FOR_nothing; - if (TYPE_UNSIGNED (TREE_TYPE (expr))) + if (TYPE_UNSIGNED (type)) icode = vcondu_gen_code[mode]; else icode = vcond_gen_code[mode]; @@ -6850,27 +6850,29 @@ get_vcond_icode (tree expr, enum machine_mode mode) } /* Return TRUE iff, appropriate vector insns are available - for vector cond expr expr in VMODE mode. */ + for vector cond expr with type TYPE in VMODE mode. */ bool -expand_vec_cond_expr_p (tree expr, enum machine_mode vmode) +expand_vec_cond_expr_p (tree type, enum machine_mode vmode) { - if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing) + if (get_vcond_icode (type, vmode) == CODE_FOR_nothing) return false; return true; } -/* Generate insns for VEC_COND_EXPR. */ +/* Generate insns for a VEC_COND_EXPR, given its TYPE and its + three operands. */ rtx -expand_vec_cond_expr (tree vec_cond_expr, rtx target) +expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, + rtx target) { enum insn_code icode; rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1; - enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr)); - bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr)); + enum machine_mode mode = TYPE_MODE (vec_cond_type); + bool unsignedp = TYPE_UNSIGNED (vec_cond_type); - icode = get_vcond_icode (vec_cond_expr, mode); + icode = get_vcond_icode (vec_cond_type, mode); if (icode == CODE_FOR_nothing) return 0; @@ -6878,17 +6880,17 @@ expand_vec_cond_expr (tree vec_cond_expr, rtx target) target = gen_reg_rtx (mode); /* Get comparison rtx. First expand both cond expr operands. */ - comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0), + comparison = vector_compare_rtx (op0, unsignedp, icode); cc_op0 = XEXP (comparison, 0); cc_op1 = XEXP (comparison, 1); /* Expand both operands and force them in reg, if required. */ - rtx_op1 = expand_normal (TREE_OPERAND (vec_cond_expr, 1)); + rtx_op1 = expand_normal (op1); if (!insn_data[icode].operand[1].predicate (rtx_op1, mode) && mode != VOIDmode) rtx_op1 = force_reg (mode, rtx_op1); - rtx_op2 = expand_normal (TREE_OPERAND (vec_cond_expr, 2)); + rtx_op2 = expand_normal (op2); if (!insn_data[icode].operand[2].predicate (rtx_op2, mode) && mode != VOIDmode) rtx_op2 = force_reg (mode, rtx_op2); diff --git a/gcc/optabs.h b/gcc/optabs.h index 2cb8f676f3e..af3ea66de87 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -670,7 +670,7 @@ extern enum insn_code sync_lock_release[NUM_MACHINE_MODES]; /* Define functions given in optabs.c. */ -extern rtx expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, +extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op, rtx target, int unsignedp); extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab, @@ -772,10 +772,9 @@ extern bool expand_sfix_optab (rtx, rtx, convert_optab); bool expand_vec_cond_expr_p (tree, enum machine_mode); /* Generate code for VEC_COND_EXPR. */ -extern rtx expand_vec_cond_expr (tree, rtx); - +extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx); /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */ -extern rtx expand_vec_shift_expr (tree, rtx); +extern rtx expand_vec_shift_expr (sepops, rtx); #define optab_handler(optab,mode) (&(optab)->handlers[(int) (mode)]) #define convert_optab_handler(optab,mode,mode2) \ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index aacf768a4cf..0a2ab19a232 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3889,7 +3889,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, if (!vec_stmt) { STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; - return expand_vec_cond_expr_p (op, vec_mode); + return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode); } /* Transform */ |