OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index fc311bc..7a0533e 100644 (file)
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "tree-ssa-sccvn.h"
+#include "tree-scalar-evolution.h"
 #include "params.h"
 #include "dbgcnt.h"
 
@@ -134,7 +135,7 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Representation of expressions on value numbers:
 
-   Expressions consisting of  value numbers are represented the same
+   Expressions consisting of value numbers are represented the same
    way as our VN internally represents them, with an additional
    "pre_expr" wrapping around them in order to facilitate storing all
    of the expressions in the same sets.  */
@@ -1290,7 +1291,7 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
   return NULL_TREE;
 }
 
-/* Like find_leader, but checks for the value existing in SET1 *or*
+/* Like bitmap_find_leader, but checks for the value existing in SET1 *or*
    SET2.  This is used to avoid making a set consisting of the union
    of PA_IN and ANTIC_IN during insert.  */
 
@@ -1599,6 +1600,9 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                else if (!opresult)
                  break;
              }
+           /* We can't possibly insert these.  */
+           else if (op1 && !is_gimple_min_invariant (op1))
+             break;
            changed |= op1 != oldop1;
            if (op2 && TREE_CODE (op2) == SSA_NAME)
              {
@@ -1616,6 +1620,9 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                else if (!opresult)
                  break;
              }
+           /* We can't possibly insert these.  */
+           else if (op2 && !is_gimple_min_invariant (op2))
+             break;
            changed |= op2 != oldop2;
 
            if (!newoperands)
@@ -1996,8 +2003,7 @@ vro_valid_in_sets (bitmap_set_t set1, bitmap_set_t set2,
    ONLY SET2 CAN BE NULL.
    This means that we have a leader for each part of the expression
    (if it consists of values), or the expression is an SSA_NAME.
-   For loads/calls, we also see if the vuse is killed in this block.
-*/
+   For loads/calls, we also see if the vuse is killed in this block.  */
 
 static bool
 valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
@@ -2562,8 +2568,8 @@ is_exception_related (gimple stmt)
              || gimple_assign_rhs_code (stmt) == EXC_PTR_EXPR));
 }
 
-/* Return true if OP is a tree which we can perform PRE on
-   on.  This may not match the operations we can value number, but in
+/* Return true if OP is a tree which we can perform PRE on.
+   This may not match the operations we can value number, but in
    a perfect world would.  */
 
 static bool
@@ -2742,7 +2748,8 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
        pre_expr op1expr;
        tree genop2 = currop->op1;
        pre_expr op2expr;
-       tree genop3;
+       tree genop3 = currop->op2;
+       pre_expr op3expr;
        genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
                                                   stmts, domstmt);
        if (!genop0)
@@ -2759,8 +2766,17 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
            if (!genop2)
              return NULL_TREE;
          }
-
-       genop3 = currop->op2;
+       if (genop3)
+         {
+           tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
+           genop3 = size_binop (EXACT_DIV_EXPR, genop3,
+                                size_int (TYPE_ALIGN_UNIT (elmt_type)));
+           op3expr = get_or_alloc_expr_for (genop3);
+           genop3 = find_or_generate_expression (block, op3expr, stmts,
+                                                 domstmt);
+           if (!genop3)
+             return NULL_TREE;
+         }
        return build4 (currop->opcode, currop->type, genop0, genop1,
                       genop2, genop3);
       }
@@ -3082,6 +3098,62 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
 }
 
 
+/* Returns true if we want to inhibit the insertions of PHI nodes
+   for the given EXPR for basic block BB (a member of a loop).
+   We want to do this, when we fear that the induction variable we
+   create might inhibit vectorization.  */
+
+static bool
+inhibit_phi_insertion (basic_block bb, pre_expr expr)
+{
+  vn_reference_t vr = PRE_EXPR_REFERENCE (expr);
+  VEC (vn_reference_op_s, heap) *ops = vr->operands;
+  vn_reference_op_t op;
+  unsigned i;
+
+  /* If we aren't going to vectorize we don't inhibit anything.  */
+  if (!flag_tree_vectorize)
+    return false;
+
+  /* Otherwise we inhibit the insertion when the address of the
+     memory reference is a simple induction variable.  In other
+     cases the vectorizer won't do anything anyway (either it's
+     loop invariant or a complicated expression).  */
+  for (i = 0; VEC_iterate (vn_reference_op_s, ops, i, op); ++i)
+    {
+      switch (op->opcode)
+       {
+       case ARRAY_REF:
+       case ARRAY_RANGE_REF:
+         if (TREE_CODE (op->op0) != SSA_NAME)
+           break;
+         /* Fallthru.  */
+       case SSA_NAME:
+         {
+           basic_block defbb = gimple_bb (SSA_NAME_DEF_STMT (op->op0));
+           affine_iv iv;
+           /* Default defs are loop invariant.  */
+           if (!defbb)
+             break;
+           /* Defined outside this loop, also loop invariant.  */
+           if (!flow_bb_inside_loop_p (bb->loop_father, defbb))
+             break;
+           /* If it's a simple induction variable inhibit insertion,
+              the vectorizer might be interested in this one.  */
+           if (simple_iv (bb->loop_father, bb->loop_father,
+                          op->op0, &iv, true))
+             return true;
+           /* No simple IV, vectorizer can't do anything, hence no
+              reason to inhibit the transformation for this operand.  */
+           break;
+         }
+       default:
+         break;
+       }
+    }
+  return false;
+}
+
 /* Insert the to-be-made-available values of expression EXPRNUM for each
    predecessor, stored in AVAIL, into the predecessors of BLOCK, and
    merge the result with a phi node, given the same value number as
@@ -3112,8 +3184,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
     }
 
   /* Make sure we aren't creating an induction variable.  */
