OSDN Git Service

2010-10-26 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index 4298958..133d916 100644 (file)
@@ -422,11 +422,11 @@ remap_type_1 (tree type, copy_body_data *id)
       {
        tree f, nf = NULL;
 
-       for (f = TYPE_FIELDS (new_tree); f ; f = TREE_CHAIN (f))
+       for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f))
          {
            t = remap_decl (f, id);
            DECL_CONTEXT (t) = new_tree;
-           TREE_CHAIN (t) = nf;
+           DECL_CHAIN (t) = nf;
            nf = t;
          }
        TYPE_FIELDS (new_tree) = nreverse (nf);
@@ -537,7 +537,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
   tree new_decls = NULL_TREE;
 
   /* Remap its variables.  */
-  for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
+  for (old_var = decls; old_var; old_var = DECL_CHAIN (old_var))
     {
       tree new_var;
 
@@ -573,7 +573,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
       else
        {
          gcc_assert (DECL_P (new_var));
-         TREE_CHAIN (new_var) = new_decls;
+         DECL_CHAIN (new_var) = new_decls;
          new_decls = new_var;
  
          /* Also copy value-expressions.  */
@@ -858,6 +858,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
                  *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
                                     ptr, TREE_OPERAND (*tp, 1));
                  TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+                 TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
                }
              TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
              *walk_subtrees = 0;
@@ -1087,6 +1088,8 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
                      *tp = build1 (INDIRECT_REF, type, new_tree);
                      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
                      TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
+                     TREE_READONLY (*tp) = TREE_READONLY (old);
+                     TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
                    }
                }
              *walk_subtrees = 0;
@@ -1558,7 +1561,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
          tree new_rhs;
          new_rhs = force_gimple_operand_gsi (&seq_gsi,
                                              gimple_assign_rhs1 (stmt),
-                                             true, NULL, false, GSI_NEW_STMT);
+                                             true, NULL, false,
+                                             GSI_CONTINUE_LINKING);
          gimple_assign_set_rhs1 (stmt, new_rhs);
          id->regimplify = false;
        }
@@ -1595,7 +1599,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
              size_t nargs = gimple_call_num_args (id->gimple_call);
              size_t n;
 
-             for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+             for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
                nargs--;
 
              /* Create the new array of arguments.  */
@@ -1642,7 +1646,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
              tree count, p;
              gimple new_stmt;
 
-             for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+             for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
                nargs--;
 
              count = build_int_cst (integer_type_node, nargs);
@@ -1741,7 +1745,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
                     most common reason for missing edges).  */
                  gcc_assert (dest->needed || !dest->analyzed
                              || dest->address_taken
-                             || !id->src_node->analyzed);
+                             || !id->src_node->analyzed
+                             || !id->dst_node->analyzed);
                  if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
                    cgraph_create_edge_including_clones
                      (id->dst_node, dest, orig_stmt, stmt, bb->count,
@@ -1976,12 +1981,13 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
   edge_iterator ei;
   gimple phi;
   gimple_stmt_iterator si;
+  edge new_edge;
+  bool inserted = false;
 
   for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si))
     {
       tree res, new_res;
       gimple new_phi;
-      edge new_edge;
 
       phi = gsi_stmt (si);
       res = PHI_RESULT (phi);
@@ -2021,13 +2027,19 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
                {
                  gimple_seq stmts = NULL;
                  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
-                 gsi_insert_seq_on_edge_immediate (new_edge, stmts);
+                 gsi_insert_seq_on_edge (new_edge, stmts);
+                 inserted = true;
                }
              add_phi_arg (new_phi, new_arg, new_edge,
                           gimple_phi_arg_location_from_edge (phi, old_edge));
            }
        }
     }
+
+  /* Commit the delayed edge insertions.  */
+  if (inserted)
+    FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
+      gsi_commit_one_edge_insert (new_edge, NULL);
 }
 
 
@@ -2370,7 +2382,7 @@ copy_debug_stmts (copy_body_data *id)
   if (!id->debug_stmts)
     return;
 
-  for (i = 0; VEC_iterate (gimple, id->debug_stmts, i, stmt); i++)
+  FOR_EACH_VEC_ELT (gimple, id->debug_stmts, i, stmt)
     copy_debug_stmt (stmt, id);
 
   VEC_free (gimple, heap, id->debug_stmts);
@@ -2553,7 +2565,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
     }
 
   /* Declare this new variable.  */
-  TREE_CHAIN (var) = *vars;
+  DECL_CHAIN (var) = *vars;
   *vars = var;
 
   /* Make gimplifier happy about this variable.  */
