diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b6c6038989..fb7da456173 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-05-15 Teresa Johnson + + * function.h (has_bb_partition): New rtl_data flag. + (bb_reorder_complete): Ditto. + * cfgcleanup.c (try_crossjump_to_edge): Check for has_bb_partition + instead of flag_reorder_blocks_and_partition. + * cfgrtl.c (verify_hot_cold_block_grouping): Moved from bb-reorder.c, + with some enhancements. + (rtl_verify_flow_info_1): Call verify_hot_cold_block_grouping. + * bb-reorder.c (connect_traces): Check for has_bb_partition + instead of flag_reorder_blocks_and_partition. + (verify_hot_cold_block_grouping): Moved to cfgrtl.c. + (reorder_basic_blocks): Set bb_reorder_complete flag, remove call to + verify_hot_cold_block_grouping. + (partition_hot_cold_basic_blocks): Set has_bb_partition. + 2013-05-15 Ramana Radhakrishnan PR target/19599 diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index abb2e391983..3167220d972 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -1053,7 +1053,7 @@ connect_traces (int n_traces, struct trace *traces) current_partition = BB_PARTITION (traces[0].first); two_passes = false; - if (flag_reorder_blocks_and_partition) + if (crtl->has_bb_partition) for (i = 0; i < n_traces && !two_passes; i++) if (BB_PARTITION (traces[0].first) != BB_PARTITION (traces[i].first)) @@ -1262,7 +1262,7 @@ connect_traces (int n_traces, struct trace *traces) } } - if (flag_reorder_blocks_and_partition) + if (crtl->has_bb_partition) try_copy = false; /* Copy tiny blocks always; copy larger blocks only when the @@ -2068,43 +2068,6 @@ add_reg_crossing_jump_notes (void) add_reg_note (BB_END (e->src), REG_CROSSING_JUMP, NULL_RTX); } -/* Verify, in the basic block chain, that there is at most one switch - between hot/cold partitions. This is modelled on - rtl_verify_flow_info_1, but it cannot go inside that function - because this condition will not be true until after - reorder_basic_blocks is called. */ - -static void -verify_hot_cold_block_grouping (void) -{ - basic_block bb; - int err = 0; - bool switched_sections = false; - int current_partition = 0; - - FOR_EACH_BB (bb) - { - if (!current_partition) - current_partition = BB_PARTITION (bb); - if (BB_PARTITION (bb) != current_partition) - { - if (switched_sections) - { - error ("multiple hot/cold transitions found (bb %i)", - bb->index); - err = 1; - } - else - { - switched_sections = true; - current_partition = BB_PARTITION (bb); - } - } - } - - gcc_assert(!err); -} - /* Reorder basic blocks. The main entry point to this file. FLAGS is the set of flags to pass to cfg_layout_initialize(). */ @@ -2157,8 +2120,9 @@ reorder_basic_blocks (void) dump_flow_info (dump_file, dump_flags); } - if (flag_reorder_blocks_and_partition) - verify_hot_cold_block_grouping (); + /* Signal that rtl_verify_flow_info_1 can now verify that there + is at most one switch between hot/cold sections. */ + crtl->bb_reorder_complete = true; } /* Determine which partition the first basic block in the function @@ -2503,6 +2467,8 @@ partition_hot_cold_basic_blocks (void) if (!crossing_edges.exists ()) return 0; + crtl->has_bb_partition = true; + /* Make sure the source of any crossing edge ends in a jump and the destination of any crossing edge has a label. */ add_labels_and_missing_jumps (crossing_edges); diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 7764c6c9d2d..1379cf76156 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1864,7 +1864,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2, 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 && reload_completed) + if (crtl->has_bb_partition && reload_completed) return false; /* Search backward through forwarder blocks. We don't need to worry diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 9b12d28d8f5..335e4d972bb 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -2058,6 +2058,44 @@ get_last_bb_insn (basic_block bb) return end; } + +/* Verify, in the basic block chain, that there is at most one switch + between hot/cold partitions. This condition will not be true until + after reorder_basic_blocks is called. */ + +static void +verify_hot_cold_block_grouping (void) +{ + basic_block bb; + int err = 0; + bool switched_sections = false; + int current_partition = BB_UNPARTITIONED; + + if (!crtl->bb_reorder_complete) + return; + + FOR_EACH_BB (bb) + { + if (current_partition != BB_UNPARTITIONED + && BB_PARTITION (bb) != current_partition) + { + if (switched_sections) + { + error ("multiple hot/cold transitions found (bb %i)", + bb->index); + err = 1; + } + else + switched_sections = true; + + if (!crtl->has_bb_partition) + error ("partition found but function partition flag not set"); + } + current_partition = BB_PARTITION (bb); + } + + gcc_assert(!err); +} /* Verify the CFG and RTL consistency common for both underlying RTL and cfglayout RTL. @@ -2072,6 +2110,7 @@ get_last_bb_insn (basic_block bb) and NOTE_INSN_BASIC_BLOCK - verify that no fall_thru edge crosses hot/cold partition boundaries - verify that there are no pending RTL branch predictions + - verify that there is a single hot/cold partition boundary after bbro In future it can be extended check a lot of other stuff as well (reachability of basic blocks, life information, etc. etc.). */ @@ -2323,6 +2362,8 @@ rtl_verify_flow_info_1 (void) } } + verify_hot_cold_block_grouping(); + /* Clean up. */ return err; } diff --git a/gcc/function.h b/gcc/function.h index c0e42d3c39c..c651f5037f8 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -446,6 +446,15 @@ struct GTY(()) rtl_data { sched2) and is useful only if the port defines LEAF_REGISTERS. */ bool uses_only_leaf_regs; + /* Nonzero if the function being compiled has undergone hot/cold partitioning + (under flag_reorder_blocks_and_partition) and has at least one cold + block. */ + bool has_bb_partition; + + /* Nonzero if the function being compiled has completed the bb reordering + pass. */ + bool bb_reorder_complete; + /* Like regs_ever_live, but 1 if a reg is set or clobbered from an asm. Unlike regs_ever_live, elements of this array corresponding to eliminable regs (like the frame pointer) are set if an asm