OSDN Git Service

* cgraph.c (hash_node, eq_node, cgraph_node, cgraph_remove_node)
[pf3gnuchains/gcc-fork.git] / gcc / passes.c
index 2453c74..841e361 100644 (file)
@@ -394,7 +394,8 @@ rest_of_decl_compilation (tree decl,
        }
       else
        {
-         error ("invalid register name `%s' for register variable", asmspec);
+         error ("%Hinvalid register name `%s' for register variable",
+                &DECL_SOURCE_LOCATION (decl), asmspec);
          DECL_REGISTER (decl) = 0;
          if (!top_level)
            expand_decl (decl);
@@ -465,7 +466,7 @@ rest_of_handle_final (tree decl, rtx insns)
       fflush (asm_out_file);
 
     /* Release all memory allocated by flow.  */
-    free_basic_block_vars (0);
+    free_basic_block_vars ();
 
     /* Release all memory held by regsets now.  */
     regset_release_memory ();
@@ -518,7 +519,7 @@ rest_of_handle_stack_regs (tree decl, rtx insns)
   timevar_push (TV_REG_STACK);
   open_dump_file (DFI_stack, decl);
 
-  if (reg_to_stack (insns, dump_file) && optimize)
+  if (reg_to_stack (dump_file) && optimize)
     {
       if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
                       | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
@@ -623,7 +624,8 @@ rest_of_handle_old_regalloc (tree decl, rtx insns)
   allocate_reg_info (max_regno, FALSE, TRUE);
 
   /* And the reg_equiv_memory_loc array.  */
-  reg_equiv_memory_loc = xcalloc (max_regno, sizeof (rtx));
+  VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno);
+  reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0);
 
   allocate_initial_values (reg_equiv_memory_loc);
 
@@ -976,34 +978,6 @@ rest_of_handle_addressof (tree decl, rtx insns)
   close_dump_file (DFI_addressof, print_rtl, insns);
 }
 
-/* We may have potential sibling or tail recursion sites.  Select one
-   (of possibly multiple) methods of performing the call.  */
-static void
-rest_of_handle_sibling_calls (rtx insns)
-{
-  rtx insn;
-  optimize_sibling_and_tail_recursive_calls ();
-
-  /* Recompute the CFG as sibling optimization clobbers it randomly.  */
-  free_bb_for_insn ();
-  find_exception_handler_labels ();
-  rebuild_jump_labels (insns);
-  find_basic_blocks (insns, max_reg_num (), dump_file);
-
-  /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION
-     notes before simplifying cfg and we must do lowering after sibcall
-     that unhides parts of RTL chain and cleans up the CFG.
-
-     Until sibcall is replaced by tree-level optimizer, lets just
-     sweep away the NOTE_INSN_PREDICTION notes that leaked out.  */
-  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == NOTE
-       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
-      delete_insn (insn);
-
-  close_dump_file (DFI_sibling, print_rtl, get_insns ());
-}
-
 /* Perform jump bypassing and control flow optimizations.  */
 static void
 rest_of_handle_jump_bypass (tree decl, rtx insns)
@@ -1031,169 +1005,6 @@ rest_of_handle_jump_bypass (tree decl, rtx insns)
 #endif
 }
 
