OSDN Git Service

Add TLS checks to ObjC
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index dd9fb96..ac676cd 100644 (file)
@@ -1407,7 +1407,7 @@ get_representative_for (const pre_expr e)
      that we will return.  */
   if (!pretemp || exprtype != TREE_TYPE (pretemp))
     {
-      pretemp = create_tmp_var (exprtype, "pretmp");
+      pretemp = create_tmp_reg (exprtype, "pretmp");
       get_var_ann (pretemp);
     }
 
@@ -2608,8 +2608,7 @@ can_PRE_operation (tree op)
 /* Inserted expressions are placed onto this worklist, which is used
    for performing quick dead code elimination of insertions we made
    that didn't turn out to be necessary.   */
-static VEC(gimple,heap) *inserted_exprs;
-static bitmap inserted_phi_names;
+static bitmap inserted_exprs;
 
 /* Pool allocated fake store expressions are placed onto this
    worklist, which, after performing dead code elimination, is walked
@@ -2631,31 +2630,46 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
     {
     case CALL_EXPR:
       {
-       tree folded, sc = currop->op1;
+       tree folded, sc = NULL_TREE;
        unsigned int nargs = 0;
-       tree *args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
-                                               ref->operands) - 1);
+       tree fn, *args;
+       if (TREE_CODE (currop->op0) == FUNCTION_DECL)
+         fn = currop->op0;
+       else
+         {
+           pre_expr op0 = get_or_alloc_expr_for (currop->op0);
+           fn = find_or_generate_expression (block, op0, stmts, domstmt);
+           if (!fn)
+             return NULL_TREE;
+         }
+       if (currop->op1)
+         {
+           pre_expr scexpr = get_or_alloc_expr_for (currop->op1);
+           sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
+           if (!sc)
+             return NULL_TREE;
+         }
+       args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
+                                         ref->operands) - 1);
        while (*operand < VEC_length (vn_reference_op_s, ref->operands))
          {
            args[nargs] = create_component_ref_by_pieces_1 (block, ref,
                                                            operand, stmts,
                                                            domstmt);
+           if (!args[nargs])
+             {
+               free (args);
+               return NULL_TREE;
+             }
            nargs++;
          }
        folded = build_call_array (currop->type,
-                                  TREE_CODE (currop->op0) == FUNCTION_DECL
-                                  ? build_fold_addr_expr (currop->op0)
-                                  : currop->op0,
+                                  (TREE_CODE (fn) == FUNCTION_DECL
+                                   ? build_fold_addr_expr (fn) : fn),
                                   nargs, args);
        free (args);
        if (sc)
-         {
-           pre_expr scexpr = get_or_alloc_expr_for (sc);
-           sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
-           if (!sc)
-             return NULL_TREE;
-           CALL_EXPR_STATIC_CHAIN (folded) = sc;
-         }
+         CALL_EXPR_STATIC_CHAIN (folded) = sc;
        return folded;
       }
       break;
@@ -3068,9 +3082,9 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
          tree forcedname = gimple_get_lhs (stmt);
          pre_expr nameexpr;
 
-         VEC_safe_push (gimple, heap, inserted_exprs, stmt);
          if (TREE_CODE (forcedname) == SSA_NAME)
            {
+             bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
              VN_INFO_GET (forcedname)->valnum = forcedname;
              VN_INFO (forcedname)->value_id = get_next_value_id ();
              nameexpr = get_or_alloc_expr_for_name (forcedname);
@@ -3088,24 +3102,20 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
      that we will return.  */
   if (!pretemp || exprtype != TREE_TYPE (pretemp))
     {
-      pretemp = create_tmp_var (exprtype, "pretmp");
+      pretemp = create_tmp_reg (exprtype, "pretmp");
       get_var_ann (pretemp);
     }
 
   temp = pretemp;
   add_referenced_var (temp);
 
-  if (TREE_CODE (exprtype) == COMPLEX_TYPE
-      || TREE_CODE (exprtype) == VECTOR_TYPE)
-    DECL_GIMPLE_REG_P (temp) = 1;
-
   newstmt = gimple_build_assign (temp, folded);
   name = make_ssa_name (temp, newstmt);
   gimple_assign_set_lhs (newstmt, name);
   gimple_set_plf (newstmt, NECESSARY, false);
 
   gimple_seq_add_stmt (stmts, newstmt);
-  VEC_safe_push (gimple, heap, inserted_exprs, newstmt);
+  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
 
   /* All the symbols in NEWEXPR should be put into SSA form.  */
   mark_symbols_for_renaming (newstmt);
