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);
&& 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;
|| 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))
{
}
}
- /* 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
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;
}
--- /dev/null
+-- { 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;
--- /dev/null
+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;