OSDN Git Service

Implement -Wno-maybe-uninitialized
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index 8293e97..a833a04 100644 (file)
@@ -484,10 +484,12 @@ static tree pretemp;
 static tree storetemp;
 static tree prephitemp;
 
-/* Set of blocks with statements that have had its EH information
-   cleaned up.  */
+/* Set of blocks with statements that have had their EH properties changed.  */
 static bitmap need_eh_cleanup;
 
+/* Set of blocks with statements that have had their AB properties changed.  */
+static bitmap need_ab_cleanup;
+
 /* The phi_translate_table caches phi translations for a given
    expression and predecessor.  */
 
@@ -578,8 +580,7 @@ phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
 
   slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
                                   new_pair->hashcode, INSERT);
-  if (*slot)
-    free (*slot);
+  free (*slot);
   *slot = (void *) new_pair;
 }
 
@@ -855,9 +856,8 @@ bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
   exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
   FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
     {
-      if (bitmap_bit_p (&set->expressions, i))
+      if (bitmap_clear_bit (&set->expressions, i))
        {
-         bitmap_clear_bit (&set->expressions, i);
          bitmap_set_bit (&set->expressions, get_expression_id (expr));
          return;
        }
@@ -894,9 +894,7 @@ bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr)
 {
   unsigned int val = get_expr_value_id (expr);
 
-#ifdef ENABLE_CHECKING
-  gcc_assert (expr->id == get_or_alloc_expression_id (expr));
-#endif
+  gcc_checking_assert (expr->id == get_or_alloc_expression_id (expr));
 
   /* Constant values are always considered to be part of the set.  */
   if (value_id_constant_p (val))
@@ -1682,7 +1680,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
            tree result = vn_reference_lookup_pieces (newvuse, ref->set,
                                                      ref->type,
                                                      newoperands,
-                                                     &newref, true);
+                                                     &newref, VN_WALK);
            if (result)
              VEC_free (vn_reference_op_s, heap, newoperands);
 
@@ -1692,6 +1690,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
                result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result);
                converted = true;
              }
+           else if (!result && newref
+                    && !useless_type_conversion_p (ref->type, newref->type))
+             {
+               VEC_free (vn_reference_op_s, heap, newoperands);
+               return NULL;
+             }
 
            if (result && is_gimple_min_invariant (result))
              {
@@ -1887,7 +1891,7 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
     }
 
   exprs = sorted_array_from_bitmap_set (set);
-  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
+  FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
     {
       pre_expr translated;
       translated = phi_translate (expr, set, NULL, pred, phiblock);
@@ -2151,7 +2155,7 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
        vn_reference_op_t vro;
        unsigned int i;
 
-       for (i = 0; VEC_iterate (vn_reference_op_s, ref->operands, i, vro); i++)
+       FOR_EACH_VEC_ELT (vn_reference_op_s, ref->operands, i, vro)
          {
            if (!vro_valid_in_sets (set1, set2, vro))
              return false;
@@ -2185,7 +2189,7 @@ dependent_clean (bitmap_set_t set1, bitmap_set_t set2, basic_block block)
   pre_expr expr;
   int i;
 
-  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
+  FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
     {
       if (!valid_in_sets (set1, set2, expr, block))
        bitmap_remove_from_set (set1, expr);
@@ -2204,7 +2208,7 @@ clean (bitmap_set_t set, basic_block block)
   pre_expr expr;
   int i;
 
-  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
+  FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
     {
       if (!valid_in_sets (set, NULL, expr, block))
        bitmap_remove_from_set (set, expr);
@@ -2338,7 +2342,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
       else
        bitmap_set_copy (ANTIC_OUT, ANTIC_IN (first));
 
-      for (i = 0; VEC_iterate (basic_block, worklist, i, bprime); i++)
+      FOR_EACH_VEC_ELT (basic_block, worklist, i, bprime)
        {
          if (!gimple_seq_empty_p (phi_nodes (bprime)))
            {
@@ -2481,7 +2485,7 @@ compute_partial_antic_aux (basic_block block,
        }
       if (VEC_length (basic_block, worklist) > 0)
        {
-         for (i = 0; VEC_iterate (basic_block, worklist, i, bprime); i++)
+         FOR_EACH_VEC_ELT (basic_block, worklist, i, bprime)
            {
              unsigned int i;
              bitmap_iterator bi;
@@ -2595,6 +2599,10 @@ compute_antic (void)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Starting iteration %d\n", num_iterations);
+      /* ???  We need to clear our PHI translation cache here as the
+         ANTIC sets shrink and we restrict valid translations to
+        those having operands with leaders in ANTIC.  Same below
+        for PA ANTIC computation.  */
       num_iterations++;
       changed = false;
       for (i = n_basic_blocks - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
@@ -2607,10 +2615,8 @@ compute_antic (void)
                                                      block->index));
            }
        }
-#ifdef ENABLE_CHECKING
       /* Theoretically possible, but *highly* unlikely.  */
-      gcc_assert (num_iterations < 500);
-#endif
+      gcc_checking_assert (num_iterations < 500);
     }
 
   statistics_histogram_event (cfun, "compute_antic iterations",
@@ -2639,10 +2645,8 @@ compute_antic (void)
                                                            block->index));
                }
            }
-#ifdef ENABLE_CHECKING
          /* Theoretically possible, but *highly* unlikely.  */
-         gcc_assert (num_iterations < 500);
-#endif
+         gcc_checking_assert (num_iterations < 500);
        }
       statistics_histogram_event (cfun, "compute_partial_antic iterations",
                                  num_iterations);
