aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/bb-reorder.c43
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/opt68.adb53
-rw-r--r--gcc/testsuite/gnat.dg/opt68.ads26
5 files changed, 114 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b403f06..b1b14be8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-10-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * bb-reorder.c (find_traces_1_round): Fix off-by-one index.
+ Move comment around. Do not reset best_edge for a copiable
+ destination if the copy would cause a partition change.
+ (better_edge_p): Remove redundant check.
+
2017-10-27 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386-protos.h (ix86_fp_compare_mode): Remove prototype.
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index dc2025f..cd95952 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -529,7 +529,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
if (dump_file)
fprintf (dump_file, "Basic block %d was visited in trace %d\n",
- bb->index, *n_traces - 1);
+ bb->index, *n_traces);
ends_in_call = block_ends_with_call_p (bb);
@@ -545,6 +545,8 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
&& bb_visited_trace (e->dest) != *n_traces)
continue;
+ /* If partitioning hot/cold basic blocks, don't consider edges
+ that cross section boundaries. */
if (BB_PARTITION (e->dest) != BB_PARTITION (bb))
continue;
@@ -574,9 +576,6 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
|| e->count () < count_th) && (!for_size)))
continue;
- /* If partitioning hot/cold basic blocks, don't consider edges
- that cross section boundaries. */
-
if (better_edge_p (bb, e, prob, freq, best_prob, best_freq,
best_edge))
{
@@ -586,12 +585,28 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
}
}
- /* If the best destination has multiple predecessors, and can be
- duplicated cheaper than a jump, don't allow it to be added
- to a trace. We'll duplicate it when connecting traces. */
- if (best_edge && EDGE_COUNT (best_edge->dest->preds) >= 2
+ /* If the best destination has multiple predecessors and can be
+ duplicated cheaper than a jump, don't allow it to be added to
+ a trace; we'll duplicate it when connecting the traces later.
+ However, we need to check that this duplication wouldn't leave
+ the best destination with only crossing predecessors, because
+ this would change its effective partition from hot to cold. */
+ if (best_edge
+ && EDGE_COUNT (best_edge->dest->preds) >= 2
&& copy_bb_p (best_edge->dest, 0))
- best_edge = NULL;
+ {
+ bool only_crossing_preds = true;
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, best_edge->dest->preds)
+ if (e != best_edge && !(e->flags & EDGE_CROSSING))
+ {
+ only_crossing_preds = false;
+ break;
+ }
+ if (!only_crossing_preds)
+ best_edge = NULL;
+ }
/* If the best destination has multiple successors or predecessors,
don't allow it to be added when optimizing for size. This makes
@@ -988,16 +1003,6 @@ better_edge_p (const_basic_block bb, const_edge e, profile_probability prob,
else
is_better_edge = false;
- /* If we are doing hot/cold partitioning, make sure that we always favor
- non-crossing edges over crossing edges. */
-
- if (!is_better_edge
- && flag_reorder_blocks_and_partition
- && cur_best_edge
- && (cur_best_edge->flags & EDGE_CROSSING)
- && !(e->flags & EDGE_CROSSING))
- is_better_edge = true;
-
return is_better_edge;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9383607..58da3bb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-10-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt68.ad[sb]: New test.
+
2017-10-27 Daniel Santos <daniel.santos@pobox.com>
* gcc.target/i386/pr82196-1.c (dg-options): Add -mno-avx.
diff --git a/gcc/testsuite/gnat.dg/opt68.adb b/gcc/testsuite/gnat.dg/opt68.adb
new file mode 100644
index 0000000..caf6b71
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt68.adb
@@ -0,0 +1,53 @@
+-- { dg-do compile }
+-- { dg-options "-O3" }
+
+with Ada.Unchecked_Deallocation;
+
+package body Opt68 is
+
+ procedure Free
+ is new Ada.Unchecked_Deallocation (Queue_Element, A_Queue_Element);
+
+ procedure Copy (dest : in out Queue; src : Queue) is
+ d, s, pd, ps, t : A_Queue_Element;
+ begin
+ if src.sz /= 0 then
+ d := dest.front;
+ s := src.front;
+ while d /= null and s /= null loop
+ d.value := s.value;
+ pd := d;
+ ps := s;
+ d := d.next;
+ s := s.next;
+ end loop;
+ if src.sz = dest.sz then
+ return;
+ elsif s = null then
+ while d /= null loop
+ t := d.next;
+ Free (d);
+ d := t;
+ end loop;
+ dest.back := pd;
+ dest.back.next := null;
+ else
+ if pd = null then
+ dest.front := new Queue_Element;
+ dest.front.value := s.value;
+ s := s.next;
+ pd := dest.front;
+ end if;
+ while s /= null loop
+ pd.next := new Queue_Element;
+ pd.next.value := s.value;
+ pd := pd.next;
+ s := s.next;
+ end loop;
+ dest.back := pd;
+ end if;
+ dest.sz := src.sz;
+ end if;
+ end;
+
+end Opt68;
diff --git a/gcc/testsuite/gnat.dg/opt68.ads b/gcc/testsuite/gnat.dg/opt68.ads
new file mode 100644
index 0000000..25e28a5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt68.ads
@@ -0,0 +1,26 @@
+with Ada.Finalization;
+
+package Opt68 is
+
+ type Cont is new Ada.Finalization.Controlled with null record;
+
+ type Element is record
+ C : Cont;
+ end record;
+
+ type Queue_Element;
+ type A_Queue_Element is access Queue_Element;
+ type Queue_Element is record
+ Value : Element;
+ Next : A_Queue_Element;
+ end record;
+
+ type Queue is limited record
+ Sz : Natural;
+ Front : A_Queue_Element;
+ Back : A_Queue_Element;
+ end record;
+
+ procedure Copy (dest : in out Queue; src : Queue);
+
+end Opt68;