aboutsummaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/gcc/final.c b/gcc/final.c
index b53e9a8..9aa4657 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1623,6 +1623,35 @@ 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 (GET_CODE (temp) == NOTE
+ && NOTE_LINE_NUMBER (temp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
+ return true;
+ if (GET_CODE (temp) == NOTE
+ && 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.
@@ -1672,7 +1701,31 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
case NOTE_INSN_EXPECTED_VALUE:
break;
+ case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
+
+ /* 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 ();
+ break;
+
case NOTE_INSN_BASIC_BLOCK:
+
+ /* If we are performing the optimization that paritions
+ 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
+ && in_unlikely_text_section()
+ && !scan_ahead_for_unlikely_executed_note (insn))
+ text_section ();
+
#ifdef IA64_UNWIND_INFO
IA64_UNWIND_EMIT (asm_out_file, insn);
#endif
@@ -1859,6 +1912,27 @@ 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)
+ {
+ rtx tmp_table, tmp_label;
+ if (GET_CODE (insn) == CODE_LABEL
+ && 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 ())
+ text_section ();
+ }
+ }
+
if (app_on)
{
fputs (ASM_APP_OFF, file);