Commit 00c6cd4e authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup irphase: phase_reinit is a special case and doesn't polute the main...

cleanup irphase: phase_reinit is a special case and doesn't polute the main callback interface anymore

[r27709]
parent c3689ef7
......@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "list.h"
#include "irdump.h"
......@@ -39,9 +40,9 @@
#include "iredges_t.h"
struct _heights_t {
ir_phase ph;
unsigned visited;
void *dump_handle;
ir_phase phase;
unsigned visited;
void *dump_handle;
};
typedef struct {
......@@ -49,18 +50,28 @@ typedef struct {
unsigned visited;
} irn_height_t;
static void *irn_height_init(ir_phase *ph, const ir_node *irn, void *data)
static void *irn_height_init(ir_phase *phase, const ir_node *node)
{
irn_height_t *h = data ? data : phase_alloc(ph, sizeof(h[0]));
(void)irn;
memset(h, 0, sizeof(h[0]));
irn_height_t *h = phase_alloc(phase, sizeof(*h));
(void) node;
memset(h, 0, sizeof(*h));
return h;
}
static void *irn_height_reinit(ir_phase *phase, const ir_node *node,
void *old_data)
{
irn_height_t *h = (irn_height_t*) old_data;
(void) node;
(void) phase;
memset(h, 0, sizeof(*h));
return h;
}
static void height_dump_cb(void *data, FILE *f, const ir_node *irn)
{
heights_t *heights = data;
irn_height_t *h = phase_get_irn_data(&heights->ph, irn);
irn_height_t *h = phase_get_irn_data(&heights->phase, irn);
if (h)
fprintf(f, "height: %u\n", h->height);
......@@ -73,7 +84,7 @@ static void height_dump_cb(void *data, FILE *f, const ir_node *irn)
* @param tgt The node we try to reach.
* @return 1, one of tgt can be reached from curr, 0 else.
*/
static int search(heights_t *h, const ir_node *curr, const ir_node *tgt)
static bool search(heights_t *h, const ir_node *curr, const ir_node *tgt)
{
irn_height_t *h_curr;
irn_height_t *h_tgt;
......@@ -81,23 +92,23 @@ static int search(heights_t *h, const ir_node *curr, const ir_node *tgt)
/* if the current node is the one we were looking for, we're done. */
if (curr == tgt)
return 1;
return true;
/* If we are in another block or at a phi we won't find our target. */
if (get_nodes_block(curr) != get_nodes_block(tgt))
return 0;
return false;
if (is_Phi(curr))
return 0;
return false;
/* Check, if we have already been here. Coming more often won't help :-) */
h_curr = phase_get_irn_data(&h->ph, curr);
h_curr = phase_get_irn_data(&h->phase, curr);
if (h_curr->visited >= h->visited)
return 0;
return false;
/* If we are too deep into the DAG we won't find the target either. */
h_tgt = phase_get_irn_data(&h->ph, tgt);
h_tgt = phase_get_irn_data(&h->phase, tgt);
if (h_curr->height > h_tgt->height)
return 0;
return false;
/* Mark this place as visited. */
h_curr->visited = h->visited;
......@@ -106,10 +117,10 @@ static int search(heights_t *h, const ir_node *curr, const ir_node *tgt)
for (i = 0, n = get_irn_ins_or_deps(curr); i < n; ++i) {
ir_node *op = get_irn_in_or_dep(curr, i);
if (search(h, op, tgt))
return 1;
return true;
}
return 0;
return false;
}
/**
......@@ -118,8 +129,8 @@ static int search(heights_t *h, const ir_node *curr, const ir_node *tgt)
int heights_reachable_in_block(heights_t *h, const ir_node *n, const ir_node *m)
{
int res = 0;
irn_height_t *hn = phase_get_irn_data(&h->ph, n);
irn_height_t *hm = phase_get_irn_data(&h->ph, m);
irn_height_t *hn = phase_get_irn_data(&h->phase, n);
irn_height_t *hm = phase_get_irn_data(&h->phase, m);
assert(get_nodes_block(n) == get_nodes_block(m));
assert(hn != NULL && hm != NULL);
......@@ -140,7 +151,7 @@ int heights_reachable_in_block(heights_t *h, const ir_node *n, const ir_node *m)
*/
static unsigned compute_height(heights_t *h, ir_node *irn, const ir_node *bl)
{
irn_height_t *ih = phase_get_or_set_irn_data(&h->ph, irn);
irn_height_t *ih = phase_get_or_set_irn_data(&h->phase, irn);
const ir_edge_t *edge;
......@@ -209,7 +220,7 @@ static void compute_heights_in_block_walker(ir_node *block, void *data)
unsigned get_irn_height(heights_t *heights, const ir_node *irn)
{
irn_height_t *h = phase_get_irn_data(&heights->ph, irn);
irn_height_t *h = phase_get_irn_data(&heights->phase, irn);
assert(h && "No height information for node");
return h->height;
}
......@@ -218,14 +229,13 @@ unsigned heights_recompute_block(heights_t *h, ir_node *block)
{
const ir_edge_t *edge;
edges_assure(phase_get_irg(&h->ph));
edges_assure(phase_get_irg(&h->phase));
/* reset phase data for all nodes in the block */
foreach_out_edge(block, edge) {
ir_node *irn = get_edge_src_irn(edge);
irn_height_t *ih = phase_get_irn_data(&h->ph, irn);
irn_height_init(&h->ph, irn, ih);
irn_height_t *ih = phase_get_irn_data(&h->phase, irn);
memset(ih, 0, sizeof(*ih));
}
h->visited = 0;
......@@ -234,16 +244,18 @@ unsigned heights_recompute_block(heights_t *h, ir_node *block)
void heights_recompute(heights_t *h)
{
edges_assure(phase_get_irg(&h->ph));
phase_reinit_irn_data(&h->ph);
ir_graph *irg = phase_get_irg(&h->phase);
edges_assure(irg);
phase_reinit_irn_data(&h->phase, irn_height_reinit);
h->visited = 0;
irg_block_walk_graph(phase_get_irg(&h->ph), compute_heights_in_block_walker, NULL, h);
irg_block_walk_graph(irg, compute_heights_in_block_walker, NULL, h);
}
heights_t *heights_new(ir_graph *irg)
{
heights_t *res = XMALLOC(heights_t);
phase_init(&res->ph, irg, irn_height_init);
phase_init(&res->phase, irg, irn_height_init);
res->dump_handle = dump_add_node_info_callback(height_dump_cb, res);
heights_recompute(res);
......@@ -252,7 +264,7 @@ heights_t *heights_new(ir_graph *irg)
void heights_free(heights_t *h)
{
phase_deinit(&h->ph);
phase_deinit(&h->phase);
dump_remove_node_info_callback(h->dump_handle);
xfree(h);
}
......@@ -85,7 +85,7 @@ struct _lv_chk_t {
DEBUG_ONLY(firm_dbg_module_t *dbg;)
};
static void *init_block_data(ir_phase *ph, const ir_node *irn, void *old)
static void *init_block_data(ir_phase *ph, const ir_node *irn)
{
lv_chk_t *lv = firm_container_of(ph, lv_chk_t, ph);
bl_info_t *bi = phase_alloc(ph, sizeof(bi[0]));
......@@ -95,7 +95,6 @@ static void *init_block_data(ir_phase *ph, const ir_node *irn, void *old)
bi->red_reachable = bitset_obstack_alloc(phase_obst(ph), lv->n_blocks);
bi->be_tgt_reach = bitset_obstack_alloc(phase_obst(ph), lv->n_blocks);
bi->be_tgt_calc = 0;
(void) old;
return bi;
}
......
......@@ -498,14 +498,13 @@ static void vrp_first_pass(ir_node *n, void *e)
}
}
static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old)
static void *vrp_init_node(ir_phase *phase, const ir_node *n)
{
ir_mode *mode;
vrp_attr *vrp;
struct vrp_env_t *env = phase->priv;
DBG((env->dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n)));
assert(old==NULL && "init called for node already initialized");
vrp = phase_alloc(phase, sizeof(vrp_attr));
memset(vrp, 0, sizeof(vrp_attr));
......
......@@ -180,12 +180,12 @@ typedef struct {
#define get_co2_irn(co2, irn) ((co2_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
#define get_co2_cloud_irn(co2, irn) ((co2_cloud_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
static void *co2_irn_init(ir_phase *ph, const ir_node *irn, void *data)
static void *co2_irn_init(ir_phase *ph, const ir_node *irn)
{
co2_t *env = (co2_t *) ph;
affinity_node_t *a = get_affinity_info(env->co, irn);
size_t size = a ? sizeof(co2_cloud_irn_t) : sizeof(co2_irn_t);
co2_irn_t *ci = data ? data : phase_alloc(ph, size);
co2_irn_t *ci = phase_alloc(ph, size);
memset(ci, 0, size);
INIT_LIST_HEAD(&ci->changed_list);
......
......@@ -368,59 +368,57 @@ static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
/**
* In case there is no phase information for irn, initialize it.
*/
static void *co_mst_irn_init(ir_phase *ph, const ir_node *irn, void *old)
static void *co_mst_irn_init(ir_phase *ph, const ir_node *irn)
{
co_mst_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0]));
co_mst_irn_t *res = phase_alloc(ph, sizeof(res[0]));
co_mst_env_t *env = ph->priv;
if (!old) {
const arch_register_req_t *req;
neighbours_iter_t nodes_it;
ir_node *neigh;
unsigned len;
res->irn = irn;
res->chunk = NULL;
res->fixed = 0;
res->tmp_col = -1;
res->int_neighs = NULL;
res->int_aff_neigh = 0;
res->col = arch_register_get_index(arch_get_irn_register(irn));
res->init_col = res->col;
INIT_LIST_HEAD(&res->list);
DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
/* set admissible registers */
res->adm_colors = bitset_obstack_alloc(phase_obst(ph), env->n_regs);
/* Exclude colors not assignable to the irn */
req = arch_get_register_req_out(irn);
if (arch_register_req_is(req, limited))
rbitset_copy_to_bitset(req->limited, res->adm_colors);
else
bitset_set_all(res->adm_colors);
/* exclude global ignore registers as well */
bitset_andnot(res->adm_colors, env->ignore_regs);
/* compute the constraint factor */
res->constr_factor = (real_t) (1 + env->n_regs - bitset_popcount(res->adm_colors)) / env->n_regs;
/* set the number of interfering affinity neighbours to -1, they are calculated later */
res->int_aff_neigh = -1;
/* build list of interfering neighbours */
len = 0;
be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
if (!arch_irn_is_ignore(neigh)) {
obstack_ptr_grow(phase_obst(ph), neigh);
++len;
}
const arch_register_req_t *req;
neighbours_iter_t nodes_it;
ir_node *neigh;
unsigned len;
res->irn = irn;
res->chunk = NULL;
res->fixed = 0;
res->tmp_col = -1;
res->int_neighs = NULL;
res->int_aff_neigh = 0;
res->col = arch_register_get_index(arch_get_irn_register(irn));
res->init_col = res->col;
INIT_LIST_HEAD(&res->list);
DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
/* set admissible registers */
res->adm_colors = bitset_obstack_alloc(phase_obst(ph), env->n_regs);
/* Exclude colors not assignable to the irn */
req = arch_get_register_req_out(irn);
if (arch_register_req_is(req, limited))
rbitset_copy_to_bitset(req->limited, res->adm_colors);
else
bitset_set_all(res->adm_colors);
/* exclude global ignore registers as well */
bitset_andnot(res->adm_colors, env->ignore_regs);
/* compute the constraint factor */
res->constr_factor = (real_t) (1 + env->n_regs - bitset_popcount(res->adm_colors)) / env->n_regs;
/* set the number of interfering affinity neighbours to -1, they are calculated later */
res->int_aff_neigh = -1;
/* build list of interfering neighbours */
len = 0;
be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
if (!arch_irn_is_ignore(neigh)) {
obstack_ptr_grow(phase_obst(ph), neigh);
++len;
}
res->int_neighs = obstack_finish(phase_obst(ph));
res->n_neighs = len;
}
res->int_neighs = obstack_finish(phase_obst(ph));
res->n_neighs = len;
return res;
}
......
......@@ -275,37 +275,37 @@ static int cmp_ilpsched_irn(const void *a, const void *b)
return QSORT_CMP(n1_a->sched_point, n2_a->sched_point);
}
/**
* In case there is no phase information for irn, initialize it.
*/
static void *init_ilpsched_irn(ir_phase *ph, const ir_node *irn, void *old)
static void *reinit_ilpsched_irn(ir_phase *ph, const ir_node *irn, void *old)
{
be_ilpsched_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0]));
be_ilpsched_irn_t *res = old;
if (res == old) {
/* if we have already some data: check for reinitialization */
if (! is_Block(irn)) {
ilpsched_node_attr_t *na = get_ilpsched_node_attr(res);
/* if we have already some data: check for reinitialization */
if (! is_Block(irn)) {
ilpsched_node_attr_t *na = get_ilpsched_node_attr(res);
if (! na->transitive_block_nodes) {
ir_node *block = get_nodes_block(irn);
be_ilpsched_irn_t *block_node = phase_get_or_set_irn_data(ph, block);
ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
if (! na->transitive_block_nodes) {
ir_node *block = get_nodes_block(irn);
be_ilpsched_irn_t *block_node = phase_get_or_set_irn_data(ph, block);
ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
/* we are called after the block indices have been build: create bitset */
na->transitive_block_nodes = bitset_obstack_alloc(phase_obst(ph), ba->block_last_idx);
}
else {
/* we are called from reinit block data: clear the bitset */
bitset_clear_all(na->transitive_block_nodes);
na->visit_idx = 0;
na->alap_changed = 1;
}
/* we are called after the block indices have been build: create bitset */
na->transitive_block_nodes = bitset_obstack_alloc(phase_obst(ph), ba->block_last_idx);
} else {
/* we are called from reinit block data: clear the bitset */
bitset_clear_all(na->transitive_block_nodes);
na->visit_idx = 0;
na->alap_changed = 1;
}
return old;
}
return res;
}
/**
* In case there is no phase information for irn, initialize it.
*/
static void *init_ilpsched_irn(ir_phase *phase, const ir_node *irn)
{
be_ilpsched_irn_t *res = phase_alloc(phase, sizeof(res[0]));
res->irn = irn;
/* set ilpsched irn attributes (either block or irn) */
......@@ -318,8 +318,7 @@ static void *init_ilpsched_irn(ir_phase *ph, const ir_node *irn, void *old)
ba->head_ilp_nodes = NULL;
ba->livein_nodes = new_pset(cmp_live_in_nodes, 16);
ba->max_steps = 0;
}
else {
} else {
ilpsched_node_attr_t *na = get_ilpsched_node_attr(res);
memset(na, 0, sizeof(*na));
}
......@@ -2025,7 +2024,7 @@ void be_ilp_sched(ir_graph *irg)
now we can allocate the bitsets (size depends on block indices)
for all nodes.
*/
phase_reinit_irn_data(&env.ph);
phase_reinit_irn_data(&env.ph, reinit_ilpsched_irn);
/* Collect all root nodes (having no user in their block) and calculate ASAP. */
irg_walk_in_or_dep_blkwise_graph(env.irg, collect_alap_root_nodes, calculate_irn_asap, &env);
......
......@@ -481,11 +481,10 @@ static void lv_dump_block(void *context, FILE *f, const ir_node *bl)
}
}
static void *lv_phase_data_init(ir_phase *phase, const ir_node *irn, void *old)
static void *lv_phase_data_init(ir_phase *phase, const ir_node *irn)
{
struct _be_lv_info_t *info = phase_alloc(phase, LV_STD_SIZE * sizeof(info[0]));
(void) irn;
(void) old;
memset(info, 0, LV_STD_SIZE * sizeof(info[0]));
info[0].u.head.n_size = LV_STD_SIZE - 1;
......
......@@ -77,9 +77,9 @@ typedef struct _mris_irn_t {
#define get_mris_irn(env, irn) ((mris_irn_t *) phase_get_or_set_irn_data(&env->ph, irn))
#define foreach_lineage(env, pos, tmp) list_for_each_entry_safe(mris_irn_t, pos, tmp, &(env)->lineage_head, lineage_list)
static void *mris_irn_data_init(ir_phase *ph, const ir_node *irn, void *data)
static void *mris_irn_data_init(ir_phase *ph, const ir_node *irn)
{
mris_irn_t *mi = data ? data : phase_alloc(ph, sizeof(mi[0]));
mris_irn_t *mi = phase_alloc(ph, sizeof(mi[0]));
(void) irn;
memset(mi, 0, sizeof(mi[0]));
INIT_LIST_HEAD(&mi->lineage_list);
......
......@@ -597,9 +597,9 @@ static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg)
/**
* In case there is no rss information for irn, initialize it.
*/
static void *init_rss_irn(ir_phase *ph, const ir_node *irn, void *old)
static void *init_rss_irn(ir_phase *ph, const ir_node *irn)
{
rss_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0]));
rss_irn_t *res = phase_alloc(ph, sizeof(res[0]));
res->descendant_list = plist_obstack_new(phase_obst(ph));
res->descendants = NULL;
......@@ -760,7 +760,6 @@ static void collect_node_info(rss_t *rss, ir_node *irn)
/* check if node info is already available */
if (rss_irn->handled)
return;
//phase_reinit_single_irn_data(&rss->ph, irn);
DBG((rss->dbg, LEVEL_1, "\tcomputing consumers of %+F:\n", irn));
......
......@@ -334,21 +334,13 @@ typedef struct _next_use_t {
or NULL. */
} next_use_t;
static void *next_use_init(ir_phase *phase, const ir_node *irn, void *old)
{
(void) phase;
(void) irn;
(void) old;
return NULL;
}
static void build_next_uses(block_info_t *bi)
{
ir_node *irn;
sched_renumber(bi->bl);
phase_init(&bi->next_uses, bi->bel->irg, next_use_init);
phase_init(&bi->next_uses, bi->bel->irg, phase_irn_init_default);
sched_foreach_reverse(bi->bl, irn) {
int i;
......
......@@ -34,11 +34,10 @@
#include "irgraph_t.h"
#include "irphase_t.h"
void *phase_irn_init_default(ir_phase *ph, const ir_node *irn, void *old)
void *phase_irn_init_default(ir_phase *ph, const ir_node *irn)
{
(void) ph;
(void) irn;
(void) old;
return NULL;
}
......@@ -75,7 +74,7 @@ void phase_free(ir_phase *phase)
phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat)
{
int i, n;
unsigned i, n;
memset(stat, 0, sizeof(stat[0]));
stat->node_map_bytes = phase->n_data_ptr * sizeof(phase->data_ptr[0]);
......@@ -89,31 +88,19 @@ phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat)
return stat;
}
void phase_reinit_irn_data(ir_phase *phase)
void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit)
{
int i, n;
if (! phase->data_init)
return;
for (i = 0, n = phase->n_data_ptr; i < n; ++i) {
if (phase->data_ptr[i])
phase->data_init(phase, get_idx_irn(phase->irg, i), phase->data_ptr[i]);
}
}
void phase_reinit_block_irn_data(ir_phase *phase, ir_node *block)
{
int i, n;
unsigned i, n;
ir_graph *irg;
if (! phase->data_init)
return;
irg = phase->irg;
for (i = 0, n = phase->n_data_ptr; i < n; ++i) {
if (phase->data_ptr[i]) {
ir_node *irn = get_idx_irn(phase->irg, i);
if (! is_Block(irn) && get_nodes_block(irn) == block)
phase->data_init(phase, irn, phase->data_ptr[i]);
ir_node *node = get_idx_irn(irg, i);
data_reinit(phase, node, phase->data_ptr[i]);
}
}
}
......
......@@ -29,7 +29,9 @@
#include "firm_types.h"
typedef struct ir_phase ir_phase;
typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn, void *old);
typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn);
typedef void *(phase_irn_reinit)(ir_phase *phase, const ir_node *irn,
void *old_data);
/**
* Allocate and initialize a new phase object
......@@ -37,6 +39,7 @@ typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn, void *old);
* @param irg The graph the phase will run on.
* @param irn_data_init A callback that is called to initialize newly created
* node data. Must be non-null. You could use
* phase_irn_init_default
* @return A new phase object.
*/
ir_phase *new_phase(ir_graph *irg, phase_irn_init *data_init);
......@@ -60,21 +63,15 @@ void phase_deinit(ir_phase *phase);
void phase_free(ir_phase *phase);
/**
* Re-initialize the irn data for all nodes in the node => data map using the given callback.
* Re-initialize the irn data for all nodes in the node => data map using the
* given callback.
* This is mainly used for reusing already allocated memory which could speed
* things up a little bit.
*
* @param phase The phase.
* @param phase The phase.
* @param called to reinitialize phase data.
*/
void phase_reinit_irn_data(ir_phase *phase);
/**
* Re-initialize the irn data for all nodes having phase data in the given block.
*
* @param phase The phase.
* @param block The block.
*
* @note Beware: iterates over all nodes in the graph to find the nodes of the given block.
*/
void phase_reinit_block_irn_data(ir_phase *phase, ir_node *block);
void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit);
/**
* A default node initializer.
......
......@@ -39,7 +39,7 @@ struct ir_phase {
void **data_ptr; /**< Map node indexes to irn data on the obstack. */
ir_graph *irg; /**< The irg this phase will we applied to. */
phase_irn_init *data_init; /**< A callback that is called to initialize newly created node data. */
size_t n_data_ptr; /**< The length of the data_ptr array. */
unsigned n_data_ptr; /**< The length of the data_ptr array. */
struct obstack obst; /**< The obstack where the irn phase data will be stored on. */
void *priv; /**< Some pointer private to the user of the phase. */
};
......@@ -69,7 +69,8 @@ phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat);
* @param phase The phase.
* @param irn The irn.
*/
static inline void phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn)
static inline void phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn,
phase_irn_reinit *reinit)