OSDN Git Service

* tree-inline.c (eni_inlining_weights): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index f3c4204..9fb9faf 100644 (file)
@@ -41,7 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-mudflap.h"
 #include "tree-flow.h"
 #include "function.h"
-#include "ggc.h"
 #include "tree-flow.h"
 #include "diagnostic.h"
 #include "except.h"
@@ -102,10 +101,6 @@ along with GCC; see the file COPYING3.  If not see
      calls?  */
 
 
-/* Weights that estimate_num_insns uses for heuristics in inlining.  */
-
-eni_weights eni_inlining_weights;
-
 /* Weights that estimate_num_insns uses to estimate the size of the
    produced code.  */
 
@@ -211,11 +206,21 @@ remap_ssa_name (tree name, copy_body_data *id)
       && (TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL
          || !id->transform_return_to_modify))
     {
+      struct ptr_info_def *pi;
       new_tree = make_ssa_name (new_tree, NULL);
       insert_decl_map (id, name, new_tree);
       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_tree)
        = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name);
       TREE_TYPE (new_tree) = TREE_TYPE (SSA_NAME_VAR (new_tree));
+      /* At least IPA points-to info can be directly transferred.  */
+      if (id->src_cfun->gimple_df
+         && id->src_cfun->gimple_df->ipa_pta
+         && (pi = SSA_NAME_PTR_INFO (name))
+         && !pi->pt.anything)
+       {
+         struct ptr_info_def *new_pi = get_ptr_info (new_tree);
+         new_pi->pt = pi->pt;
+       }
       if (gimple_nop_p (SSA_NAME_DEF_STMT (name)))
        {
          /* By inlining function having uninitialized variable, we might
@@ -1391,6 +1396,12 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
                  default:
                    break;
                  }
+
+             /* Reset alias info if we didn't apply measures to
+                keep it valid over inlining by setting DECL_PT_UID.  */
+             if (!id->src_cfun->gimple_df
+                 || !id->src_cfun->gimple_df->ipa_pta)
+               gimple_call_reset_alias_info (copy);
            }
            break;
 
@@ -1650,6 +1661,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
                                   bb->frequency,
                                   copy_basic_block->frequency);
                        }
+                     stmt = cgraph_redirect_edge_call_stmt_to_callee (edge);
                    }
                  break;
 
@@ -1998,7 +2010,6 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
   cfun->last_verified = src_cfun->last_verified;
   cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
   cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
-  cfun->function_frequency = src_cfun->function_frequency;
   cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
   cfun->stdarg = src_cfun->stdarg;
   cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p;
