OSDN Git Service

PR target/36684
[pf3gnuchains/gcc-fork.git] / gcc / cgraphunit.c
index 5d81f56..2dcccc1 100644 (file)
@@ -119,9 +119,9 @@ along with GCC; see the file COPYING3.  If not see
        Functions are output early using call of
        cgraph_assemble_pending_function from cgraph_finalize_function.  The
        decision on whether function is needed is made more conservative so
-       uninlininable static functions are needed too.  During the call-graph
+       uninlinable static functions are needed too.  During the call-graph
        construction the edge destinations are not marked as reachable and it
-       is completely relied upn assemble_variable to mark them.  */
+       is completely relied upon assemble_variable to mark them.  */
 
 
 #include "config.h"
@@ -326,7 +326,7 @@ cgraph_build_cdtor_fns (void)
 
 /* Determine if function DECL is needed.  That is, visible to something
    either outside this translation unit, something magic in the system
-   configury, or (if not doing unit-at-a-time) to something we havn't
+   configury, or (if not doing unit-at-a-time) to something we haven't
    seen yet.  */
 
 static bool
@@ -443,7 +443,6 @@ cgraph_process_new_functions (void)
             it into reachable functions list.  */
 
          node->next_needed = NULL;
-         node->needed = node->reachable = false;
          cgraph_finalize_function (fndecl, false);
          cgraph_mark_reachable_node (node);
          output = true;
@@ -460,22 +459,13 @@ cgraph_process_new_functions (void)
            cgraph_analyze_function (node);
          push_cfun (DECL_STRUCT_FUNCTION (fndecl));
          current_function_decl = fndecl;