@@ -2683,7 +2695,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
 
   /* Loop through the parameter declarations, replacing each with an
      equivalent VAR_DECL, appropriately initialized.  */
-  for (p = parms, i = 0; p; p = TREE_CHAIN (p), i++)
+  for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
     {
       tree val;
       val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
@@ -2693,7 +2705,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
      in a second loop over all parameters to appropriately remap
      variable sized arrays when the size is specified in a
      parameter following the array.  */
-  for (p = parms, i = 0; p; p = TREE_CHAIN (p), i++)
+  for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
     {
       tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
       if (varp
@@ -3197,12 +3209,6 @@ tree_inlinable_function_p (tree fn)
       inlinable = false;
     }
 
-  /* Don't auto-inline anything that might not be bound within
-     this unit of translation.  */
-  else if (!DECL_DECLARED_INLINE_P (fn)
-          && DECL_REPLACEABLE_P (fn))
-    inlinable = false;
-
   else if (!function_attribute_inlinable_p (fn))
     {
       if (do_warning)
@@ -3505,7 +3511,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
        if (decl && DECL_ARGUMENTS (decl) && !stdarg)
          {
            tree arg;
-           for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
+           for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
              if (!VOID_TYPE_P (TREE_TYPE (arg)))
                cost += estimate_move_cost (TREE_TYPE (arg));
          }
@@ -3687,21 +3693,24 @@ add_local_variables (struct function *callee, struct function *caller,
          add_local_decl (caller, var);
       }
     else if (!can_be_nonlocal (var, id))
-      add_local_decl (caller, remap_decl (var, id));
-}
-
-/* Fetch callee declaration from the call graph edge going from NODE and
-   associated with STMR call statement.  Return NULL_TREE if not found.  */
-static tree
-get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt)
-{
-  struct cgraph_edge *cs;
-
-  cs = cgraph_edge (node, stmt);
-  if (cs && !cs->indirect_unknown_callee)
-    return cs->callee->decl;
+      {
+        tree new_var = remap_decl (var, id);
 
-  return NULL_TREE;
+        /* Remap debug-expressions.  */
+       if (TREE_CODE (new_var) == VAR_DECL
+           && DECL_DEBUG_EXPR_IS_FROM (new_var)
+           && new_var != var)
+         {
+           tree tem = DECL_DEBUG_EXPR (var);
+           bool old_regimplify = id->regimplify;
+           id->remapping_type_depth++;
+           walk_tree (&tem, copy_tree_body_r, id, NULL);
+           id->remapping_type_depth--;
+           id->regimplify = old_regimplify;
+           SET_DECL_DEBUG_EXPR (new_var, tem);
+         }
+       add_local_decl (caller, new_var);
+      }
 }
 
 /* If STMT is a GIMPLE_CALL, replace it with its inline expansion.  */
@@ -3737,11 +3746,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
      If we cannot, then there is no hope of inlining the function.  */
   fn = gimple_call_fndecl (stmt);
   if (!fn)
-    {
-      fn = get_indirect_callee_fndecl (id->dst_node, stmt);
-      if (!fn)
-       goto egress;
-    }
+    goto egress;
 
   /* Turn forward declarations into real ones.  */
   fn = cgraph_node (fn)->decl;
@@ -4005,7 +4010,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
     }
 
   if (purge_dead_abnormal_edges)
-    gimple_purge_dead_abnormal_call_edges (return_block);
+    {
+      gimple_purge_dead_eh_edges (return_block);
+      gimple_purge_dead_abnormal_call_edges (return_block);
+    }
 
   /* If the value of the new expression is ignored, that's OK.  We
      don't warn about this for CALL_EXPRs, so we shouldn't warn about
@@ -4161,6 +4169,7 @@ optimize_inline_calls (tree fn)
   basic_block bb;
   int last = n_basic_blocks;
   struct gimplify_ctx gctx;
+  bool inlined_p = false;
 
   /* There is no point in performing inlining if errors have already
      occurred -- and we might crash if we try to inline invalid
@@ -4200,7 +4209,7 @@ optimize_inline_calls (tree fn)
      follow it; we'll trudge through them, processing their CALL_EXPRs
      along the way.  */
   FOR_EACH_BB (bb)
-    gimple_expand_calls_inline (bb, &id);
+    inlined_p |= gimple_expand_calls_inline (bb, &id);
 
   pop_gimplify_context (NULL);
 
@@ -4216,18 +4225,19 @@ optimize_inline_calls (tree fn)
     }
 #endif
 
-  /* Fold the statements before compacting/renumbering the basic blocks.  */
+  /* Fold queued statements.  */
   fold_marked_statements (last, id.statements_to_fold);
   pointer_set_destroy (id.statements_to_fold);
 
   gcc_assert (!id.debug_stmts);
 