-/* Handle inlining of functions in rest_of_compilation.  Return TRUE
-   if we must exit rest_of_compilation upon return.  */
-static bool
-rest_of_handle_inlining (tree decl)
-{
-  rtx insns;
-  int inlinable = 0;
-  tree parent;
-  const char *lose;
-
-  /* If we are reconsidering an inline function at the end of
-     compilation, skip the stuff for making it inline.  */
-  if (cfun->rtl_inline_init)
-    return 0;
-  cfun->rtl_inline_init = 1;
-
-  /* If this is nested inside an inlined external function, pretend
-     it was only declared.  Since we cannot inline such functions,
-     generating code for this one is not only not necessary but will
-     confuse some debugging output writers.  */
-  for (parent = DECL_CONTEXT (current_function_decl);
-       parent != NULL_TREE;
-       parent = get_containing_scope (parent))
-    if (TREE_CODE (parent) == FUNCTION_DECL
-       && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
-      {
-       DECL_INITIAL (decl) = 0;
-       return true;
-      }
-    else if (TYPE_P (parent))
-      /* A function in a local class should be treated normally.  */
-      break;
-
-  /* If requested, consider whether to make this function inline.  */
-  if ((DECL_INLINE (decl) && !flag_no_inline)
-      || flag_inline_functions)
-    {
-      timevar_push (TV_INTEGRATION);
-      lose = function_cannot_inline_p (decl);
-      timevar_pop (TV_INTEGRATION);
-      if (lose || ! optimize)
-       {
-         if (warn_inline && lose && DECL_INLINE (decl))
-            {
-              char *msg = concat ("%J", lose, NULL);
-              warning (msg, decl);
-              free (msg);
-            }
-         DECL_ABSTRACT_ORIGIN (decl) = 0;
-         /* Don't really compile an extern inline function.
-            If we can't make it inline, pretend
-            it was only declared.  */
-         if (DECL_EXTERNAL (decl))
-           {
-             DECL_INITIAL (decl) = 0;
-             return true;
-           }
-       }
-      else
-       inlinable = DECL_INLINE (decl) = 1;
-    }
-
-  insns = get_insns ();
-
-  /* Dump the rtl code if we are dumping rtl.  */
-
-  if (open_dump_file (DFI_rtl, decl))
-    {
-      if (DECL_STRUCT_FUNCTION (decl)
-         && DECL_STRUCT_FUNCTION (decl)->saved_for_inline)
-       fprintf (dump_file, ";; (integrable)\n\n");
-      close_dump_file (DFI_rtl, print_rtl, insns);
-    }
-
-  /* Convert from NOTE_INSN_EH_REGION style notes, and do other
-     sorts of eh initialization.  Delay this until after the
-     initial rtl dump so that we can see the original nesting.  */
-  convert_from_eh_region_ranges ();
-
-  /* If function is inline, and we don't yet know whether to
-     compile it by itself, defer decision till end of compilation.
-     wrapup_global_declarations will (indirectly) call
-     rest_of_compilation again for those functions that need to
-     be output.  Also defer those functions that we are supposed
-     to defer.  */
-
-  if (inlinable
-      || (DECL_INLINE (decl)
-         /* Egad.  This RTL deferral test conflicts with Fortran assumptions
-            for unreferenced symbols.  See g77.f-torture/execute/980520-1.f.
-            But removing this line from the check breaks all languages that
-            use the call graph to output symbols.  This hard-coded check is
-            the least invasive work-around.  */
-         && (flag_inline_functions
-             || strcmp (lang_hooks.name, "GNU F77") == 0)
-         && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
-              && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
-              && ! flag_keep_inline_functions)
-             || DECL_EXTERNAL (decl))))
-    DECL_DEFER_OUTPUT (decl) = 1;
-
-  if (DECL_INLINE (decl))
-    /* DWARF wants separate debugging info for abstract and
-       concrete instances of all inline functions, including those
-       declared inline but not inlined, and those inlined even
-       though they weren't declared inline.  Conveniently, that's
-       what DECL_INLINE means at this point.  */
-    (*debug_hooks->deferred_inline_function) (decl);
-
-  if (DECL_DEFER_OUTPUT (decl))
-    {
-      /* If -Wreturn-type, we have to do a bit of compilation.  We just
-        want to call cleanup the cfg to figure out whether or not we can
-        fall off the end of the function; we do the minimum amount of
-        work necessary to make that safe.  */
-      if (warn_return_type)
-       {
-         int saved_optimize = optimize;
-
-         optimize = 0;
-         rebuild_jump_labels (insns);
-         find_exception_handler_labels ();
-         find_basic_blocks (insns, max_reg_num (), dump_file);
-         cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
-         optimize = saved_optimize;
-
-         /* CFG is no longer maintained up-to-date.  */
-         free_bb_for_insn ();
-       }
-
-      set_nothrow_function_flags ();
-      if (current_function_nothrow)
-       /* Now we know that this can't throw; set the flag for the benefit
-          of other functions later in this translation unit.  */
-       TREE_NOTHROW (current_function_decl) = 1;
-
-      timevar_push (TV_INTEGRATION);
-      save_for_inline (decl);
-      timevar_pop (TV_INTEGRATION);
-      DECL_STRUCT_FUNCTION (decl)->inlinable = inlinable;
-      return true;
-    }
-
-  /* If specified extern inline but we aren't inlining it, we are
-     done.  This goes for anything that gets here with DECL_EXTERNAL
-     set, not just things with DECL_INLINE.  */
-  return (bool) DECL_EXTERNAL (decl);
-}
-
-/* Try to identify useless null pointer tests and delete them.  */
-static void
-rest_of_handle_null_pointer (tree decl, rtx insns)
-{
-  open_dump_file (DFI_null, decl);
-  if (dump_file)
-    dump_flow_info (dump_file);
-
-  if (delete_null_pointer_checks (insns))
-    cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-
-  close_dump_file (DFI_null, print_rtl_with_bb, insns);
-}
-
 /* Try combining insns through substitution.  */
 static void
 rest_of_handle_combine (tree decl, rtx insns)