@@ -3288,7 +3298,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
                          for (; !gsi_end_p (gsi); gsi_next (&gsi))
                            {
                              gimple stmt = gsi_stmt (gsi);
-                             VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+                             tree lhs = gimple_get_lhs (stmt);
+                             if (TREE_CODE (lhs) == SSA_NAME)
+                               bitmap_set_bit (inserted_exprs,
+                                               SSA_NAME_VERSION (lhs));
                              gimple_set_plf (stmt, NECESSARY, false);
                            }
                          gsi_insert_seq_on_edge (pred, stmts);
@@ -3327,7 +3340,9 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
                  for (; !gsi_end_p (gsi); gsi_next (&gsi))
                    {
                      gimple stmt = gsi_stmt (gsi);
-                     VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+                     tree lhs = gimple_get_lhs (stmt);
+                     if (TREE_CODE (lhs) == SSA_NAME)
+                       bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
                      gimple_set_plf (stmt, NECESSARY, false);
                    }
                  gsi_insert_seq_on_edge (pred, stmts);
@@ -3363,9 +3378,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
   gimple_set_plf (phi, NECESSARY, false);
   VN_INFO_GET (gimple_phi_result (phi))->valnum = gimple_phi_result (phi);
   VN_INFO (gimple_phi_result (phi))->value_id = val;
-  VEC_safe_push (gimple, heap, inserted_exprs, phi);
-  bitmap_set_bit (inserted_phi_names,
-                 SSA_NAME_VERSION (gimple_phi_result (phi)));
+  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (gimple_phi_result (phi)));
   FOR_EACH_EDGE (pred, ei, block->preds)
     {
       pre_expr ae = avail[pred->src->index];
@@ -4298,8 +4311,7 @@ eliminate (void)
             replacing the PHI with a single copy if possible.
             Do not touch inserted, single-argument or virtual PHIs.  */
          if (gimple_phi_num_args (phi) == 1
-             || !is_gimple_reg (res)
-             || bitmap_bit_p (inserted_phi_names, SSA_NAME_VERSION (res)))
+             || !is_gimple_reg (res))
            {
              gsi_next (&gsi);
              continue;
@@ -4339,14 +4351,17 @@ eliminate (void)
            sprime = fold_convert (TREE_TYPE (res), sprime);
          stmt = gimple_build_assign (res, sprime);
          SSA_NAME_DEF_STMT (res) = stmt;
-         if (TREE_CODE (sprime) == SSA_NAME)
-           gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
-                           NECESSARY, true);
+         gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY));
+
          gsi2 = gsi_after_labels (b);
          gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
          /* Queue the copy for eventual removal.  */
          VEC_safe_push (gimple, heap, to_remove, stmt);
-         pre_stats.eliminations++;
+         /* If we inserted this PHI node ourself, it's not an elimination.  */
+         if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
+           pre_stats.phis--;
+         else
+           pre_stats.eliminations++;
        }
     }
 
@@ -4367,8 +4382,11 @@ eliminate (void)
          && single_imm_use (lhs, &use_p, &use_stmt)
          && may_propagate_copy (USE_FROM_PTR (use_p), rhs))
        {
-         SET_USE (use_p, gimple_assign_rhs1 (stmt));
+         SET_USE (use_p, rhs);
          update_stmt (use_stmt);
+         if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs))
+             && TREE_CODE (rhs) == SSA_NAME)
+           gimple_set_plf (SSA_NAME_DEF_STMT (rhs), NECESSARY, true);
        }
 
       /* If this is a store or a now unused copy, remove it.  */
@@ -4378,6 +4396,8 @@ eliminate (void)
          gsi = gsi_for_stmt (stmt);
          unlink_stmt_vdef (stmt);
          gsi_remove (&gsi, true);
+         if (TREE_CODE (lhs) == SSA_NAME)
+           bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
          release_defs (stmt);
        }
     }