@@ -2652,11 +2656,13 @@ compute_antic (void)
 }
 
 /* Return true if we can value number the call in STMT.  This is true
-   if we have a pure or constant call.  */
+   if we have a pure or constant call to a real function.  */
 
 static bool
 can_value_number_call (gimple stmt)
 {
+  if (gimple_call_internal_p (stmt))
+    return false;
   if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
     return true;
   return false;
@@ -2773,10 +2779,10 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
       break;
     case TARGET_MEM_REF:
       {
+       pre_expr op0expr, op1expr;
+       tree genop0 = NULL_TREE, genop1 = NULL_TREE;
        vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
-                                             *operand);
-       pre_expr op0expr;
-       tree genop0 = NULL_TREE;
+                                             ++*operand);
        tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
                                                        stmts, domstmt);
        if (!baseop)
@@ -2789,16 +2795,16 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
            if (!genop0)
              return NULL_TREE;
          }
-       if (DECL_P (baseop))
-         return build6 (TARGET_MEM_REF, currop->type,
-                        baseop, NULL_TREE,
-                        genop0, currop->op1, currop->op2,
-                        unshare_expr (nextop->op1));
-       else
-         return build6 (TARGET_MEM_REF, currop->type,
-                        NULL_TREE, baseop,
-                        genop0, currop->op1, currop->op2,
-                        unshare_expr (nextop->op1));
+       if (nextop->op0)
+         {
+           op1expr = get_or_alloc_expr_for (nextop->op0);
+           genop1 = find_or_generate_expression (block, op1expr,
+                                                 stmts, domstmt);
+           if (!genop1)
+             return NULL_TREE;
+         }
+       return build5 (TARGET_MEM_REF, currop->type,
+                      baseop, currop->op2, genop0, currop->op1, genop1);
       }
       break;
     case ADDR_EXPR:
@@ -2823,26 +2829,6 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
        return folded;
       }
       break;
