Mercurial > hg > CbC > CbC_gcc
diff gcc/cfgcleanup.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/cfgcleanup.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/cfgcleanup.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Control flow optimization code for GNU compiler. - Copyright (C) 1987-2017 Free Software Foundation, Inc. + Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -394,19 +394,6 @@ edge_iterator ei; edge e, *threaded_edges = NULL; - /* If we are partitioning hot/cold basic blocks, we don't want to - mess up unconditional or indirect jumps that cross between hot - and cold sections. - - Basic block partitioning may result in some jumps that appear to - be optimizable (or blocks that appear to be mergeable), but which really - must be left untouched (they are required to make it safely across - partition boundaries). See the comments at the top of - bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */ - - if (JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))) - return false; - for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); ) { basic_block target, first; @@ -415,6 +402,7 @@ bool threaded = false; int nthreaded_edges = 0; bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0; + bool new_target_threaded = false; /* Skip complex edges because we don't know how to update them. @@ -431,29 +419,12 @@ counter = NUM_FIXED_BLOCKS; goto_locus = e->goto_locus; - /* If we are partitioning hot/cold basic_blocks, we don't want to mess - up jumps that cross between hot/cold sections. - - Basic block partitioning may result in some jumps that appear - to be optimizable (or blocks that appear to be mergeable), but which - really must be left untouched (they are required to make it safely - across partition boundaries). See the comments at the top of - bb-reorder.c:partition_hot_cold_basic_blocks for complete - details. */ - - if (first != EXIT_BLOCK_PTR_FOR_FN (cfun) - && JUMP_P (BB_END (first)) - && CROSSING_JUMP_P (BB_END (first))) - return changed; - while (counter < n_basic_blocks_for_fn (cfun)) { basic_block new_target = NULL; - bool new_target_threaded = false; may_thread |= (target->flags & BB_MODIFIED) != 0; if (FORWARDER_BLOCK_P (target) - && !(single_succ_edge (target)->flags & EDGE_CROSSING) && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun)) { /* Bypass trivial infinite loops. */ @@ -543,8 +514,14 @@ break; counter++; - target = new_target; - threaded |= new_target_threaded; + /* Do not turn non-crossing jump to crossing. Depending on target + it may require different instruction pattern. */ + if ((e->flags & EDGE_CROSSING) + || BB_PARTITION (first) == BB_PARTITION (new_target)) + { + target = new_target; + threaded |= new_target_threaded; + } } if (counter >= n_basic_blocks_for_fn (cfun)) @@ -559,8 +536,6 @@ { /* Save the values now, as the edge may get removed. */ profile_count edge_count = e->count (); - profile_probability edge_probability = e->probability; - int edge_frequency; int n = 0; e->goto_locus = goto_locus; @@ -585,8 +560,6 @@ /* We successfully forwarded the edge. Now update profile data: for each edge we traversed in the chain, remove the original edge's execution count. */ - edge_frequency = edge_probability.apply (b->frequency); - do { edge t; @@ -596,16 +569,12 @@ gcc_assert (n < nthreaded_edges); t = threaded_edges [n++]; gcc_assert (t->src == first); - update_bb_profile_for_threading (first, edge_frequency, - edge_count, t); + update_bb_profile_for_threading (first, edge_count, t); update_br_prob_note (first); } else { first->count -= edge_count; - first->frequency -= edge_frequency; - if (first->frequency < 0) - first->frequency = 0; /* It is possible that as the result of threading we've removed edge as it is threaded to the fallthru edge. Avoid @@ -872,8 +841,6 @@ MEM_ATTRS (x) = 0; else { - HOST_WIDE_INT mem_size; - if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) { set_mem_alias_set (x, 0); @@ -889,20 +856,23 @@ } else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y) || (MEM_OFFSET_KNOWN_P (x) - && MEM_OFFSET (x) != MEM_OFFSET (y))) + && maybe_ne (MEM_OFFSET (x), MEM_OFFSET (y)))) { clear_mem_offset (x); clear_mem_offset (y); } - if (MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y)) - { - mem_size = MAX (MEM_SIZE (x), MEM_SIZE (y)); - set_mem_size (x, mem_size); - set_mem_size (y, mem_size); - } + if (!MEM_SIZE_KNOWN_P (x)) + clear_mem_size (y); + else if (!MEM_SIZE_KNOWN_P (y)) + clear_mem_size (x); + else if (known_le (MEM_SIZE (x), MEM_SIZE (y))) + set_mem_size (x, MEM_SIZE (y)); + else if (known_le (MEM_SIZE (y), MEM_SIZE (x))) + set_mem_size (y, MEM_SIZE (x)); else { + /* The sizes aren't ordered, so we can't merge them. */ clear_mem_size (x); clear_mem_size (y); } @@ -1180,7 +1150,7 @@ /* ??? Worse, this adjustment had better be constant lest we have differing incoming stack levels. */ if (!frame_pointer_needed - && find_args_size_adjust (i1) == HOST_WIDE_INT_MIN) + && known_eq (find_args_size_adjust (i1), HOST_WIDE_INT_MIN)) return dir_none; } else if (p1 || p2) @@ -2109,7 +2079,7 @@ else redirect_edges_to = osrc2; - /* Recompute the frequencies and counts of outgoing edges. */ + /* Recompute the counts of destinations of outgoing edges. */ FOR_EACH_EDGE (s, ei, redirect_edges_to->succs) { edge s2; @@ -2132,24 +2102,17 @@ that there is no more than one in the chain, so we can't run into infinite loop. */ if (FORWARDER_BLOCK_P (s->dest)) - { - s->dest->frequency += EDGE_FREQUENCY (s); - } + s->dest->count += s->count (); if (FORWARDER_BLOCK_P (s2->dest)) - { - s2->dest->frequency -= EDGE_FREQUENCY (s); - if (s2->dest->frequency < 0) - s2->dest->frequency = 0; - } - - if (!redirect_edges_to->frequency && !src1->frequency) - s->probability = s->probability.combine_with_freq - (redirect_edges_to->frequency, - s2->probability, src1->frequency); + s2->dest->count -= s->count (); + + s->probability = s->probability.combine_with_count + (redirect_edges_to->count, + s2->probability, src1->count); } - /* Adjust count and frequency for the block. An earlier jump + /* Adjust count for the block. An earlier jump threading pass may have left the profile in an inconsistent state (see update_bb_profile_for_threading) so we must be prepared for overflows. */ @@ -2157,9 +2120,6 @@ do { tmp->count += src1->count; - tmp->frequency += src1->frequency; - if (tmp->frequency > BB_FREQ_MAX) - tmp->frequency = BB_FREQ_MAX; if (tmp == redirect_edges_to) break; tmp = find_fallthru_edge (tmp->succs)->dest; @@ -2465,9 +2425,7 @@ max_match--; if (max_match == 0) return false; - do - e0_last_head = prev_real_insn (e0_last_head); - while (DEBUG_INSN_P (e0_last_head)); + e0_last_head = prev_real_nondebug_insn (e0_last_head); } if (max_match == 0) @@ -3027,8 +2985,11 @@ to detect and fix during edge forwarding, and in some cases is only visible after newly unreachable blocks are deleted, which will be done in fixup_partitions. */ - fixup_partitions (); - checking_verify_flow_info (); + if ((mode & CLEANUP_NO_PARTITIONING) == 0) + { + fixup_partitions (); + checking_verify_flow_info (); + } } changed_overall |= changed; @@ -3053,13 +3014,13 @@ find_unreachable_blocks (); - /* When we're in GIMPLE mode and there may be debug insns, we should - delete blocks in reverse dominator order, so as to get a chance - to substitute all released DEFs into debug stmts. If we don't - have dominators information, walking blocks backward gets us a - better chance of retaining most debug information than + /* When we're in GIMPLE mode and there may be debug bind insns, we + should delete blocks in reverse dominator order, so as to get a + chance to substitute all released DEFs into debug bind stmts. If + we don't have dominators information, walking blocks backward + gets us a better chance of retaining most debug information than otherwise. */ - if (MAY_HAVE_DEBUG_INSNS && current_ir_type () == IR_GIMPLE + if (MAY_HAVE_DEBUG_BIND_INSNS && current_ir_type () == IR_GIMPLE && dom_info_available_p (CDI_DOMINATORS)) { for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;