@@ -3253,22 +3264,93 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
        if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
          switch (DECL_FUNCTION_CODE (decl))
            {
+           /* Builtins that expand to constants.  */
            case BUILT_IN_CONSTANT_P:
-             return 0;
            case BUILT_IN_EXPECT:
-             return 0;
-
-           /* Prefetch instruction is not expensive.  */
-           case BUILT_IN_PREFETCH:
-             cost = weights->target_builtin_call_cost;
-             break;
-
+           case BUILT_IN_OBJECT_SIZE:
+           case BUILT_IN_UNREACHABLE:
+           /* Simple register moves or loads from stack.  */
+           case BUILT_IN_RETURN_ADDRESS:
+           case BUILT_IN_EXTRACT_RETURN_ADDR:
+           case BUILT_IN_FROB_RETURN_ADDR:
+           case BUILT_IN_RETURN:
+           case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
+           case BUILT_IN_FRAME_ADDRESS:
+           case BUILT_IN_VA_END:
+           case BUILT_IN_STACK_SAVE:
+           case BUILT_IN_STACK_RESTORE:
            /* Exception state returns or moves registers around.  */
            case BUILT_IN_EH_FILTER:
            case BUILT_IN_EH_POINTER:
            case BUILT_IN_EH_COPY_VALUES:
              return 0;
 
+           /* builtins that are not expensive (that is they are most probably
+              expanded inline into resonably simple code).  */
+           case BUILT_IN_ABS:
+           case BUILT_IN_ALLOCA:
+           case BUILT_IN_BSWAP32:
+           case BUILT_IN_BSWAP64:
+           case BUILT_IN_CLZ:
+           case BUILT_IN_CLZIMAX:
+           case BUILT_IN_CLZL:
+           case BUILT_IN_CLZLL:
+           case BUILT_IN_CTZ:
+           case BUILT_IN_CTZIMAX:
+           case BUILT_IN_CTZL:
+           case BUILT_IN_CTZLL:
+           case BUILT_IN_FFS:
+           case BUILT_IN_FFSIMAX:
+           case BUILT_IN_FFSL:
+           case BUILT_IN_FFSLL:
+           case BUILT_IN_IMAXABS:
+           case BUILT_IN_FINITE:
+           case BUILT_IN_FINITEF:
+           case BUILT_IN_FINITEL:
+           case BUILT_IN_FINITED32:
+           case BUILT_IN_FINITED64:
+           case BUILT_IN_FINITED128:
+           case BUILT_IN_FPCLASSIFY:
+           case BUILT_IN_ISFINITE:
+           case BUILT_IN_ISINF_SIGN:
+           case BUILT_IN_ISINF:
+           case BUILT_IN_ISINFF:
+           case BUILT_IN_ISINFL:
+           case BUILT_IN_ISINFD32:
+           case BUILT_IN_ISINFD64:
+           case BUILT_IN_ISINFD128:
+           case BUILT_IN_ISNAN:
+           case BUILT_IN_ISNANF:
+           case BUILT_IN_ISNANL:
+           case BUILT_IN_ISNAND32:
+           case BUILT_IN_ISNAND64:
+           case BUILT_IN_ISNAND128:
+           case BUILT_IN_ISNORMAL:
+           case BUILT_IN_ISGREATER:
+           case BUILT_IN_ISGREATEREQUAL:
+           case BUILT_IN_ISLESS:
+           case BUILT_IN_ISLESSEQUAL:
+           case BUILT_IN_ISLESSGREATER:
+           case BUILT_IN_ISUNORDERED:
+           case BUILT_IN_VA_ARG_PACK:
+           case BUILT_IN_VA_ARG_PACK_LEN:
+           case BUILT_IN_VA_COPY:
+           case BUILT_IN_TRAP:
+           case BUILT_IN_SAVEREGS:
+           case BUILT_IN_POPCOUNTL:
+           case BUILT_IN_POPCOUNTLL:
+           case BUILT_IN_POPCOUNTIMAX:
+           case BUILT_IN_POPCOUNT:
+           case BUILT_IN_PARITYL:
+           case BUILT_IN_PARITYLL:
+           case BUILT_IN_PARITYIMAX:
+           case BUILT_IN_PARITY:
+           case BUILT_IN_LABS:
+           case BUILT_IN_LLABS:
+           case BUILT_IN_PREFETCH:
+             cost = weights->target_builtin_call_cost;
+             break;
+
            default:
              break;
            }
@@ -3723,12 +3805,9 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
             cg_edge->frequency * REG_BR_PROB_BASE / CGRAPH_FREQ_BASE,
             bb, return_block);
 
-  /* Reset the escaped and callused solutions.  */
+  /* Reset the escaped solution.  */
   if (cfun->gimple_df)
-    {
-      pt_solution_reset (&cfun->gimple_df->escaped);
-      pt_solution_reset (&cfun->gimple_df->callused);
-    }
+    pt_solution_reset (&cfun->gimple_df->escaped);
 
   /* Clean up.  */
   if (id->debug_map)
@@ -4511,6 +4590,8 @@ copy_decl_to_var (tree decl, copy_body_data *id)
 
   copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
                     VAR_DECL, DECL_NAME (decl), type);
+  if (DECL_PT_UID_SET_P (decl))
+    SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
   TREE_READONLY (copy) = TREE_READONLY (decl);
   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
@@ -4536,6 +4617,8 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
 
   copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
                     VAR_DECL, DECL_NAME (decl), type);
+  if (DECL_PT_UID_SET_P (decl))
+    SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
   TREE_READONLY (copy) = TREE_READONLY (decl);
   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
   if (!DECL_BY_REFERENCE (decl))
@@ -5065,7 +5148,7 @@ tree_can_inline_p (struct cgraph_edge *e)
        return false;
     }
 #endif
-  tree caller, callee;
+  tree caller, callee, lhs;
 
   caller = e->caller->decl;
   callee = e->callee->decl;
@@ -5091,8 +5174,16 @@ tree_can_inline_p (struct cgraph_edge *e)
       return false;
     }
 
+  /* Do not inline calls where we cannot triviall work around mismatches
+     in argument or return types.  */
   if (e->call_stmt
-      && !gimple_check_call_args (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;
       gimple_call_set_cannot_inline (e->call_stmt, true);