OSDN Git Service

* cgraph.c (cgraph_mark_address_taken_node): No longer imply needed flag.
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index 59661a7..03b013c 100644 (file)
@@ -101,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.  */
 
@@ -669,16 +665,30 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id)
     }
 
   if (BIND_EXPR_VARS (*tp))
-    /* This will remap a lot of the same decls again, but this should be
-       harmless.  */
-    BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
+    {
+      tree t;
+
+      /* This will remap a lot of the same decls again, but this should be
+        harmless.  */
+      BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
+      /* Also copy value-expressions.  */
+      for (t = BIND_EXPR_VARS (*tp); t; t = TREE_CHAIN (t))
+       if (TREE_CODE (t) == VAR_DECL
+           && DECL_HAS_VALUE_EXPR_P (t))
+         {
+           tree tem = DECL_VALUE_EXPR (t);
+           walk_tree (&tem, copy_tree_body_r, id, NULL);
+           SET_DECL_VALUE_EXPR (t, tem);
+         }
+    }
 }
 
 
 /* Create a new gimple_seq by remapping all the statements in BODY
    using the inlining information in ID.  */
 
-gimple_seq
+static gimple_seq
 remap_gimple_seq (gimple_seq body, copy_body_data *id)
 {
   gimple_stmt_iterator si;
@@ -1688,9 +1698,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
              /* Constant propagation on argument done during inlining
                 may create new direct call.  Produce an edge for it.  */
              if ((!edge
-                  || (edge->indirect_call
+                  || (edge->indirect_inlining_edge
                       && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
-                 && is_gimple_call (stmt)
                  && (fn = gimple_call_fndecl (stmt)) != NULL)
                {
                  struct cgraph_node *dest = cgraph_node (fn);
@@ -1702,6 +1711,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
                     other cases we hit a bug (incorrect node sharing is the
                     most common reason for missing edges).  */
                  gcc_assert (dest->needed || !dest->analyzed
+                             || dest->address_taken
                              || !id->src_node->analyzed);
                  if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
                    cgraph_create_edge_including_clones
@@ -2014,7 +2024,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;
@@ -3269,22 +3278,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;
            }
@@ -3473,7 +3553,7 @@ get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt)
   struct cgraph_edge *cs;
 
   cs = cgraph_edge (node, stmt);
-  if (cs)
+  if (cs && !cs->indirect_unknown_callee)
     return cs->callee->decl;
 
   return NULL_TREE;
@@ -3556,7 +3636,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
       /* If this call was originally indirect, we do not want to emit any
         inlining related warnings or sorry messages because there are no
         guarantees regarding those.  */
-      if (cg_edge->indirect_call)
+      if (cg_edge->indirect_inlining_edge)
        goto egress;
 
       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
@@ -4845,6 +4925,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
     (DECL_STRUCT_FUNCTION (old_decl));
   initialize_cfun (new_decl, old_decl,
                   old_entry_block->count);
+  DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta
+    = id.src_cfun->gimple_df->ipa_pta;
   push_cfun (DECL_STRUCT_FUNCTION (new_decl));
 
   /* Copy the function's static chain.  */
@@ -4956,6 +5038,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
   pointer_set_destroy (id.statements_to_fold);
   fold_cond_expr_cond ();
   delete_unreachable_blocks_update_callgraph (&id);
+  if (id.dst_node->analyzed)
+    cgraph_rebuild_references ();
   update_ssa (TODO_update_ssa);
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);