summaryrefslogtreecommitdiff
path: root/gcc/passes.c
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-13 06:41:07 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-13 06:41:07 +0000
commit4ee9c6840ad3fc92a9034343278a1e476ad6872a (patch)
treea2568888a519c077427b133de9ece5879a8484a5 /gcc/passes.c
parentebb338380ab170c91e64d38038e6b5ce930d69a1 (diff)
downloadgcc-4ee9c6840ad3fc92a9034343278a1e476ad6872a.tar.gz
Merge tree-ssa-20020619-branch into mainline.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81764 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/passes.c')
-rw-r--r--gcc/passes.c256
1 files changed, 39 insertions, 217 deletions
diff --git a/gcc/passes.c b/gcc/passes.c
index eaf4de5df41..43b46e2cae7 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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);
@@ -976,34 +977,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,155 +1004,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)
@@ -1241,11 +1065,10 @@ rest_of_handle_life (tree decl, rtx insns)
| (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)
@@ -1368,10 +1191,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 +1371,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 +1418,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 +1462,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 +1531,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);
@@ -1766,9 +1585,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