summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-25 13:33:54 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-25 13:33:54 +0000
commit2c02962cf935ac329a5069f6721839c3c1a3d331 (patch)
tree21065dda4814644807909923e74947363f96ca60
parent588e1cc345332f6d464f2de3aa43692535094ab5 (diff)
downloadgcc-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/ChangeLog21
-rw-r--r--gcc/expr.c52
-rw-r--r--gcc/expr.h11
-rw-r--r--gcc/optabs.c54
-rw-r--r--gcc/optabs.h7
-rw-r--r--gcc/tree-vect-stmts.c2
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 */