OSDN Git Service

* config/picochip/picochip.c (picochip_init_builtins): Call
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index b4f9dcd..3777675 100644 (file)
@@ -1204,7 +1204,7 @@ remap_eh_region_tree_nr (tree old_t_nr, copy_body_data *id)
   old_nr = tree_low_cst (old_t_nr, 0);
   new_nr = remap_eh_region_nr (old_nr, id);
 
-  return build_int_cst (NULL, new_nr);
+  return build_int_cst (integer_type_node, new_nr);
 }
 
 /* Helper for copy_bb.  Remap statement STMT using the inlining
@@ -1678,7 +1678,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
                      edge = cgraph_clone_edge (edge, id->dst_node, stmt,
                                                gimple_uid (stmt),
                                                REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
-                                               edge->frequency, true);
+                                               true);
                      /* We could also just rescale the frequency, but
                         doing so would introduce roundoff errors and make
                         verifier unhappy.  */
@@ -1725,9 +1725,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
              if ((!edge
                   || (edge->indirect_inlining_edge
                       && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
+                 && id->dst_node->analyzed
                  && (fn = gimple_call_fndecl (stmt)) != NULL)
                {
-                 struct cgraph_node *dest = cgraph_node (fn);
+                 struct cgraph_node *dest = cgraph_get_node (fn);
 
                  /* We have missing edge in the callgraph.  This can happen
                     when previous inlining turned an indirect call into a
@@ -1744,13 +1745,12 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
                      (id->dst_node, dest, orig_stmt, stmt, bb->count,
                       compute_call_stmt_bb_frequency (id->dst_node->decl,
                                                       copy_basic_block),
-                      bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL);
+                      CIF_ORIGINALLY_INDIRECT_CALL);
                  else
                    cgraph_create_edge (id->dst_node, dest, stmt,
                                        bb->count,
                                        compute_call_stmt_bb_frequency
-                                         (id->dst_node->decl, copy_basic_block),
-                                       bb->loop_depth)->inline_failed
+                                         (id->dst_node->decl, copy_basic_block))->inline_failed
                      = CIF_ORIGINALLY_INDIRECT_CALL;
                  if (dump_file)
                    {
@@ -2997,8 +2997,11 @@ inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
         this may change program's memory overhead drastically when the
         function using alloca is called in loop.  In GCC present in
         SPEC2000 inlining into schedule_block cause it to require 2GB of
-        RAM instead of 256MB.  */
+        RAM instead of 256MB.  Don't do so for alloca calls emitted for
+        VLA objects as those can't cause unbounded growth (they're always
+        wrapped inside stack_save/stack_restore regions.  */
       if (gimple_alloca_call_p (stmt)
+         && !gimple_call_alloca_for_var_p (stmt)
          && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
        {
          inline_forbidden_reason
@@ -3135,29 +3138,6 @@ inline_forbidden_p (tree fndecl)
   return forbidden_p;
 }
 
-/* Return true if CALLEE cannot be inlined into CALLER.  */
-
-static bool
-inline_forbidden_into_p (tree caller, tree callee)
-{
-  /* Don't inline if the functions have different EH personalities.  */
-  if (DECL_FUNCTION_PERSONALITY (caller)
-      && DECL_FUNCTION_PERSONALITY (callee)
-      && (DECL_FUNCTION_PERSONALITY (caller)
-         != DECL_FUNCTION_PERSONALITY (callee)))
-    return true;
-
-  /* Don't inline if the callee can throw non-call exceptions but the
-     caller cannot.  */
-  if (DECL_STRUCT_FUNCTION (callee)
-      && DECL_STRUCT_FUNCTION (callee)->can_throw_non_call_exceptions
-      && !(DECL_STRUCT_FUNCTION (caller)
-          && DECL_STRUCT_FUNCTION (caller)->can_throw_non_call_exceptions))
-    return true;
-
-  return false;
-}
-
 /* Returns nonzero if FN is a function that does not have any
    fundamental inline blocking properties.  */
 
@@ -3470,10 +3450,11 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
     case GIMPLE_CALL:
       {
        tree decl = gimple_call_fndecl (stmt);
+       struct cgraph_node *node;
 
        /* Do not special case builtins where we see the body.
           This just confuse inliner.  */
-       if (!decl || cgraph_node (decl)->analyzed)
+       if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed)
          ;
        /* For buitins that are likely expanded to nothing or
           inlined do not account operand costs.  */
@@ -3746,10 +3727,6 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
       && gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
     fn = DECL_ABSTRACT_ORIGIN (fn);
 
-  /* First check that inlining isn't simply forbidden in this case.  */
-  if (inline_forbidden_into_p (cg_edge->caller->decl, cg_edge->callee->decl))
-    goto egress;
-
   /* Don't try to inline functions that are not well-suited to inlining.  */
   if (!cgraph_inline_p (cg_edge, &reason))
     {
@@ -3767,7 +3744,9 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
                 _(cgraph_inline_failed_string (reason)));
          sorry ("called from here");
        }
-      else if (warn_inline && DECL_DECLARED_INLINE_P (fn)
+      else if (warn_inline
+              && DECL_DECLARED_INLINE_P (fn)
+              && !DECL_NO_INLINE_WARNING_P (fn)
               && !DECL_IN_SYSTEM_HEADER (fn)
               && reason != CIF_UNSPECIFIED
               && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn))
@@ -4158,7 +4137,7 @@ optimize_inline_calls (tree fn)
   /* Clear out ID.  */
   memset (&id, 0, sizeof (id));
 
-  id.src_node = id.dst_node = cgraph_node (fn);
+  id.src_node = id.dst_node = cgraph_get_node (fn);
   gcc_assert (id.dst_node->analyzed);
   id.dst_fn = fn;
   /* Or any functions that aren't finished yet.  */
@@ -4252,7 +4231,8 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
         here.  */
       tree chain = NULL_TREE, new_tree;
 
-      chain = TREE_CHAIN (*tp);
+      if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+       chain = TREE_CHAIN (*tp);
 
       /* Copy the node.  */
       new_tree = copy_node (*tp);
@@ -4291,14 +4271,26 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
                                         CONSTRUCTOR_ELTS (*tp));
       *tp = new_tree;
     }
+  else if (code == STATEMENT_LIST)
+    {
+      /* We used to just abort on STATEMENT_LIST, but we can run into them
+         with statement-expressions (c++/40975).  */
+      tree new_list = alloc_stmt_list ();
+      tree_stmt_iterator i = tsi_start (*tp);
+      tree_stmt_iterator j = tsi_last (new_list);
+      for (; !tsi_end_p (i); tsi_next (&i))
+       {
+         tree stmt = tsi_stmt (i);
+         tsi_link_after (&j, stmt, TSI_CONTINUE_LINKING);
+       }
+      *tp = new_list;
+    }
   else if (TREE_CODE_CLASS (code) == tcc_type)
     *walk_subtrees = 0;
   else if (TREE_CODE_CLASS (code) == tcc_declaration)
     *walk_subtrees = 0;
   else if (TREE_CODE_CLASS (code) == tcc_constant)
     *walk_subtrees = 0;
-  else
-    gcc_assert (code != STATEMENT_LIST);
   return NULL_TREE;
 }
 