@@ -4423,19 +4443,23 @@ mark_operand_necessary (tree op)
 static void
 remove_dead_inserted_code (void)
 {
-  VEC(gimple,heap) *worklist = NULL;
-  int i;
+  bitmap worklist;
+  unsigned i;
+  bitmap_iterator bi;
   gimple t;
 
-  worklist = VEC_alloc (gimple, heap, VEC_length (gimple, inserted_exprs));
-  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
+  worklist = BITMAP_ALLOC (NULL);
+  EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
     {
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
       if (gimple_plf (t, NECESSARY))
-       VEC_quick_push (gimple, worklist, t);
+       bitmap_set_bit (worklist, i);
     }
-  while (VEC_length (gimple, worklist) > 0)
+  while (!bitmap_empty_p (worklist))
     {
-      t = VEC_pop (gimple, worklist);
+      i = bitmap_first_set_bit (worklist);
+      bitmap_clear_bit (worklist, i);
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
 
       /* PHI nodes are somewhat special in that each PHI alternative has
         data and control dependencies.  All the statements feeding the
@@ -4444,7 +4468,6 @@ remove_dead_inserted_code (void)
        {
          unsigned k;
 
-         VEC_reserve (gimple, heap, worklist, gimple_phi_num_args (t));
          for (k = 0; k < gimple_phi_num_args (t); k++)
            {
              tree arg = PHI_ARG_DEF (t, k);
@@ -4452,7 +4475,7 @@ remove_dead_inserted_code (void)
                {
                  gimple n = mark_operand_necessary (arg);
                  if (n)
-                   VEC_quick_push (gimple, worklist, n);
+                   bitmap_set_bit (worklist, SSA_NAME_VERSION (arg));
                }
            }
        }
@@ -4473,13 +4496,14 @@ remove_dead_inserted_code (void)
            {
              gimple n = mark_operand_necessary (use);
              if (n)
-               VEC_safe_push (gimple, heap, worklist, n);
+               bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
            }
        }
     }
 
-  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
+  EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
     {
+      t = SSA_NAME_DEF_STMT (ssa_name (i));
       if (!gimple_plf (t, NECESSARY))
        {
          gimple_stmt_iterator gsi;
@@ -4500,7 +4524,7 @@ remove_dead_inserted_code (void)
            }
        }
     }
-  VEC_free (gimple, heap, worklist);
+  BITMAP_FREE (worklist);
 }
 
 /* Compute a reverse post-order in *POST_ORDER.  If INCLUDE_ENTRY_EXIT is
@@ -4593,7 +4617,7 @@ init_pre (bool do_fre)
 
   in_fre = do_fre;
 
-  inserted_exprs = NULL;
+  inserted_exprs = BITMAP_ALLOC (NULL);
   need_creation = NULL;
   pretemp = NULL_TREE;
   storetemp = NULL_TREE;
@@ -4613,7 +4637,6 @@ init_pre (bool do_fre)
   calculate_dominance_info (CDI_DOMINATORS);
 
   bitmap_obstack_initialize (&grand_bitmap_obstack);
-  inserted_phi_names = BITMAP_ALLOC (&grand_bitmap_obstack);
   phi_translate_table = htab_create (5110, expr_pred_trans_hash,
                                     expr_pred_trans_eq, free);
   expression_to_id = htab_create (num_ssa_names * 3,
@@ -4644,7 +4667,7 @@ fini_pre (bool do_fre)
 
   free (postorder);
   VEC_free (bitmap_set_t, heap, value_expressions);
-  VEC_free (gimple, heap, inserted_exprs);
+  BITMAP_FREE (inserted_exprs);
   VEC_free (gimple, heap, need_creation);
   bitmap_obstack_release (&grand_bitmap_obstack);
   free_alloc_pool (bitmap_set_pool);
@@ -4691,17 +4714,14 @@ execute_pre (bool do_fre)
   if (!run_scc_vn (do_fre))
     {
       if (!do_fre)
-       {
-         remove_dead_inserted_code ();
-         loop_optimizer_finalize ();
-       }
+       loop_optimizer_finalize ();
 
       return 0;
     }
+
   init_pre (do_fre);
   scev_initialize ();
 
-
   /* Collect and value number expressions computed in each basic block.  */
   compute_avail ();
 
@@ -4729,6 +4749,12 @@ execute_pre (bool do_fre)
       insert ();
     }
 
+  /* Make sure to remove fake edges before committing our inserts.
+     This makes sure we don't end up with extra critical edges that
+     we would need to split.  */
+  remove_fake_exit_edges ();
+  gsi_commit_edge_inserts ();
+
   /* Remove all the redundant expressions.  */
   todo |= eliminate ();
 
@@ -4738,12 +4764,6 @@ execute_pre (bool do_fre)
   statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
   statistics_counter_event (cfun, "Constified", pre_stats.constified);
 
-  /* Make sure to remove fake edges before committing our inserts.
-     This makes sure we don't end up with extra critical edges that
-     we would need to split.  */
-  remove_fake_exit_edges ();
-  gsi_commit_edge_inserts ();
-
   clear_expression_ids ();
   free_scc_vn ();
   if (!do_fre)