@@ -1234,18 +1045,17 @@ rest_of_handle_life (tree decl, rtx insns)
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
-  life_analysis (insns, dump_file, PROP_FINAL);
+  life_analysis (dump_file, PROP_FINAL);
   if (optimize)
     cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
                 | CLEANUP_LOG_LINKS
                 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
   timevar_pop (TV_FLOW);
 
-  if (warn_uninitialized)
+  if (extra_warnings)
     {
-      uninitialized_vars_warning (DECL_INITIAL (decl));
-      if (extra_warnings)
-       setjmp_args_warning ();
+      setjmp_vars_warning (DECL_INITIAL (decl));
+      setjmp_args_warning ();
     }
 
   if (optimize)
@@ -1297,19 +1107,6 @@ rest_of_handle_cse (tree decl, rtx insns)
 
   if (tem || optimize > 1)
     cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-  /* Try to identify useless null pointer tests and delete them.  */
-  if (flag_delete_null_pointer_checks)
-    {
-      timevar_push (TV_JUMP);
-
-      if (delete_null_pointer_checks (insns))
-       cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-      timevar_pop (TV_JUMP);
-    }
-
-  /* The second pass of jump optimization is likely to have
-     removed a bunch more instructions.  */
-  renumber_insns (dump_file);
 
   timevar_pop (TV_CSE);
   close_dump_file (DFI_cse, print_rtl_with_bb, insns);
@@ -1368,10 +1165,6 @@ rest_of_handle_gcse (tree decl, rtx insns)
   save_cfj = flag_cse_follow_jumps;
   flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
 
-  /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
-  if (current_function_calls_constant_p)
-    purge_builtin_constant_p ();
-
   /* If -fexpensive-optimizations, re-run CSE to clean up things done
      by gcse.  */
   if (flag_expensive_optimizations)
@@ -1552,20 +1345,31 @@ rest_of_compilation (tree decl)
      have been run to re-initialize it.  */
   cse_not_expected = ! optimize;
 
-  /* First, make sure that NOTE_BLOCK is set correctly for each
-     NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
-  if (!cfun->x_whole_function_mode_p)
-    identify_blocks ();
-
-  /* In function-at-a-time mode, we do not attempt to keep the BLOCK
-     tree in sensible shape.  So, we just recalculate it here.  */
-  if (cfun->x_whole_function_mode_p)
-    reorder_blocks ();
+  if (!cfun->dont_emit_block_notes)
+    {
+      /* First, make sure that NOTE_BLOCK is set correctly for each
+        NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
+      if (!cfun->x_whole_function_mode_p)
+       identify_blocks ();
+
+      /* In function-at-a-time mode, we do not attempt to keep the BLOCK
+        tree in sensible shape.  So, we just recalculate it here.  */
+      if (cfun->x_whole_function_mode_p)
+       reorder_blocks ();
+    }
+  else
+    finalize_block_changes ();
 
   init_flow ();
 