-  /* Renumber the (code) basic_blocks consecutively.  */
-  compact_blocks ();
+  /* If we didn't inline into the function there is nothing to do.  */
+  if (!inlined_p)
+    return 0;
+
   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
   number_blocks (fn);
 
-  fold_cond_expr_cond ();
   delete_unreachable_blocks_update_callgraph (&id);
 #ifdef ENABLE_CHECKING
   verify_cgraph_node (id.dst_node);
@@ -4240,6 +4250,7 @@ optimize_inline_calls (tree fn)
   return (TODO_update_ssa
          | TODO_cleanup_cfg
          | (gimple_in_ssa_p (cfun) ? TODO_remove_unused_locals : 0)
+         | (gimple_in_ssa_p (cfun) ? TODO_update_address_taken : 0)
          | (profile_status != PROFILE_ABSENT ? TODO_rebuild_frequencies : 0));
 }
 
@@ -4663,7 +4674,7 @@ static void
 declare_inline_vars (tree block, tree vars)
 {
   tree t;
-  for (t = vars; t; t = TREE_CHAIN (t))
+  for (t = vars; t; t = DECL_CHAIN (t))
     {
       DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
       gcc_assert (!TREE_STATIC (t) && !TREE_ASM_WRITTEN (t));
@@ -4812,13 +4823,13 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
 
   parg = &new_parm;
 
-  for (arg = orig_parm; arg; arg = TREE_CHAIN (arg), i++)
+  for (arg = orig_parm; arg; arg = DECL_CHAIN (arg), i++)
     if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
       {
         tree new_tree = remap_decl (arg, id);
         lang_hooks.dup_lang_specific_decl (new_tree);
         *parg = new_tree;
-       parg = &TREE_CHAIN (new_tree);
+       parg = &DECL_CHAIN (new_tree);
       }
     else if (!pointer_map_contains (id->decl_map, arg))
       {
@@ -4830,7 +4841,7 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
        add_referenced_var (var);
        insert_decl_map (id, arg, var);
         /* Declare this new variable.  */
-        TREE_CHAIN (var) = *vars;
+        DECL_CHAIN (var) = *vars;
         *vars = var;
       }
   return new_parm;
@@ -4843,11 +4854,11 @@ copy_static_chain (tree static_chain, copy_body_data * id)
   tree *chain_copy, *pvar;
 
   chain_copy = &static_chain;
-  for (pvar = chain_copy; *pvar; pvar = &TREE_CHAIN (*pvar))
+  for (pvar = chain_copy; *pvar; pvar = &DECL_CHAIN (*pvar))
     {
       tree new_tree = remap_decl (*pvar, id);
       lang_hooks.dup_lang_specific_decl (new_tree);
-      TREE_CHAIN (new_tree) = TREE_CHAIN (*pvar);
+      DECL_CHAIN (new_tree) = DECL_CHAIN (*pvar);
       *pvar = new_tree;
     }
   return static_chain;
@@ -5081,7 +5092,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
              {
                int i = replace_info->parm_num;
                tree parm;
-               for (parm = DECL_ARGUMENTS (old_decl); i; parm = TREE_CHAIN (parm))
+               for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
                  i --;
                replace_info->old_tree = parm;
              }
@@ -5117,9 +5128,6 @@ tree_function_versioning (tree old_decl, tree new_decl,
 
   DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
 
-  /* Renumber the lexical scoping (non-code) blocks consecutively.  */
-  number_blocks (id.dst_fn);
-
   declare_inline_vars (DECL_INITIAL (new_decl), vars);
 
   if (!VEC_empty (tree, DECL_STRUCT_FUNCTION (old_decl)->local_decls))
@@ -5184,7 +5192,15 @@ tree_function_versioning (tree old_decl, tree new_decl,
       for (e = new_version_node->callees; e; e = e->next_callee)
        {
          basic_block bb = gimple_bb (e->call_stmt);
-         e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
+         e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+                                                        bb);
+         e->count = bb->count;
+       }
+      for (e = new_version_node->indirect_calls; e; e = e->next_callee)
+       {
+         basic_block bb = gimple_bb (e->call_stmt);
+         e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+                                                        bb);
          e->count = bb->count;
        }
     }
@@ -5220,7 +5236,7 @@ maybe_inline_call_in_expr (tree exp)
       /* Remap the parameters.  */
       for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
           param;
-          param = TREE_CHAIN (param), arg = next_call_expr_arg (&iter))
+          param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
        *pointer_map_insert (decl_map, param) = arg;
 
       memset (&id, 0, sizeof (id));