Commit 87c8b4be by Caroline Tice

Fix problems with hot/cold partitioning optimization.

From-SVN: r97322
parent 68ec3111
......@@ -1874,7 +1874,7 @@ rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
$(FLAGS_H) function.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
output.h $(C_PRAGMA_H) toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h real.h
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h real.h $(BASIC_BLOCK_H)
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(CFGLAYOUT_H) $(TREE_GIMPLE_H) \
$(FLAGS_H) function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
......@@ -2174,7 +2174,7 @@ lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
$(RTL_H) $(GGC_H) gt-lists.h
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \
$(TARGET_H) function.h $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H)
$(TARGET_H) function.h $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) errors.h
tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(BASIC_BLOCK_H) hard-reg-set.h output.h $(CFGLAYOUT_H) $(FLAGS_H) $(TIMEVAR_H) \
$(PARAMS_H) $(COVERAGE_H)
......@@ -3731,7 +3731,7 @@ STAGEPROFILE_FLAGS_TO_PASS = \
# Files never linked into the final executable produces warnings about missing
# profile.
STAGEFEEDBACK_FLAGS_TO_PASS = \
CFLAGS="$(BOOT_CFLAGS) -fprofile-use"
CFLAGS="$(BOOT_CFLAGS) -fprofile-use -freorder-blocks-and-partition"
# Only build the C compiler for stage1, because that is the only one that
# we can guarantee will build with the native compiler, and also it is the
......
......@@ -155,9 +155,8 @@ try_simplify_condjump (basic_block cbranch_block)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
|| (cbranch_jump_edge->flags & EDGE_CROSSING)))
if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
|| (cbranch_jump_edge->flags & EDGE_CROSSING))
return false;
/* The conditional branch must target the block after the
......@@ -435,8 +434,7 @@ try_forward_edges (int mode, basic_block b)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
if (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
return false;
for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
......@@ -471,8 +469,7 @@ try_forward_edges (int mode, basic_block b)
bb-reorder.c:partition_hot_cold_basic_blocks for complete
details. */
if (flag_reorder_blocks_and_partition
&& first != EXIT_BLOCK_PTR
if (first != EXIT_BLOCK_PTR
&& find_reg_note (BB_END (first), REG_CROSSING_JUMP, NULL_RTX))
return false;
......@@ -684,9 +681,7 @@ merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (BB_PARTITION (a) != BB_PARTITION (b)
|| find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)))
if (BB_PARTITION (a) != BB_PARTITION (b))
return;
barrier = next_nonnote_insn (BB_END (a));
......@@ -742,9 +737,7 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (a) != BB_PARTITION (b)))
if (BB_PARTITION (a) != BB_PARTITION (b))
return;
real_b_end = BB_END (b);
......@@ -814,10 +807,7 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
|| find_reg_note (BB_END (c), REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (b) != BB_PARTITION (c)))
if (BB_PARTITION (b) != BB_PARTITION (c))
return NULL;
......@@ -1725,9 +1715,9 @@ try_crossjump_bb (int mode, basic_block bb)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (BB_PARTITION (EDGE_PRED (bb, 0)->src) != BB_PARTITION (EDGE_PRED (bb, 1)->src)
|| (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING)))
if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
BB_PARTITION (EDGE_PRED (bb, 1)->src)
|| (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
return false;
/* It is always cheapest to redirect a block that ends in a branch to
......
......@@ -51,7 +51,6 @@ static void change_scope (rtx, tree, tree);
void verify_insn_chain (void);
static void fixup_fallthru_exit_predecessor (void);
static tree insn_scope (rtx);
static void update_unlikely_executed_notes (basic_block);
rtx
unlink_insn_chain (rtx first, rtx last)
......@@ -784,28 +783,12 @@ fixup_reorder_chain (void)
section boundaries). */
BB_COPY_PARTITION (e_fall->src, single_pred (bb));
if (flag_reorder_blocks_and_partition
&& targetm.have_named_sections)
{
if (BB_PARTITION (single_pred (bb)) == BB_COLD_PARTITION)
{
rtx new_note;
rtx note = BB_HEAD (e_fall->src);
while (!INSN_P (note)
&& note != BB_END (e_fall->src))
note = NEXT_INSN (note);
new_note = emit_note_before
(NOTE_INSN_UNLIKELY_EXECUTED_CODE,
note);
NOTE_BASIC_BLOCK (new_note) = bb;
}
if (JUMP_P (BB_END (bb))
&& !any_condjump_p (BB_END (bb))
&& (single_succ_edge (bb)->flags & EDGE_CROSSING))
REG_NOTES (BB_END (bb)) = gen_rtx_EXPR_LIST
(REG_CROSSING_JUMP, NULL_RTX, REG_NOTES (BB_END (bb)));
}
&& targetm.have_named_sections
&& JUMP_P (BB_END (bb))
&& !any_condjump_p (BB_END (bb))
&& (EDGE_SUCC (bb, 0)->flags & EDGE_CROSSING))
REG_NOTES (BB_END (bb)) = gen_rtx_EXPR_LIST
(REG_CROSSING_JUMP, NULL_RTX, REG_NOTES (BB_END (bb)));
}
}
......@@ -840,8 +823,6 @@ fixup_reorder_chain (void)
bb->index = index;
BASIC_BLOCK (index) = bb;
update_unlikely_executed_notes (bb);
bb->prev_bb = prev_bb;
prev_bb->next_bb = bb;
}
......@@ -863,21 +844,6 @@ fixup_reorder_chain (void)
}
}
/* Update the basic block number information in any
NOTE_INSN_UNLIKELY_EXECUTED_CODE notes within the basic block. */
static void
update_unlikely_executed_notes (basic_block bb)
{
rtx cur_insn;
for (cur_insn = BB_HEAD (bb); cur_insn != BB_END (bb);
cur_insn = NEXT_INSN (cur_insn))
if (NOTE_P (cur_insn)
&& NOTE_LINE_NUMBER (cur_insn) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
NOTE_BASIC_BLOCK (cur_insn) = bb;
}
/* Perform sanity checks on the insn chain.
1. Check that next/prev pointers are consistent in both the forward and
reverse direction.
......@@ -1046,7 +1012,7 @@ duplicate_insn_chain (rtx from, rtx to)
break;
case NOTE_INSN_REPEATED_LINE_NUMBER:
case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
emit_note_copy (insn);
break;
......
......@@ -32,7 +32,6 @@ extern void reemit_insn_block_notes (void);
extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *,
edge *, unsigned, edge *, struct loop *);
extern bool scan_ahead_for_unlikely_executed_note (rtx);
extern rtx duplicate_insn_chain (rtx, rtx);
#endif /* GCC_CFGLAYOUT_H */
......@@ -92,8 +92,7 @@ static int
can_delete_note_p (rtx note)
{
return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_UNLIKELY_EXECUTED_CODE);
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK);
}
/* True if a given label can be deleted. */
......@@ -616,10 +615,7 @@ rtl_can_merge_blocks (basic_block a,basic_block b)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)
|| find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (a) != BB_PARTITION (b)))
if (BB_PARTITION (a) != BB_PARTITION (b))
return false;
/* There must be exactly one edge in between the blocks. */
......@@ -678,9 +674,8 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (src) != BB_PARTITION (target)))
if (find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (src) != BB_PARTITION (target))
return NULL;
/* We can replace or remove a complex jump only when we have exactly
......@@ -1108,29 +1103,16 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
BB_COPY_PARTITION (jump_block, e->src);
if (flag_reorder_blocks_and_partition
&& targetm.have_named_sections)
{
if (BB_PARTITION (jump_block) == BB_COLD_PARTITION)
{
rtx bb_note, new_note;
for (bb_note = BB_HEAD (jump_block);
bb_note && bb_note != NEXT_INSN (BB_END (jump_block));
bb_note = NEXT_INSN (bb_note))
if (NOTE_P (bb_note)
&& NOTE_LINE_NUMBER (bb_note) == NOTE_INSN_BASIC_BLOCK)
break;
new_note = emit_note_after (NOTE_INSN_UNLIKELY_EXECUTED_CODE,
bb_note);
NOTE_BASIC_BLOCK (new_note) = jump_block;
}
if (JUMP_P (BB_END (jump_block))
&& !any_condjump_p (BB_END (jump_block))
&& (single_succ_edge (jump_block)->flags & EDGE_CROSSING))
REG_NOTES (BB_END (jump_block)) = gen_rtx_EXPR_LIST
(REG_CROSSING_JUMP, NULL_RTX,
REG_NOTES (BB_END (jump_block)));
}
&& targetm.have_named_sections
&& JUMP_P (BB_END (jump_block))
&& !any_condjump_p (BB_END (jump_block))
&& (EDGE_SUCC (jump_block, 0)->flags & EDGE_CROSSING))
REG_NOTES (BB_END (jump_block)) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP,
NULL_RTX,
REG_NOTES
(BB_END
(jump_block)));
/* Wire edge in. */
new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
new_edge->probability = e->probability;
......@@ -1576,10 +1558,6 @@ commit_one_edge_insertion (edge e, int watch_calls)
tmp = NEXT_INSN (tmp);
if (NOTE_INSN_BASIC_BLOCK_P (tmp))
tmp = NEXT_INSN (tmp);
if (tmp
&& NOTE_P (tmp)
&& NOTE_LINE_NUMBER (tmp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
tmp = NEXT_INSN (tmp);
if (tmp == BB_HEAD (bb))
before = tmp;
else if (tmp)
......@@ -1629,7 +1607,7 @@ commit_one_edge_insertion (edge e, int watch_calls)
&& BB_PARTITION (e->src) == BB_COLD_PARTITION
&& !(e->flags & EDGE_CROSSING))
{
rtx bb_note, new_note, cur_insn;
rtx bb_note, cur_insn;
bb_note = NULL_RTX;
for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb));
......@@ -1641,16 +1619,11 @@ commit_one_edge_insertion (edge e, int watch_calls)
break;
}
new_note = emit_note_after (NOTE_INSN_UNLIKELY_EXECUTED_CODE,
bb_note);
NOTE_BASIC_BLOCK (new_note) = bb;
if (JUMP_P (BB_END (bb))
&& !any_condjump_p (BB_END (bb))
&& (single_succ_edge (bb)->flags & EDGE_CROSSING))
REG_NOTES (BB_END (bb)) = gen_rtx_EXPR_LIST
(REG_CROSSING_JUMP, NULL_RTX, REG_NOTES (BB_END (bb)));
if (after == bb_note)
after = new_note;
}
}
}
......@@ -2717,10 +2690,7 @@ cfg_layout_can_merge_blocks_p (basic_block a, basic_block b)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& (find_reg_note (BB_END (a), REG_CROSSING_JUMP, NULL_RTX)
|| find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
|| BB_PARTITION (a) != BB_PARTITION (b)))
if (BB_PARTITION (a) != BB_PARTITION (b))
return false;
/* There must be exactly one edge in between the blocks. */
......
......@@ -1016,12 +1016,17 @@ machopic_select_section (tree exp, int reloc,
bool weak_p = DECL_P (exp) && DECL_WEAK (exp);
static void (* const base_funs[][2])(void) = {
{ text_section, text_coal_section },
{ text_unlikely_section, text_unlikely_coal_section },
{ unlikely_text_section, text_unlikely_coal_section },
{ readonly_data_section, const_coal_section },
{ const_data_section, const_data_coal_section },
{ data_section, data_coal_section }
};
if (reloc == 0
&& (last_text_section == in_text_unlikely
|| last_text_section == in_text_unlikely_coal))
reloc = 1;
if (TREE_CODE (exp) == FUNCTION_DECL)
base_function = base_funs[reloc][weak_p];
else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
......
......@@ -621,6 +621,10 @@ FUNCTION (void) \
if (asm_out_file) \
fputs ("\t" DIRECTIVE "\n", asm_out_file); \
in_section = SECTION; \
if ((SECTION == in_text_coal) \
|| (SECTION == in_text_unlikely) \
|| (SECTION == in_text_unlikely_coal)) \
last_text_section = SECTION; \
} \
} \
......@@ -660,10 +664,6 @@ SECTION_FUNCTION (text_coal_section, \
in_text_coal, \
".section __TEXT,__textcoal_nt,coalesced," \
"pure_instructions", 0) \
SECTION_FUNCTION (text_unlikely_section, \
in_text_unlikely, \
".section __TEXT,__text_unlikely,coalesced," \
"pure_instructions", 0) \
SECTION_FUNCTION (text_unlikely_coal_section, \
in_text_unlikely_coal, \
".section __TEXT,__text_unlikely_coal," \
......
......@@ -8201,7 +8201,7 @@ sparc_output_deferred_case_vectors (void)
return;
/* Align to cache line in the function's code section. */
function_section (current_function_decl);
current_function_section (current_function_decl);
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align > 0)
......
......@@ -2074,7 +2074,7 @@ xstormy16_output_addr_vec (FILE *file, rtx label ATTRIBUTE_UNUSED, rtx table)
{
int vlen, idx;
function_section (current_function_decl);
current_function_section (current_function_decl);
vlen = XVECLEN (table, 0);
for (idx = 0; idx < vlen; idx++)
......
......@@ -1560,6 +1560,15 @@ override_options (void)
/* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
if (flag_pic > 1)
flag_pic = 1;
/* Hot/cold partitioning does not work on this architecture, because of
constant pools (the load instruction cannot necessarily reach that far).
Therefore disable it on this architecture. */
if (flag_reorder_blocks_and_partition)
{
flag_reorder_blocks_and_partition = 0;
flag_reorder_blocks = 1;
}
}
......
......@@ -275,7 +275,7 @@ static int pending_bincls = 0;
static const char *base_input_file;
#ifdef DEBUG_SYMS_TEXT
#define FORCE_TEXT function_section (current_function_decl);
#define FORCE_TEXT current_function_section (current_function_decl);
#else
#define FORCE_TEXT
#endif
......@@ -379,6 +379,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
debug_nothing_rtx, /* label */
dbxout_handle_pch, /* handle_pch */
debug_nothing_rtx, /* var_location */
debug_nothing_void, /* switch_text_section */
0 /* start_end_main_source_file */
};
#endif /* DBX_DEBUGGING_INFO */
......@@ -410,6 +411,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
debug_nothing_rtx, /* label */
dbxout_handle_pch, /* handle_pch */
debug_nothing_rtx, /* var_location */
debug_nothing_void, /* switch_text_section */
0 /* start_end_main_source_file */
};
#endif /* XCOFF_DEBUGGING_INFO */
......@@ -934,9 +936,21 @@ dbxout_function_end (tree decl)
#ifdef DBX_OUTPUT_NFUN
DBX_OUTPUT_NFUN (asm_out_file, lscope_label_name, current_function_decl);
#else
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (lscope_label_name,
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
if (flag_reorder_blocks_and_partition)
{
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (hot_section_end_label, hot_section_label);
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (cold_section_end_label,
unlikely_section_label);
}
else
{
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (lscope_label_name,
XSTR (XEXP (DECL_RTL (current_function_decl),
0), 0));
}
#endif
......
......@@ -48,6 +48,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
debug_nothing_rtx, /* label */
debug_nothing_int, /* handle_pch */
debug_nothing_rtx, /* var_location */
debug_nothing_void, /* switch_text_section */
0 /* start_end_main_source_file */
};
......
......@@ -120,6 +120,10 @@ struct gcc_debug_hooks
/* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */
void (* var_location) (rtx);
/* Called from final_scan_insn if there is a switch between hot and cold
text sections. */
void (* switch_text_section) (void);
/* This is 1 if the debug writer wants to see start and end commands for the
main source files, and 0 otherwise. */
int start_end_main_source_file;
......
......@@ -3434,7 +3434,7 @@ output_function_exception_table (void)
dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
(i ? NULL : "Exception specification table"));
function_section (current_function_decl);
current_function_section (current_function_decl);
}
#include "gt-except.h"
......@@ -1426,7 +1426,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
}
function_section (current_function_decl);
current_function_section (current_function_decl);
#if defined(ASM_OUTPUT_REG_PUSH)
if (sval && svrtx != NULL_RTX && REG_P (svrtx))
......@@ -1619,35 +1619,6 @@ output_alternate_entry_point (FILE *file, rtx insn)
}
}
/* Return boolean indicating if there is a NOTE_INSN_UNLIKELY_EXECUTED_CODE
note in the instruction chain (going forward) between the current
instruction, and the next 'executable' instruction. */
bool
scan_ahead_for_unlikely_executed_note (rtx insn)
{
rtx temp;
int bb_note_count = 0;
for (temp = insn; temp; temp = NEXT_INSN (temp))
{
if (NOTE_P (temp)
&& NOTE_LINE_NUMBER (temp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
return true;
if (NOTE_P (temp)
&& NOTE_LINE_NUMBER (temp) == NOTE_INSN_BASIC_BLOCK)
{
bb_note_count++;
if (bb_note_count > 1)
return false;
}
if (INSN_P (temp))
return false;
}
return false;
}
/* The final scan for one insn, INSN.
Args are same as in `final', except that INSN
is the insn being scanned.
......@@ -1691,30 +1662,27 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
case NOTE_INSN_EXPECTED_VALUE:
break;
case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
/* The presence of this note indicates that this basic block
belongs in the "cold" section of the .o file. If we are
not already writing to the cold section we need to change
to it. */
unlikely_text_section ();
if (last_text_section == in_text)
{
(*debug_hooks->switch_text_section) ();
unlikely_text_section ();
}
else
{
(*debug_hooks->switch_text_section) ();
text_section ();
}
break;
case NOTE_INSN_BASIC_BLOCK:
/* If we are performing the optimization that partitions
basic blocks into hot & cold sections of the .o file,
then at the start of each new basic block, before
beginning to write code for the basic block, we need to
check to see whether the basic block belongs in the hot
or cold section of the .o file, and change the section we
are writing to appropriately. */
if (flag_reorder_blocks_and_partition
&& !scan_ahead_for_unlikely_executed_note (insn))
function_section (current_function_decl);
#ifdef TARGET_UNWIND_INFO
targetm.asm_out.unwind_emit (asm_out_file, insn);
#endif
......@@ -1896,25 +1864,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
if (LABEL_NAME (insn))
(*debug_hooks->label) (insn);
/* If we are doing the optimization that partitions hot & cold
basic blocks into separate sections of the .o file, we need
to ensure the jump table ends up in the correct section... */
if (flag_reorder_blocks_and_partition
&& targetm.have_named_sections)
{
rtx tmp_table, tmp_label;
if (LABEL_P (insn)
&& tablejump_p (NEXT_INSN (insn), &tmp_label, &tmp_table))
{
/* Do nothing; Do NOT change the current section. */
}
else if (scan_ahead_for_unlikely_executed_note (insn))
unlikely_text_section ();
else if (in_unlikely_text_section ())
function_section (current_function_decl);
}
if (app_on)
{
fputs (ASM_APP_OFF, file);
......@@ -1952,7 +1901,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
ASM_OUTPUT_ALIGN (file, log_align);
}
else
function_section (current_function_decl);
current_function_section (current_function_decl);
#ifdef ASM_OUTPUT_CASE_LABEL
ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
......@@ -2011,7 +1960,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
if (! JUMP_TABLES_IN_TEXT_SECTION)
targetm.asm_out.function_rodata_section (current_function_decl);
else
function_section (current_function_decl);
current_function_section (current_function_decl);
if (app_on)
{
......@@ -2069,7 +2018,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif
#endif
function_section (current_function_decl);
current_function_section (current_function_decl);
break;
}
......
......@@ -2865,12 +2865,13 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& ((BB_END (then_bb)
&& find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (else_bb)
&& find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
NULL_RTX))))
if ((BB_END (then_bb)
&& find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (test_bb)
&& find_reg_note (BB_END (test_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (else_bb)
&& find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
NULL_RTX)))
return FALSE;
/* THEN has one successor. */
......@@ -2970,12 +2971,13 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
partition boundaries). See the comments at the top of
bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */
if (flag_reorder_blocks_and_partition
&& ((BB_END (then_bb)
&& find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (else_bb)
&& find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
NULL_RTX))))
if ((BB_END (then_bb)
&& find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (test_bb)
&& find_reg_note (BB_END (test_bb), REG_CROSSING_JUMP, NULL_RTX))
|| (BB_END (else_bb)
&& find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
NULL_RTX)))
return FALSE;
/* ELSE has one successor. */
......
......@@ -88,9 +88,8 @@ INSN_NOTE (EXPECTED_VALUE)
now included in every insn. */
INSN_NOTE (BASIC_BLOCK)
/* Record that the current basic block is unlikely to be executed and
should be moved to the UNLIKELY_EXECUTED_TEXT_SECTION. FIXME: Make
this a bit on the basic block structure. */
INSN_NOTE (UNLIKELY_EXECUTED_CODE)
/* Mark the inflection point in the instruction stream where we switch
between hot and cold text sections. */
INSN_NOTE (SWITCH_TEXT_SECTIONS)
#undef INSN_NOTE
......@@ -669,24 +669,11 @@ decode_options (unsigned int argc, const char **argv)
if (flag_exceptions && flag_reorder_blocks_and_partition)
{
warning
inform
("-freorder-blocks-and-partition does not work with exceptions");
flag_reorder_blocks_and_partition = 0;
flag_reorder_blocks = 1;
}
/* The optimization to partition hot and cold basic blocks into
separate sections of the .o and executable files does not currently
work correctly with DWARF debugging turned on. Until this is fixed
we will disable the optimization when DWARF debugging is set. */
if (flag_reorder_blocks_and_partition && write_symbols == DWARF2_DEBUG)
{
warning
("-freorder-blocks-and-partition does not work with -g (currently)");
flag_reorder_blocks_and_partition = 0;
flag_reorder_blocks = 1;
}
}
/* Handle target- and language-independent options. Return zero to
......
......@@ -209,6 +209,9 @@ extern void named_section (tree, const char *, int);
/* Tell assembler to switch to the section for function DECL. */
extern void function_section (tree);
/* Tell assembler to switch to the most recently used text section. */
extern void current_function_section (tree);
/* Tell assembler to switch to the section for string merging. */
extern void mergeable_string_section (tree, unsigned HOST_WIDE_INT,
unsigned int);
......@@ -431,6 +434,34 @@ extern rtx this_is_asm_operands;
extern int size_directive_output;
extern tree last_assemble_variable_decl;
enum in_section { no_section, in_text, in_unlikely_executed_text, in_data,
in_named
#ifdef BSS_SECTION_ASM_OP
, in_bss
#endif
#ifdef CTORS_SECTION_ASM_OP
, in_ctors
#endif
#ifdef DTORS_SECTION_ASM_OP
, in_dtors
#endif
#ifdef READONLY_DATA_SECTION_ASM_OP
, in_readonly_data
#endif
#ifdef EXTRA_SECTIONS
, EXTRA_SECTIONS
#endif
};
extern char *unlikely_section_label;
extern char *hot_section_label;
extern char *hot_section_end_label;
extern char *cold_section_end_label;
extern char *unlikely_text_section_name;
extern const char *last_text_section_name;
extern enum in_section last_text_section;
extern bool first_function_block_is_cold;
/* Decide whether DECL needs to be in a writable section.
RELOC is the same as for SELECT_SECTION. */
extern bool decl_readonly_section (tree, int);
......@@ -519,6 +550,10 @@ extern bool default_valid_pointer_mode (enum machine_mode);
extern int default_address_cost (rtx);
/* When performing hot/cold basic block partitioning, insert note in
instruction stream indicating boundary between hot and cold sections. */
extern void insert_section_boundary_note (void);
/* dbxout helper functions */
#if defined DBX_DEBUGGING_INFO || defined XCOFF_DEBUGGING_INFO
......
......@@ -332,6 +332,8 @@ rest_of_handle_final (void)
timevar_push (TV_SYMOUT);
(*debug_hooks->function_decl) (current_function_decl);
if (unlikely_text_section_name)
free (unlikely_text_section_name);
timevar_pop (TV_SYMOUT);
ggc_collect ();
......
......@@ -319,7 +319,7 @@ print_rtx (rtx in_rtx)
}
break;
case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
{
#ifndef GENERATOR_FILE
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
......
......@@ -931,8 +931,6 @@ emit_swap_insn (rtx insn, stack regstack, rtx reg)
if (LABEL_P (tmp)
|| CALL_P (tmp)
|| NOTE_INSN_BASIC_BLOCK_P (tmp)
|| (NOTE_P (tmp)
&& NOTE_LINE_NUMBER (tmp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
|| (NONJUMP_INSN_P (tmp)
&& stack_regs_mentioned (tmp)))
{
......
......@@ -336,6 +336,7 @@ const struct gcc_debug_hooks sdb_debug_hooks =
sdbout_label, /* label */
debug_nothing_int, /* handle_pch */
debug_nothing_rtx, /* var_location */
debug_nothing_void, /* switch_text_section */
0 /* start_end_main_source_file */
};
......
......@@ -210,6 +210,7 @@ const struct gcc_debug_hooks vmsdbg_debug_hooks
debug_nothing_rtx, /* label */
debug_nothing_int, /* handle_pch */
debug_nothing_rtx, /* var_location */
debug_nothing_void, /* switch_text_section */
0 /* start_end_main_source_file */
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment