]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
expr.h (struct separate_ops, sepops): New type for passing around an exploded simple...
authorMichael Matz <matz@suse.de>
Tue, 25 Aug 2009 13:33:54 +0000 (13:33 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Tue, 25 Aug 2009 13:33:54 +0000 (13:33 +0000)
        * 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.

From-SVN: r151079

gcc/ChangeLog
gcc/expr.c
gcc/expr.h
gcc/optabs.c
gcc/optabs.h
gcc/tree-vect-stmts.c

index bb5e0b11eaf79c9cc6a4ada6df1b649b8db3caef..e99500ba5145f99dcbafac5806df967a550c1049 100644 (file)
@@ -1,3 +1,24 @@
+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,
index 7e316b547ad848115f3d797619e4369b34f27250..12d0dc99856d550fe4f2e01c584e0192bc46db83 100644 (file)
@@ -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;
 }
 \f
-/* 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;
index 7058354a86677422dc46f31c5cc5c36af1a88e72..228a34597beb0ff5af6c01a3e66a51324173a4c5 100644 (file)
@@ -267,6 +267,17 @@ do {                                                               \
 #define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)
 #endif
 \f
+/* 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;
+\f
 /* Functions from optabs.c, commonly used, and without need for the optabs
    tables:  */
 
index fcc1649caf32d598d8440f0be814f8dd53609aa2..61d8bcfe2986780953e0124ee3f6b7abbf5318cd 100644 (file)
@@ -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);
index 2cb8f676f3e7cf679a9cb91b1d2b2430773a6ac5..af3ea66de8731e855a50f24ae318d6a4a275c9ce 100644 (file)
@@ -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) \
index aacf768a4cf7f6035cdaf3437a69b05356275ef5..0a2ab19a232e2202eede110b29c0542306b0c7a8 100644 (file)
@@ -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 */