-    case MISALIGNED_INDIRECT_REF:
-      {
-       tree folded;
-       tree genop1 = create_component_ref_by_pieces_1 (block, ref,
-                                                       operand,
-                                                       stmts, domstmt);
-       if (!genop1)
-         return NULL_TREE;
-       genop1 = fold_convert (build_pointer_type (currop->type),
-                              genop1);
-
-       if (currop->opcode == MISALIGNED_INDIRECT_REF)
-         folded = fold_build2 (currop->opcode, currop->type,
-                               genop1, currop->op1);
-       else
-         folded = fold_build1 (currop->opcode, currop->type,
-                               genop1);
-       return folded;
-      }
-      break;
     case BIT_FIELD_REF:
       {
        tree folded;
@@ -2889,8 +2875,11 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
          return NULL_TREE;
        if (genop2)
          {
-           /* Drop zero minimum index.  */
-           if (tree_int_cst_equal (genop2, integer_zero_node))
+           tree domain_type = TYPE_DOMAIN (TREE_TYPE (genop0));
+           /* Drop zero minimum index if redundant.  */
+           if (integer_zerop (genop2)
+               && (!domain_type
+                   || integer_zerop (TYPE_MIN_VALUE (domain_type))))
              genop2 = NULL_TREE;
            else
              {
@@ -3264,7 +3253,7 @@ inhibit_phi_insertion (basic_block bb, pre_expr expr)
      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)
+  FOR_EACH_VEC_ELT (vn_reference_op_s, ops, i, op)
     {
       switch (op->opcode)
        {
@@ -3551,7 +3540,7 @@ do_regular_insertion (basic_block block, basic_block dom)
   pre_expr expr;
   int i;
 
-  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
+  FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
     {
       if (expr->kind != NAME)
        {
@@ -3632,11 +3621,23 @@ do_regular_insertion (basic_block block, basic_block dom)
             already existing along every predecessor, and
             it's defined by some predecessor, it is
             partially redundant.  */
-         if (!cant_insert && !all_same && by_some && do_insertion
-             && dbg_cnt (treepre_insert))
+         if (!cant_insert && !all_same && by_some)
            {
-             if (insert_into_preds_of_block (block, get_expression_id (expr),
-                                             avail))
+             if (!do_insertion)
+               {
+                 if (dump_file && (dump_flags & TDF_DETAILS))
+                   {
+                     fprintf (dump_file, "Skipping partial redundancy for "
+                              "expression ");
+                     print_pre_expr (dump_file, expr);
+                     fprintf (dump_file, " (%04d), no redundancy on to be "
+                              "optimized for speed edge\n", val);
+                   }
+               }
+             else if (dbg_cnt (treepre_insert)
+                      && insert_into_preds_of_block (block,
+                                                     get_expression_id (expr),
+                                                     avail))
                new_stuff = true;
            }
          /* If all edges produce the same value and that value is
@@ -3697,7 +3698,7 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
   pre_expr expr;
   int i;
 
-  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
+  FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
     {
       if (expr->kind != NAME)
        {
@@ -4024,7 +4025,7 @@ compute_avail (void)
                copy_reference_ops_from_call (stmt, &ops);
                vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
                                            gimple_expr_type (stmt),
-                                           ops, &ref, false);
+                                           ops, &ref, VN_NOWALK);
                VEC_free (vn_reference_op_s, heap, ops);
                if (!ref)
                  continue;
@@ -4094,7 +4095,7 @@ compute_avail (void)
 
                      vn_reference_lookup (gimple_assign_rhs1 (stmt),
                                           gimple_vuse (stmt),
-                                          true, &ref);
+                                          VN_WALK, &ref);
                      if (!ref)
                        continue;
 
@@ -4274,6 +4275,10 @@ eliminate (void)
                      || TREE_CODE (rhs) != SSA_NAME
                      || may_propagate_copy (rhs, sprime)))
                {
+                 bool can_make_abnormal_goto
+                   = is_gimple_call (stmt)
+                     && stmt_can_make_abnormal_goto (stmt);
+
                  gcc_assert (sprime != rhs);
 
                  if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4302,14 +4307,24 @@ eliminate (void)
                  stmt = gsi_stmt (gsi);
                  update_stmt (stmt);
 
-                 /* If we removed EH side effects from the statement, clean
+                 /* If we removed EH side-effects from the statement, clean
                     its EH information.  */
                  if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
                    {
                      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");
+                       fprintf (dump_file, "  Removed EH side-effects.\n");
+                   }
+
+                 /* Likewise for AB side-effects.  */
+                 if (can_make_abnormal_goto
+                     && !stmt_can_make_abnormal_goto (stmt))
+                   {
+                     bitmap_set_bit (need_ab_cleanup,
+                                     gimple_bb (stmt)->index);
+                     if (dump_file && (dump_flags & TDF_DETAILS))
+                       fprintf (dump_file, "  Removed AB side-effects.\n");
                    }
                }
            }
@@ -4324,7 +4339,7 @@ eliminate (void)
              tree rhs = gimple_assign_rhs1 (stmt);
              tree val;
              val = vn_reference_lookup (gimple_assign_lhs (stmt),
-                                        gimple_vuse (stmt), true, NULL);
+                                        gimple_vuse (stmt), VN_WALK, NULL);
              if (TREE_CODE (rhs) == SSA_NAME)
                rhs = VN_INFO (rhs)->valnum;
              if (val
@@ -4366,13 +4381,27 @@ eliminate (void)
            }
          /* Visit indirect calls and turn them into direct calls if
             possible.  */
-         if (gimple_code (stmt) == GIMPLE_CALL
-             && TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME)
+         if (is_gimple_call (stmt))
            {
-             tree fn = VN_INFO (gimple_call_fn (stmt))->valnum;
-             if (TREE_CODE (fn) == ADDR_EXPR
-                 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
+             tree orig_fn = gimple_call_fn (stmt);
+             tree fn;
+             if (!orig_fn)
+               continue;
+             if (TREE_CODE (orig_fn) == SSA_NAME)
+               fn = VN_INFO (orig_fn)->valnum;
+             else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF
+                      && TREE_CODE (OBJ_TYPE_REF_EXPR (orig_fn)) == SSA_NAME)
+               fn = VN_INFO (OBJ_TYPE_REF_EXPR (orig_fn))->valnum;
+             else
+               continue;
+             if (gimple_call_addr_fndecl (fn) != NULL_TREE
+                 && useless_type_conversion_p (TREE_TYPE (orig_fn),
+                                               TREE_TYPE (fn)))
                {
+                 bool can_make_abnormal_goto
+                   = stmt_can_make_abnormal_goto (stmt);
+                 bool was_noreturn = gimple_call_noreturn_p (stmt);
+
                  if (dump_file && (dump_flags & TDF_DETAILS))
                    {
                      fprintf (dump_file, "Replacing call target with ");
@@ -4383,12 +4412,30 @@ eliminate (void)
 
                  gimple_call_set_fn (stmt, fn);
                  update_stmt (stmt);
+
+                 /* When changing a call into a noreturn call, cfg cleanup
+                    is needed to fix up the noreturn call.  */
+                 if (!was_noreturn && gimple_call_noreturn_p (stmt))
+                   todo |= TODO_cleanup_cfg;
+
+                 /* If we removed EH side-effects from the statement, clean
+                    its EH information.  */
                  if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
                    {
                      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");
+                       fprintf (dump_file, "  Removed EH side-effects.\n");
+                   }
+
+                 /* Likewise for AB side-effects.  */
+                 if (can_make_abnormal_goto
+                     && !stmt_can_make_abnormal_goto (stmt))
+                   {
+                     bitmap_set_bit (need_ab_cleanup,
+                                     gimple_bb (stmt)->index);
+                     if (dump_file && (dump_flags & TDF_DETAILS))
+                       fprintf (dump_file, "  Removed AB side-effects.\n");
                    }
 
                  /* Changing an indirect call to a direct call may
@@ -4478,7 +4525,7 @@ eliminate (void)
   /* We cannot remove stmts during BB walk, especially not release SSA
      names there as this confuses the VN machinery.  The stmts ending
      up in to_remove are either stores or simple copies.  */
-  for (i = 0; VEC_iterate (gimple, to_remove, i, stmt); ++i)
+  FOR_EACH_VEC_ELT (gimple, to_remove, i, stmt)
     {
       tree lhs = gimple_assign_lhs (stmt);
       tree rhs = gimple_assign_rhs1 (stmt);
@@ -4503,9 +4550,12 @@ eliminate (void)
       if (TREE_CODE (lhs) != SSA_NAME
          || has_zero_uses (lhs))
        {
+         basic_block bb = gimple_bb (stmt);
          gsi = gsi_for_stmt (stmt);
          unlink_stmt_vdef (stmt);
          gsi_remove (&gsi, true);
+         if (gimple_purge_dead_eh_edges (bb))
+           todo |= TODO_cleanup_cfg;
          if (TREE_CODE (lhs) == SSA_NAME)
            bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
          release_defs (stmt);
@@ -4740,8 +4790,7 @@ init_pre (bool do_fre)
   postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
   my_rev_post_order_compute (postorder, false);
 
-  FOR_ALL_BB (bb)
-    bb->aux = XCNEWVEC (struct bb_bitmap_sets, 1);
+  alloc_aux_for_blocks (sizeof (struct bb_bitmap_sets));
 
   calculate_dominance_info (CDI_POST_DOMINATORS);
   calculate_dominance_info (CDI_DOMINATORS);
@@ -4765,6 +4814,7 @@ init_pre (bool do_fre)
     }
 
   need_eh_cleanup = BITMAP_ALLOC (NULL);
+  need_ab_cleanup = BITMAP_ALLOC (NULL);
 }
 
 
@@ -4773,8 +4823,6 @@ init_pre (bool do_fre)
 static void
 fini_pre (bool do_fre)
 {
-  basic_block bb;
-
   free (postorder);
   VEC_free (bitmap_set_t, heap, value_expressions);
   BITMAP_FREE (inserted_exprs);
@@ -4786,11 +4834,7 @@ fini_pre (bool do_fre)
   htab_delete (expression_to_id);
   VEC_free (unsigned, heap, name_to_id);
 
-  FOR_ALL_BB (bb)
-    {
-      free (bb->aux);
-      bb->aux = NULL;
-    }
+  free_aux_for_blocks ();
 
   free_dominance_info (CDI_POST_DOMINATORS);
 
@@ -4802,6 +4846,14 @@ fini_pre (bool do_fre)
 
   BITMAP_FREE (need_eh_cleanup);
 
+  if (!bitmap_empty_p (need_ab_cleanup))
+    {
+      gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
+      cleanup_tree_cfg ();
+    }
+
+  BITMAP_FREE (need_ab_cleanup);
+
   if (!do_fre)
     loop_optimizer_finalize ();
 }
@@ -4821,7 +4873,7 @@ execute_pre (bool do_fre)
   if (!do_fre)
     loop_optimizer_init (LOOPS_NORMAL);
 
-  if (!run_scc_vn ())
+  if (!run_scc_vn (do_fre ? VN_WALKREWRITE : VN_WALK))
     {
       if (!do_fre)
        loop_optimizer_finalize ();
@@ -4877,7 +4929,10 @@ execute_pre (bool do_fre)
   clear_expression_ids ();
   free_scc_vn ();
   if (!do_fre)
-    remove_dead_inserted_code ();
+    {
+      remove_dead_inserted_code ();
+      todo |= TODO_verify_flow;
+    }
 
   scev_finalize ();
   fini_pre (do_fre);