#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
#include "tm_p.h"
-#include "obstack.h"
#include "alloc-pool.h"
#include "timevar.h"
#include "ggc.h"
/* The obstack on which the flow graph components are allocated. */
-struct obstack flow_obstack;
-static char *flow_firstobj;
+struct bitmap_obstack reg_obstack;
/* Number of basic blocks in the current function. */
void
init_flow (void)
{
- static int initialized;
-
n_edges = 0;
- if (!initialized)
- {
- gcc_obstack_init (&flow_obstack);
- flow_firstobj = obstack_alloc (&flow_obstack, 0);
- initialized = 1;
- }
- else
- {
- obstack_free (&flow_obstack, flow_firstobj);
- flow_firstobj = obstack_alloc (&flow_obstack, 0);
- }
-
ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
e = ggc_alloc_cleared (sizeof (*e));
n_edges++;
- VEC_safe_insert (edge, src->succs, 0, e);
- VEC_safe_insert (edge, dst->preds, 0, e);
+ VEC_safe_push (edge, src->succs, e);
+ VEC_safe_push (edge, dst->preds, e);
e->src = src;
e->dest = dst;
e->flags = flags;
+ e->dest_idx = EDGE_COUNT (dst->preds) - 1;
+
+ execute_on_growing_pred (e);
return e;
}
{
int use_edge_cache;
edge e;
- edge_iterator ei;
/* Don't bother with edge cache for ENTRY or EXIT, if there aren't that
many edges to them, or we didn't allocate memory for it. */
/* Fall through. */
case 0:
- FOR_EACH_EDGE (e, ei, src->succs)
- if (e->dest == dst)
- {
- e->flags |= flags;
- return NULL;
- }
+ e = find_edge (src, dst);
+ if (e)
+ {
+ e->flags |= flags;
+ return NULL;
+ }
break;
}
{
edge tmp;
basic_block src, dest;
+ unsigned int dest_idx;
bool found = false;
edge_iterator ei;
+ execute_on_shrinking_pred (e);
+
src = e->src;
dest = e->dest;
+ dest_idx = e->dest_idx;
for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
{
if (tmp == e)
{
- VEC_ordered_remove (edge, src->succs, ei.index);
+ VEC_unordered_remove (edge, src->succs, ei.index);
found = true;
break;
}
gcc_assert (found);
- found = false;
- for (ei = ei_start (dest->preds); (tmp = ei_safe_edge (ei)); )
- {
- if (tmp == e)
- {
- VEC_ordered_remove (edge, dest->preds, ei.index);
- found = true;
- break;
- }
- else
- ei_next (&ei);
- }
+ VEC_unordered_remove (edge, dest->preds, dest_idx);
- gcc_assert (found);
+ /* If we removed an edge in the middle of the edge vector, we need
+ to update dest_idx of the edge that moved into the "hole". */
+ if (dest_idx < EDGE_COUNT (dest->preds))
+ EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
free_edge (e);
}
void
redirect_edge_succ (edge e, basic_block new_succ)
{
- edge tmp;
- edge_iterator ei;
- bool found = false;
+ basic_block dest = e->dest;
+ unsigned int dest_idx = e->dest_idx;
- /* Disconnect the edge from the old successor block. */
- for (ei = ei_start (e->dest->preds); (tmp = ei_safe_edge (ei)); )
- {
- if (tmp == e)
- {
- VEC_ordered_remove (edge, e->dest->preds, ei.index);
- found = true;
- break;
- }
- else
- ei_next (&ei);
- }
+ execute_on_shrinking_pred (e);
- gcc_assert (found);
+ VEC_unordered_remove (edge, dest->preds, dest_idx);
+
+ /* If we removed an edge in the middle of the edge vector, we need
+ to update dest_idx of the edge that moved into the "hole". */
+ if (dest_idx < EDGE_COUNT (dest->preds))
+ EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
/* Reconnect the edge to the new successor block. */
- VEC_safe_insert (edge, new_succ->preds, 0, e);
+ VEC_safe_push (edge, new_succ->preds, e);
e->dest = new_succ;
+ e->dest_idx = EDGE_COUNT (new_succ->preds) - 1;
+ execute_on_growing_pred (e);
}
/* Like previous but avoid possible duplicate edge. */
redirect_edge_succ_nodup (edge e, basic_block new_succ)
{
edge s;
- edge_iterator ei;
- /* Check whether the edge is already present. */
- FOR_EACH_EDGE (s, ei, e->src->succs)
- if (s->dest == new_succ && s != e)
- break;
-
- if (s)
+ s = find_edge (e->src, new_succ);
+ if (s && s != e)
{
s->flags |= e->flags;
s->probability += e->probability;
{
if (tmp == e)
{
- VEC_ordered_remove (edge, e->src->succs, ei.index);
+ VEC_unordered_remove (edge, e->src->succs, ei.index);
found = true;
break;
}
gcc_assert (found);
/* Reconnect the edge to the new predecessor block. */
- VEC_safe_insert (edge, new_pred->succs, 0, e);
+ VEC_safe_push (edge, new_pred->succs, e);
e->src = new_pred;
}
FOR_EACH_EDGE (e, ei, bb->succs)
dump_edge_info (file, e, 1);
- fprintf (file, "\nRegisters live at start:");
- dump_regset (bb->global_live_at_start, file);
-
- fprintf (file, "\nRegisters live at end:");
- dump_regset (bb->global_live_at_end, file);
-
- putc ('\n', file);
-
if (bb->global_live_at_start)
{
fprintf (file, "\nRegisters live at start:");
for (; (c = ei_safe_edge (ei)); ei_next (&ei))
c->probability = 0;
}
- else
- FOR_EACH_EDGE (c, ei, bb->succs)
- c->probability = ((c->probability * REG_BR_PROB_BASE) / (double) prob);
+ else if (prob != REG_BR_PROB_BASE)
+ {
+ int scale = REG_BR_PROB_BASE / prob;
+
+ FOR_EACH_EDGE (c, ei, bb->succs)
+ c->probability *= scale;
+ }
if (bb != taken_edge->src)
abort ();