basic block. */
static int last_basic_block_before_change;
-/* The following function allocates the loop tree nodes. If LOOPS_P
- is FALSE, the nodes corresponding to the loops (except the root
- which corresponds the all function) will be not allocated but nodes
- will still be allocated for basic blocks. */
+/* Initialize some members in loop tree node NODE. Use LOOP_NUM for
+ the member loop_num. */
static void
-create_loop_tree_nodes (bool loops_p)
+init_loop_tree_node (struct ira_loop_tree_node *node, int loop_num)
+{
+ int max_regno = max_reg_num ();
+
+ node->regno_allocno_map
+ = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno);
+ memset (node->regno_allocno_map, 0, sizeof (ira_allocno_t) * max_regno);
+ memset (node->reg_pressure, 0, sizeof (node->reg_pressure));
+ node->all_allocnos = ira_allocate_bitmap ();
+ node->modified_regnos = ira_allocate_bitmap ();
+ node->border_allocnos = ira_allocate_bitmap ();
+ node->local_copies = ira_allocate_bitmap ();
+ node->loop_num = loop_num;
+ node->children = NULL;
+ node->subloops = NULL;
+}
+
+
+/* The following function allocates the loop tree nodes. If
+ CURRENT_LOOPS is NULL, the nodes corresponding to the loops (except
+ the root which corresponds the all function) will be not allocated
+ but nodes will still be allocated for basic blocks. */
+static void
+create_loop_tree_nodes (void)
{
unsigned int i, j;
- int max_regno;
bool skip_p;
edge_iterator ei;
edge e;
ira_bb_nodes[i].border_allocnos = NULL;
ira_bb_nodes[i].local_copies = NULL;
}
+ if (current_loops == NULL)
+ {
+ ira_loop_nodes = ((struct ira_loop_tree_node *)
+ ira_allocate (sizeof (struct ira_loop_tree_node)));
+ init_loop_tree_node (ira_loop_nodes, 0);
+ return;
+ }
ira_loop_nodes = ((struct ira_loop_tree_node *)
ira_allocate (sizeof (struct ira_loop_tree_node)
* VEC_length (loop_p, ira_loops.larray)));
- max_regno = max_reg_num ();
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
{
if (loop != ira_loops.tree_root)
{
ira_loop_nodes[i].regno_allocno_map = NULL;
- if (! loops_p)
- continue;
skip_p = false;
FOR_EACH_EDGE (e, ei, loop->header->preds)
if (e->src != loop->latch
if (skip_p)
continue;
}
- ira_loop_nodes[i].regno_allocno_map
- = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno);
- memset (ira_loop_nodes[i].regno_allocno_map, 0,
- sizeof (ira_allocno_t) * max_regno);
- memset (ira_loop_nodes[i].reg_pressure, 0,
- sizeof (ira_loop_nodes[i].reg_pressure));
- ira_loop_nodes[i].all_allocnos = ira_allocate_bitmap ();
- ira_loop_nodes[i].modified_regnos = ira_allocate_bitmap ();
- ira_loop_nodes[i].border_allocnos = ira_allocate_bitmap ();
- ira_loop_nodes[i].local_copies = ira_allocate_bitmap ();
+ init_loop_tree_node (&ira_loop_nodes[i], loop->num);
}
}
unsigned int i;
loop_p loop;
- FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
- if (ira_loop_nodes[i].regno_allocno_map != NULL
- && ira_loop_tree_root != &ira_loop_nodes[i])
- return true;
+ if (current_loops != NULL)
+ FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
+ if (ira_loop_nodes[i].regno_allocno_map != NULL
+ && ira_loop_tree_root != &ira_loop_nodes[i])
+ return true;
return false;
}
unsigned int i;
loop_p loop;
- FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
- finish_loop_tree_node (&ira_loop_nodes[i]);
+ if (current_loops == NULL)
+ finish_loop_tree_node (&ira_loop_nodes[0]);
+ else
+ FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
+ finish_loop_tree_node (&ira_loop_nodes[i]);
ira_free (ira_loop_nodes);
for (i = 0; i < (unsigned int) last_basic_block_before_change; i++)
{
\f
/* The following recursive function adds LOOP to the loop tree
- hierarchy. LOOP is added only once. */
+ hierarchy. LOOP is added only once. If LOOP is NULL we adding
+ loop designating the whole function when CFG loops are not
+ built. */
static void
add_loop_to_tree (struct loop *loop)
{
+ int loop_num;
struct loop *parent;
ira_loop_tree_node_t loop_node, parent_node;
/* We can not use loop node access macros here because of potential
checking and because the nodes are not initialized enough
yet. */
- if (loop_outer (loop) != NULL)
+ if (loop != NULL && loop_outer (loop) != NULL)
add_loop_to_tree (loop_outer (loop));
- if (ira_loop_nodes[loop->num].regno_allocno_map != NULL
- && ira_loop_nodes[loop->num].children == NULL)
+ loop_num = loop != NULL ? loop->num : 0;
+ if (ira_loop_nodes[loop_num].regno_allocno_map != NULL
+ && ira_loop_nodes[loop_num].children == NULL)
{
/* We have not added loop node to the tree yet. */
- loop_node = &ira_loop_nodes[loop->num];
+ loop_node = &ira_loop_nodes[loop_num];
loop_node->loop = loop;
loop_node->bb = NULL;
- for (parent = loop_outer (loop);
- parent != NULL;
- parent = loop_outer (parent))
- if (ira_loop_nodes[parent->num].regno_allocno_map != NULL)
- break;
+ if (loop == NULL)
+ parent = NULL;
+ else
+ {
+ for (parent = loop_outer (loop);
+ parent != NULL;
+ parent = loop_outer (parent))
+ if (ira_loop_nodes[parent->num].regno_allocno_map != NULL)
+ break;
+ }
if (parent == NULL)
{
loop_node->next = NULL;
static void
form_loop_tree (void)
{
- unsigned int i;
basic_block bb;
struct loop *parent;
ira_loop_tree_node_t bb_node, loop_node;
- loop_p loop;
/* We can not use loop/bb node access macros because of potential
checking and because the nodes are not initialized enough
yet. */
- FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
- if (ira_loop_nodes[i].regno_allocno_map != NULL)
- {
- ira_loop_nodes[i].children = NULL;
- ira_loop_nodes[i].subloops = NULL;
- }
FOR_EACH_BB (bb)
{
bb_node = &ira_bb_nodes[bb->index];
bb_node->children = NULL;
bb_node->subloop_next = NULL;
bb_node->next = NULL;
- for (parent = bb->loop_father;
- parent != NULL;
- parent = loop_outer (parent))
- if (ira_loop_nodes[parent->num].regno_allocno_map != NULL)
- break;
+ if (current_loops == NULL)
+ parent = NULL;
+ else
+ {
+ for (parent = bb->loop_father;
+ parent != NULL;
+ parent = loop_outer (parent))
+ if (ira_loop_nodes[parent->num].regno_allocno_map != NULL)
+ break;
+ }
add_loop_to_tree (parent);
- loop_node = &ira_loop_nodes[parent->num];
+ loop_node = &ira_loop_nodes[parent == NULL ? 0 : parent->num];
bb_node->next = loop_node->children;
bb_node->parent = loop_node;
loop_node->children = bb_node;
}
- ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (ira_loops.tree_root->num);
+ ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (0);
ira_loop_tree_height = setup_loop_tree_level (ira_loop_tree_root, 0);
ira_assert (ira_loop_tree_root->regno_allocno_map != NULL);
}
loop_p loop;
ira_allocno_iterator ai;
+ ira_assert (current_loops != NULL);
max_regno = max_reg_num ();
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop)
if (ira_loop_nodes[l].regno_allocno_map != NULL)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (ira_dump_file, ",b%d", bb->index);
else
- fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
+ fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
if (ALLOCNO_CAP_MEMBER (a) != NULL)
{
fprintf (ira_dump_file, ":");
edge e;
VEC (edge, heap) *edges;
+ ira_assert (current_loops != NULL);
FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
if (e->src != loop_node->loop->latch)
create_loop_allocnos (e);
if ((diff = (int) loop_depth (l1->loop) - (int) loop_depth (l2->loop)) != 0)
return diff;
/* Make sorting stable. */
- return l1->loop->num - l2->loop->num;
+ return l1->loop_num - l2->loop_num;
}
/* Mark loops which should be removed from regional allocation. We
ira_loop_tree_node_t *sorted_loops;
loop_p loop;
+ ira_assert (current_loops != NULL);
sorted_loops
= (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t)
* VEC_length (loop_p,
fprintf
(ira_dump_file,
" Mark loop %d (header %d, freq %d, depth %d) for removal (%s)\n",
- sorted_loops[i]->loop->num, sorted_loops[i]->loop->header->index,
+ sorted_loops[i]->loop_num, sorted_loops[i]->loop->header->index,
sorted_loops[i]->loop->header->frequency,
loop_depth (sorted_loops[i]->loop),
low_pressure_loop_node_p (sorted_loops[i]->parent)
int i;
loop_p loop;
+ ira_assert (current_loops != NULL);
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL)
{
fprintf
(ira_dump_file,
" Mark loop %d (header %d, freq %d, depth %d) for removal\n",
- ira_loop_nodes[i].loop->num,
+ ira_loop_nodes[i].loop_num,
ira_loop_nodes[i].loop->header->index,
ira_loop_nodes[i].loop->header->frequency,
loop_depth (ira_loop_nodes[i].loop));
static void
remove_unnecessary_regions (bool all_p)
{
+ if (current_loops == NULL)
+ return;
if (all_p)
mark_all_loops_for_removal ();
else
}
/* Create a internal representation (IR) for IRA (allocnos, copies,
- loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to
- the loops (except the root which corresponds the all function) and
- correspondingly allocnos for the loops will be not created. Such
- parameter value is used for Chaitin-Briggs coloring. The function
- returns TRUE if we generate loop structure (besides nodes
- representing all function and the basic blocks) for regional
- allocation. A true return means that we really need to flatten IR
- before the reload. */
+ loop tree nodes). The function returns TRUE if we generate loop
+ structure (besides nodes representing all function and the basic
+ blocks) for regional allocation. A true return means that we
+ really need to flatten IR before the reload. */
bool
-ira_build (bool loops_p)
+ira_build (void)
{
- df_analyze ();
+ bool loops_p;
+ df_analyze ();
initiate_cost_vectors ();
initiate_allocnos ();
initiate_copies ();
- create_loop_tree_nodes (loops_p);
+ create_loop_tree_nodes ();
form_loop_tree ();
create_allocnos ();
ira_costs ();
}
}
fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n",
- VEC_length (loop_p, ira_loops.larray), n_basic_blocks,
- ira_max_point);
+ current_loops == NULL ? 1 : VEC_length (loop_p, ira_loops.larray),
+ n_basic_blocks, ira_max_point);
fprintf (ira_dump_file,
" allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n",
ira_allocnos_num, nr_big, ira_copies_num, n, nr);
update_conflict_hard_regno_costs (full_costs, aclass, false);
}
min_cost = min_full_cost = INT_MAX;
-
/* We don't care about giving callee saved registers to allocnos no
living through calls because call clobbered registers are
allocated first (it is usual practice to put them first in
edge e;
VEC (edge, heap) *edges;
- ira_assert (loop_node->loop != NULL
+ ira_assert (current_loops != NULL && loop_node->loop != NULL
&& (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
freq = 0;
if (! exit_p)
edge e;
edge_iterator ei;
- ira_assert (loop_tree_node->loop != NULL);
- fprintf (ira_dump_file,
- "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
- loop_tree_node->loop->num,
- (loop_tree_node->parent == NULL
- ? -1 : loop_tree_node->parent->loop->num),
- loop_tree_node->loop->header->index,
- loop_depth (loop_tree_node->loop));
+ if (loop_tree_node->parent == NULL)
+ fprintf (ira_dump_file,
+ "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
+ NUM_FIXED_BLOCKS);
+ else
+ {
+ ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
+ fprintf (ira_dump_file,
+ "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
+ loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
+ loop_tree_node->loop->header->index,
+ loop_depth (loop_tree_node->loop));
+ }
for (subloop_node = loop_tree_node->children;
subloop_node != NULL;
subloop_node = subloop_node->next)
&& ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
!= loop_tree_node))
fprintf (ira_dump_file, "(->%d:l%d)",
- e->dest->index, dest_loop_node->loop->num);
+ e->dest->index, dest_loop_node->loop_num);
}
fprintf (ira_dump_file, "\n all:");
EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
fprintf
(ira_dump_file,
" Moving spill/restore for a%dr%d up from loop %d",
- ALLOCNO_NUM (a), regno, loop_node->loop->num);
+ ALLOCNO_NUM (a), regno, loop_node->loop_num);
fprintf (ira_dump_file, " - profit %d\n", -cost);
}
changed_p = true;