-         node->local.inlinable = tree_inlinable_function_p (fndecl);
-         node->local.self_insns = estimate_num_insns (fndecl,
-                                                      &eni_inlining_weights);
-         node->local.disregard_inline_limits
-           |= DECL_DISREGARD_INLINE_LIMITS (fndecl);
-         /* Inlining characteristics are maintained by the
-            cgraph_mark_inline.  */
-         node->global.insns = node->local.self_insns;
-         if (flag_really_no_inline && !node->local.disregard_inline_limits)
-            node->local.inlinable = 0;
+         compute_inline_parameters (node);
          if ((cgraph_state == CGRAPH_STATE_IPA_SSA
              && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
              /* When not optimizing, be sure we run early local passes anyway
                 to expand OMP.  */
              || !optimize)
-           execute_pass_list (pass_early_local_passes.sub);
+           execute_pass_list (pass_early_local_passes.pass.sub);
          free_dominance_info (CDI_POST_DOMINATORS);
          free_dominance_info (CDI_DOMINATORS);
          pop_cfun ();
@@ -505,7 +495,7 @@ cgraph_assemble_pending_functions (void)
 {
   bool output = false;
 
-  if (flag_unit_at_a_time)
+  if (flag_unit_at_a_time || errorcount || sorrycount)
     return false;
 
   cgraph_output_pending_asms ();
@@ -574,8 +564,9 @@ cgraph_reset_node (struct cgraph_node *node)
   cgraph_node_remove_callees (node);
 
   /* We may need to re-queue the node for assembling in case
-     we already proceeded it and ignored as not needed.  */
-  if (node->reachable && !flag_unit_at_a_time)
+     we already proceeded it and ignored as not needed or got
+     a re-declaration in IMA mode.  */
+  if (node->reachable)
     {
       struct cgraph_node *n;
 
@@ -611,7 +602,6 @@ cgraph_finalize_function (tree decl, bool nested)
 
   node->pid = cgraph_max_pid ++;
   notice_global_symbol (decl);
-  node->decl = decl;
   node->local.finalized = true;
   node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
   record_cdtor_fn (node->decl);
@@ -650,6 +640,18 @@ cgraph_finalize_function (tree decl, bool nested)
     do_warn_unused_parameter (decl);
 }
 
+/* C99 extern inline keywords allow changing of declaration after function
+   has been finalized.  We need to re-decide if we want to mark the function as
+   needed then.   */
+
+void
+cgraph_mark_if_needed (tree decl)
+{
+  struct cgraph_node *node = cgraph_node (decl);
+  if (node->local.finalized && decide_is_function_needed (node, decl))
+    cgraph_mark_needed_node (node);
+}
+
 /* Verify cgraph nodes of given cgraph node.  */
 void
 verify_cgraph_node (struct cgraph_node *node)
@@ -657,6 +659,7 @@ verify_cgraph_node (struct cgraph_node *node)
   struct cgraph_edge *e;
   struct cgraph_node *main_clone;
   struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
+  struct function *saved_cfun = cfun;
   basic_block this_block;
   block_stmt_iterator bsi;
   bool error_found = false;
@@ -665,6 +668,8 @@ verify_cgraph_node (struct cgraph_node *node)
     return;
 
   timevar_push (TV_CGRAPH_VERIFY);
+  /* debug_generic_stmt needs correct cfun */
+  set_cfun (this_cfun);
   for (e = node->callees; e; e = e->next_callee)
     if (e->aux)
       {
@@ -807,6 +812,7 @@ verify_cgraph_node (struct cgraph_node *node)
       dump_cgraph_node (stderr, node);
       internal_error ("verify_cgraph_node failed");
     }
+  set_cfun (saved_cfun);
   timevar_pop (TV_CGRAPH_VERIFY);
 }
 
@@ -849,11 +855,11 @@ cgraph_analyze_function (struct cgraph_node *node)
   cgraph_lower_function (node);
   node->analyzed = true;
 
-  if (!flag_unit_at_a_time)
+  if (!flag_unit_at_a_time && !sorrycount && !errorcount)
     {
       bitmap_obstack_initialize (NULL);
       tree_register_cfg_hooks ();
-      execute_pass_list (pass_early_local_passes.sub);
+      execute_pass_list (pass_early_local_passes.pass.sub);
       free_dominance_info (CDI_POST_DOMINATORS);
       free_dominance_info (CDI_DOMINATORS);
       bitmap_obstack_release (NULL);
@@ -1153,10 +1159,10 @@ cgraph_expand_function (struct cgraph_node *node)
 
   /* Make sure that BE didn't give up on compiling.  */
   /* ??? Can happen with nested function of extern inline.  */
-  gcc_assert (TREE_ASM_WRITTEN (node->decl));
+  gcc_assert (TREE_ASM_WRITTEN (decl));
 
   current_function_decl = NULL;
-  if (!cgraph_preserve_function_body_p (node->decl))
+  if (!cgraph_preserve_function_body_p (decl))
     {
       cgraph_release_function_body (node);
       /* Eliminate all call edges.  This is important so the call_expr no longer
@@ -1193,7 +1199,7 @@ cgraph_expand_all_functions (void)
 {
   struct cgraph_node *node;
   struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
-  int order_pos = 0, new_order_pos = 0;
+  int order_pos, new_order_pos = 0;
   int i;
 
   order_pos = cgraph_postorder (order);
@@ -1381,7 +1387,7 @@ cgraph_optimize (void)
   if (!quiet_flag)
     fprintf (stderr, "Performing interprocedural optimizations\n");
   cgraph_state = CGRAPH_STATE_IPA;
-    
+
   /* Don't run the IPA passes if there was any error or sorry messages.  */
   if (errorcount == 0 && sorrycount == 0)
     ipa_passes ();
@@ -1423,8 +1429,8 @@ cgraph_optimize (void)
       varpool_remove_unreferenced_decls ();
 
       varpool_assemble_pending_decls ();
-      varpool_output_debug_info ();
     }
+  varpool_output_debug_info ();
   cgraph_process_new_functions ();
   cgraph_state = CGRAPH_STATE_FINISHED;
 
@@ -1452,14 +1458,14 @@ cgraph_optimize (void)
            dump_cgraph_node (stderr, node);
          }
       if (error_found)
-       internal_error ("nodes with no released memory found");
+       internal_error ("nodes with unreleased memory found");
     }
 #endif
 }
 /* Generate and emit a static constructor or destructor.  WHICH must
    be one of 'I' (for a constructor) or 'D' (for a destructor).  BODY
    is a STATEMENT_LIST containing GENERIC statements.  PRIORITY is the
-   initialization priority fot this constructor or destructor.  */
+   initialization priority for this constructor or destructor.  */
 
 void
 cgraph_build_static_cdtor (char which, tree body, int priority)