| Index: gcc/gcc/cfglayout.c
|
| diff --git a/gcc/gcc/cfglayout.c b/gcc/gcc/cfglayout.c
|
| index 27eb029d076688b67bdd35dc439d377aa6329f90..5e120570b9a030fcd073e74582df4ed6a8b04256 100644
|
| --- a/gcc/gcc/cfglayout.c
|
| +++ b/gcc/gcc/cfglayout.c
|
| @@ -1,5 +1,5 @@
|
| /* Basic block reordering routines for the GNU compiler.
|
| - Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
|
| + Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
| Free Software Foundation, Inc.
|
|
|
| This file is part of GCC.
|
| @@ -112,9 +112,7 @@ skip_insns_after_block (basic_block bb)
|
|
|
| case CODE_LABEL:
|
| if (NEXT_INSN (insn)
|
| - && JUMP_P (NEXT_INSN (insn))
|
| - && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
|
| - || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
|
| + && JUMP_TABLE_DATA_P (NEXT_INSN (insn)))
|
| {
|
| insn = NEXT_INSN (insn);
|
| last_insn = insn;
|
| @@ -240,7 +238,7 @@ int epilogue_locator;
|
| /* Hold current location information and last location information, so the
|
| datastructures are built lazily only when some instructions in given
|
| place are needed. */
|
| -location_t curr_location, last_location;
|
| +static location_t curr_location, last_location;
|
| static tree curr_block, last_block;
|
| static int curr_rtl_loc = -1;
|
|
|
| @@ -292,12 +290,17 @@ set_curr_insn_source_location (location_t location)
|
| time locators are not initialized. */
|
| if (curr_rtl_loc == -1)
|
| return;
|
| - if (location == last_location)
|
| - return;
|
| curr_location = location;
|
| }
|
|
|
| -/* Set current scope block. */
|
| +/* Get current location. */
|
| +location_t
|
| +get_curr_insn_source_location (void)
|
| +{
|
| + return curr_location;
|
| +}
|
| +
|
| +/* Set current scope block. */
|
| void
|
| set_curr_insn_block (tree b)
|
| {
|
| @@ -309,6 +312,13 @@ set_curr_insn_block (tree b)
|
| curr_block = b;
|
| }
|
|
|
| +/* Get current scope block. */
|
| +tree
|
| +get_curr_insn_block (void)
|
| +{
|
| + return curr_block;
|
| +}
|
| +
|
| /* Return current insn locator. */
|
| int
|
| curr_insn_locator (void)
|
| @@ -363,9 +373,9 @@ struct rtl_opt_pass pass_into_cfg_layout_mode =
|
| NULL, /* sub */
|
| NULL, /* next */
|
| 0, /* static_pass_number */
|
| - 0, /* tv_id */
|
| + TV_NONE, /* tv_id */
|
| 0, /* properties_required */
|
| - 0, /* properties_provided */
|
| + PROP_cfglayout, /* properties_provided */
|
| 0, /* properties_destroyed */
|
| 0, /* todo_flags_start */
|
| TODO_dump_func, /* todo_flags_finish */
|
| @@ -382,10 +392,10 @@ struct rtl_opt_pass pass_outof_cfg_layout_mode =
|
| NULL, /* sub */
|
| NULL, /* next */
|
| 0, /* static_pass_number */
|
| - 0, /* tv_id */
|
| + TV_NONE, /* tv_id */
|
| 0, /* properties_required */
|
| 0, /* properties_provided */
|
| - 0, /* properties_destroyed */
|
| + PROP_cfglayout, /* properties_destroyed */
|
| 0, /* todo_flags_start */
|
| TODO_dump_func, /* todo_flags_finish */
|
| }
|
| @@ -585,9 +595,7 @@ reemit_insn_block_notes (void)
|
| tree this_block;
|
|
|
| /* Avoid putting scope notes between jump table and its label. */
|
| - if (JUMP_P (insn)
|
| - && (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
| - || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
|
| + if (JUMP_TABLE_DATA_P (insn))
|
| continue;
|
|
|
| this_block = insn_scope (insn);
|
| @@ -686,7 +694,7 @@ relink_block_chain (bool stay_in_cfglayout_mode)
|
| free_original_copy_tables ();
|
| if (stay_in_cfglayout_mode)
|
| initialize_original_copy_tables ();
|
| -
|
| +
|
| /* Finally, put basic_block_info in the new order. */
|
| compact_blocks ();
|
| }
|
| @@ -779,6 +787,18 @@ fixup_reorder_chain (void)
|
| {
|
| if (any_condjump_p (bb_end_insn))
|
| {
|
| + /* This might happen if the conditional jump has side
|
| + effects and could therefore not be optimized away.
|
| + Make the basic block to end with a barrier in order
|
| + to prevent rtl_verify_flow_info from complaining. */
|
| + if (!e_fall)
|
| + {
|
| + gcc_assert (!onlyjump_p (bb_end_insn)
|
| + || returnjump_p (bb_end_insn));
|
| + bb->il.rtl->footer = emit_barrier_after (bb_end_insn);
|
| + continue;
|
| + }
|
| +
|
| /* If the old fallthru is still next, nothing to do. */
|
| if (bb->aux == e_fall->dest
|
| || e_fall->dest == EXIT_BLOCK_PTR)
|
| @@ -840,6 +860,18 @@ fixup_reorder_chain (void)
|
| continue;
|
| }
|
| }
|
| + else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL)
|
| + {
|
| + /* If the old fallthru is still next or if
|
| + asm goto doesn't have a fallthru (e.g. when followed by
|
| + __builtin_unreachable ()), nothing to do. */
|
| + if (! e_fall
|
| + || bb->aux == e_fall->dest
|
| + || e_fall->dest == EXIT_BLOCK_PTR)
|
| + continue;
|
| +
|
| + /* Otherwise we'll have to use the fallthru fixup below. */
|
| + }
|
| else
|
| {
|
| /* Otherwise we have some return, switch or computed
|
| @@ -900,7 +932,7 @@ fixup_reorder_chain (void)
|
| FOR_EACH_EDGE (e, ei, bb->succs)
|
| if (e->flags & EDGE_FALLTHRU)
|
| break;
|
| -
|
| +
|
| if (e && !can_fallthru (e->src, e->dest))
|
| force_nonfallthru (e);
|
| }
|
| @@ -1112,7 +1144,7 @@ cfg_layout_can_duplicate_bb_p (const_basic_block bb)
|
| rtx
|
| duplicate_insn_chain (rtx from, rtx to)
|
| {
|
| - rtx insn, last;
|
| + rtx insn, last, copy;
|
|
|
| /* Avoid updating of boundaries of previous basic block. The
|
| note will get removed from insn stream in fixup. */
|
| @@ -1124,6 +1156,7 @@ duplicate_insn_chain (rtx from, rtx to)
|
| {
|
| switch (GET_CODE (insn))
|
| {
|
| + case DEBUG_INSN:
|
| case INSN:
|
| case CALL_INSN:
|
| case JUMP_INSN:
|
| @@ -1133,7 +1166,8 @@ duplicate_insn_chain (rtx from, rtx to)
|
| if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
| || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
|
| break;
|
| - emit_copy_of_insn_after (insn, get_last_insn ());
|
| + copy = emit_copy_of_insn_after (insn, get_last_insn ());
|
| + maybe_copy_epilogue_insn (insn, copy);
|
| break;
|
|
|
| case CODE_LABEL:
|
| @@ -1153,23 +1187,18 @@ duplicate_insn_chain (rtx from, rtx to)
|
| case NOTE_INSN_DELETED:
|
| case NOTE_INSN_DELETED_LABEL:
|
| /* No problem to strip these. */
|
| - case NOTE_INSN_EPILOGUE_BEG:
|
| - /* Debug code expect these notes to exist just once.
|
| - Keep them in the master copy.
|
| - ??? It probably makes more sense to duplicate them for each
|
| - epilogue copy. */
|
| case NOTE_INSN_FUNCTION_BEG:
|
| /* There is always just single entry to function. */
|
| case NOTE_INSN_BASIC_BLOCK:
|
| break;
|
|
|
| + case NOTE_INSN_EPILOGUE_BEG:
|
| case NOTE_INSN_SWITCH_TEXT_SECTIONS:
|
| emit_note_copy (insn);
|
| break;
|
|
|
| default:
|
| - /* All other notes should have already been eliminated.
|
| - */
|
| + /* All other notes should have already been eliminated. */
|
| gcc_unreachable ();
|
| }
|
| break;
|
|
|