-  if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
-      && expr->kind != REFERENCE)
+  if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2)
     {
       bool firstinsideloop = false;
       bool secondinsideloop = false;
@@ -3122,7 +3193,9 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
       secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
                                                EDGE_PRED (block, 1)->src);
       /* Induction variables only have one edge inside the loop.  */
-      if (firstinsideloop ^ secondinsideloop)
+      if ((firstinsideloop ^ secondinsideloop)
+         && (expr->kind != REFERENCE
+             || inhibit_phi_insertion (block, expr)))
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
@@ -3271,9 +3344,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
       gcc_assert (get_expr_type (ae) == type
                  || useless_type_conversion_p (type, get_expr_type (ae)));
       if (ae->kind == CONSTANT)
-       add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred);
+       add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION);
       else
-       add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred);
+       add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
+                    UNKNOWN_LOCATION);
     }
 
   newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
@@ -3625,11 +3699,7 @@ insert (void)
 }
 
 
-/* Add OP to EXP_GEN (block), and possibly to the maximal set if it is
-   not defined by a phi node.
-   PHI nodes can't go in the maximal sets because they are not in
-   TMP_GEN, so it is possible to get into non-monotonic situations
-   during ANTIC calculation, because it will *add* bits.  */
+/* Add OP to EXP_GEN (block), and possibly to the maximal set.  */
 
 static void
 add_to_exp_gen (basic_block block, tree op)
@@ -3641,9 +3711,7 @@ add_to_exp_gen (basic_block block, tree op)
        return;
       result = get_or_alloc_expr_for_name (op);
       bitmap_value_insert_into_set (EXP_GEN (block), result);
-      if (TREE_CODE (op) != SSA_NAME
-         || gimple_code (SSA_NAME_DEF_STMT (op)) != GIMPLE_PHI)
-       bitmap_value_insert_into_set (maximal_set, result);
+      bitmap_value_insert_into_set (maximal_set, result);
     }
 }
 
@@ -3662,6 +3730,20 @@ make_values_for_phi (gimple phi, basic_block block)
       add_to_value (get_expr_value_id (e), e);
       bitmap_insert_into_set (PHI_GEN (block), e);
       bitmap_value_insert_into_set (AVAIL_OUT (block), e);
+      if (!in_fre)
+       {
+         unsigned i;
+         for (i = 0; i < gimple_phi_num_args (phi); ++i)
+           {
+             tree arg = gimple_phi_arg_def (phi, i);
+             if (TREE_CODE (arg) == SSA_NAME)
+               {
+                 e = get_or_alloc_expr_for_name (arg);
+                 add_to_value (get_expr_value_id (e), e);
+                 bitmap_value_insert_into_set (maximal_set, e);
+               }
+           }
+       }
     }
 }
 
@@ -4151,7 +4233,12 @@ eliminate (void)
                  gimple_call_set_fn (stmt, fn);
                  update_stmt (stmt);
                  if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
-                   gimple_purge_dead_eh_edges (b);
+                   {
+                     bitmap_set_bit (need_eh_cleanup,
+                                     gimple_bb (stmt)->index);
+                     if (dump_file && (dump_flags & TDF_DETAILS))
+                       fprintf (dump_file, "  Removed EH side effects.\n");
+                   }
 
                  /* Changing an indirect call to a direct call may
                     have exposed different semantics.  This may
@@ -4497,6 +4584,7 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSED)
       return 0;
     }
   init_pre (do_fre);
+  scev_initialize ();
 
 
   /* Collect and value number expressions computed in each basic block.  */
@@ -4509,11 +4597,12 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSED)
       FOR_ALL_BB (bb)
        {
          print_bitmap_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
-         print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen",
-                                 bb->index);
-         print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out",
-                                 bb->index);
+         print_bitmap_set (dump_file, PHI_GEN (bb), "phi_gen", bb->index);
+         print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen", bb->index);
+         print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out", bb->index);
        }
+
+      print_bitmap_set (dump_file, maximal_set, "maximal", 0);
     }
 
   /* Insert can get quite slow on an incredibly large number of basic
@@ -4547,6 +4636,7 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSED)
   if (!do_fre)
     remove_dead_inserted_code ();
 
+  scev_finalize ();
   fini_pre (do_fre);
 
   return todo;