-  if (rest_of_handle_inlining (decl))
-    goto exit_rest_of_compilation;
+  /* Dump the rtl code if we are dumping rtl.  */
+  if (open_dump_file (DFI_rtl, decl))
+    close_dump_file (DFI_rtl, print_rtl, get_insns ());
+
+  /* Convert from NOTE_INSN_EH_REGION style notes, and do other
+     sorts of eh initialization.  Delay this until after the
+     initial rtl dump so that we can see the original nesting.  */
+  convert_from_eh_region_ranges ();
 
   /* If we're emitting a nested function, make sure its parent gets
      emitted as well.  Doing otherwise confuses debug info.  */
@@ -1588,7 +1392,8 @@ rest_of_compilation (tree decl)
      over the instruction sequence faster, and allow the garbage
      collector to reclaim the memory used by the notes.  */
   remove_unnecessary_notes ();
-  reorder_blocks ();
+  if (!cfun->dont_emit_block_notes)
+    reorder_blocks ();
 
   ggc_collect ();
 
@@ -1631,19 +1436,11 @@ rest_of_compilation (tree decl)
       timevar_pop (TV_BRANCH_PROB);
     }
 
-  if (flag_optimize_sibling_calls)
-    rest_of_handle_sibling_calls (insns);
-
-  /* We have to issue these warnings now already, because CFG cleanups
-     further down may destroy the required information.  However, this
-     must be done after the sibcall optimization pass because the barrier
-     emitted for noreturn calls that are candidate for the optimization
-     is folded into the CALL_PLACEHOLDER until after this pass, so the
-     CFG is inaccurate.  */
-  check_function_return_warnings ();
-
   timevar_pop (TV_JUMP);
 
+  if (cfun->tail_call_emit)
+    fixup_tail_calls ();
+
   insn_locators_initialize ();
   /* Complete generation of exception handling code.  */
   if (doing_eh (0))
@@ -1708,12 +1505,8 @@ rest_of_compilation (tree decl)
   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
               | (flag_thread_jumps ? CLEANUP_THREADING : 0));
 
-  if (optimize)
-    {
-      free_bb_for_insn ();
-      copy_loop_headers (insns);
-      find_basic_blocks (insns, max_reg_num (), dump_file);
-    }
+  create_loop_notes ();
+
   purge_line_number_notes (insns);
 
   timevar_pop (TV_JUMP);
@@ -1728,9 +1521,6 @@ rest_of_compilation (tree decl)
   if (optimize)
     cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
-  if (flag_delete_null_pointer_checks)
-    rest_of_handle_null_pointer (decl, insns);
-
   /* Jump optimization, and the removal of NULL pointer checks, may
      have reduced the number of instructions substantially.  CSE, and
      future passes, allocate arrays whose dimensions involve the
@@ -1766,9 +1556,12 @@ rest_of_compilation (tree decl)
 
   rest_of_handle_cfg (decl, insns);
 
-  if (optimize > 0
-      || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+  if (!flag_tree_based_profiling
+      && (optimize > 0 || profile_arc_flag
+         || flag_test_coverage || flag_branch_probabilities))
     {
+      rtl_register_profile_hooks ();
+      rtl_register_value_prof_hooks ();
       rest_of_handle_branch_prob (decl, insns);
 
       if (flag_branch_probabilities
@@ -1904,7 +1697,7 @@ rest_of_compilation (tree decl)
       {
        open_dump_file (DFI_branch_target_load, decl);
 
-       branch_target_load_optimize (insns, false);
+       branch_target_load_optimize (/*after_prologue_epilogue_gen=*/false);
 
        close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
 
@@ -1923,7 +1716,7 @@ rest_of_compilation (tree decl)
 
   if (optimize)
     {
-      life_analysis (insns, dump_file, PROP_POSTRELOAD);
+      life_analysis (dump_file, PROP_POSTRELOAD);
       cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
                   | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
 
@@ -1993,7 +1786,7 @@ rest_of_compilation (tree decl)
 
       open_dump_file (DFI_branch_target_load, decl);
 
-      branch_target_load_optimize (insns, true);
+      branch_target_load_optimize (/*after_prologue_epilogue_gen=*/true);
 
       close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
 
@@ -2095,7 +1888,7 @@ rest_of_compilation (tree decl)
   /* Show no temporary slots allocated.  */
   init_temp_slots ();
 
-  free_basic_block_vars (0);
+  free_basic_block_vars ();
   free_bb_for_insn ();
 
   timevar_pop (TV_FINAL);