@@ -5000,8 +4992,10 @@ tree_function_versioning (tree old_decl, tree new_decl,
              && TREE_CODE (new_decl) == FUNCTION_DECL);
   DECL_POSSIBLY_INLINED (old_decl) = 1;
 
-  old_version_node = cgraph_node (old_decl);
-  new_version_node = cgraph_node (new_decl);
+  old_version_node = cgraph_get_node (old_decl);
+  gcc_checking_assert (old_version_node);
+  new_version_node = cgraph_get_node (new_decl);
+  gcc_checking_assert (new_version_node);
 
   /* Output the inlining info for this abstract function, since it has been
      inlined.  If we don't do this now, we can lose the information about the
@@ -5291,81 +5285,3 @@ build_duplicate_type (tree type)
 
   return type;
 }
-
-/* Return whether it is safe to inline a function because it used different
-   target specific options or call site actual types mismatch parameter types.
-   E is the call edge to be checked.  */
-bool
-tree_can_inline_p (struct cgraph_edge *e)
-{
-#if 0
-  /* This causes a regression in SPEC in that it prevents a cold function from
-     inlining a hot function.  Perhaps this should only apply to functions
-     that the user declares hot/cold/optimize explicitly.  */
-
-  /* Don't inline a function with a higher optimization level than the
-     caller, or with different space constraints (hot/cold functions).  */
-  tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (caller);
-  tree callee_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee);
-
-  if (caller_tree != callee_tree)
-    {
-      struct cl_optimization *caller_opt
-       = TREE_OPTIMIZATION ((caller_tree)
-                            ? caller_tree
-                            : optimization_default_node);
-
-      struct cl_optimization *callee_opt
-       = TREE_OPTIMIZATION ((callee_tree)
-                            ? callee_tree
-                            : optimization_default_node);
-
-      if ((caller_opt->optimize > callee_opt->optimize)
-         || (caller_opt->optimize_size != callee_opt->optimize_size))
-       return false;
-    }
-#endif
-  tree caller, callee, lhs;
-
-  caller = e->caller->decl;
-  callee = e->callee->decl;
-
-  /* First check that inlining isn't simply forbidden in this case.  */
-  if (inline_forbidden_into_p (caller, callee))
-    {
-      e->inline_failed = CIF_UNSPECIFIED;
-      if (e->call_stmt)
-       gimple_call_set_cannot_inline (e->call_stmt, true);
-      return false;
-    }
-
-  /* Allow the backend to decide if inlining is ok.  */
-  if (!targetm.target_option.can_inline_p (caller, callee))
-    {
-      e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
-      if (e->call_stmt)
-       gimple_call_set_cannot_inline (e->call_stmt, true);
-      e->call_stmt_cannot_inline_p = true;
-      return false;
-    }
-
-  /* Do not inline calls where we cannot triviall work around mismatches
-     in argument or return types.  */
-  if (e->call_stmt
-      && ((DECL_RESULT (callee)
-          && !DECL_BY_REFERENCE (DECL_RESULT (callee))
-          && (lhs = gimple_call_lhs (e->call_stmt)) != NULL_TREE
-          && !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)),
-                                         TREE_TYPE (lhs))
-          && !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs))
-         || !gimple_check_call_args (e->call_stmt)))
-    {
-      e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
-      if (e->call_stmt)
-       gimple_call_set_cannot_inline (e->call_stmt, true);
-      e->call_stmt_cannot_inline_p = true;
-      return false;
-    }
-
-  return true;
-}