From: Sebastian Hack Date: Thu, 22 Nov 2007 11:59:33 +0000 (+0000) Subject: Changed phase node initializer to take const ir_node X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=0e5f781d021c0b1e20ba08f583d4971419fedb5d;p=libfirm Changed phase node initializer to take const ir_node Adapted all the files to that -> constification Added irg managed phases -> scheduling uses that now. [r16820] --- diff --git a/ir/ana/height.c b/ir/ana/height.c index 43e06a28d..d7cb2611a 100644 --- a/ir/ana/height.c +++ b/ir/ana/height.c @@ -52,7 +52,7 @@ typedef struct { unsigned visited; } irn_height_t; -static void *irn_height_init(ir_phase *ph, ir_node *irn, void *data) +static void *irn_height_init(ir_phase *ph, const ir_node *irn, void *data) { irn_height_t *h = data ? data : phase_alloc(ph, sizeof(h[0])); (void)irn; diff --git a/ir/ana/irlivechk.c b/ir/ana/irlivechk.c index 2d6e91a71..39090bc03 100644 --- a/ir/ana/irlivechk.c +++ b/ir/ana/irlivechk.c @@ -61,7 +61,7 @@ #include "statev.h" typedef struct _bl_info_t { - ir_node *block; /**< The block. */ + const ir_node *block; /**< The block. */ int be_tgt_calc : 1; int id : 31; /**< a tight number for the block. @@ -87,7 +87,7 @@ struct _lv_chk_t { bl_info_t **map; }; -static void *init_block_data(ir_phase *ph, ir_node *irn, void *old) +static void *init_block_data(ir_phase *ph, const ir_node *irn, void *old) { lv_chk_t *lv = container_of(ph, lv_chk_t, ph); bl_info_t *bi = phase_alloc(ph, sizeof(bi[0])); @@ -164,7 +164,7 @@ static void red_trans_closure(lv_chk_t *lv) } -static void compute_back_edge_chain(lv_chk_t *lv, ir_node *bl) +static void compute_back_edge_chain(lv_chk_t *lv, const ir_node *bl) { bitset_t *tmp = bitset_alloca(lv->n_blocks); bl_info_t *bi = get_block_info(lv, bl); diff --git a/ir/ana/phiclass.c b/ir/ana/phiclass.c index f90046f1c..fb516f8a0 100644 --- a/ir/ana/phiclass.c +++ b/ir/ana/phiclass.c @@ -64,7 +64,7 @@ static INLINE void _set_phi_class(ir_phase *ph, ir_node *irn, ir_node ***cls) { } /* initialize data structure for given irn in given phase */ -static void *irn_phi_class_init(ir_phase *ph, ir_node *irn, void *data) { +static void *irn_phi_class_init(ir_phase *ph, const ir_node *irn, void *data) { irn_phi_class_t *ipc = data ? data : phase_alloc(ph, sizeof(ipc[0])); (void) irn; memset(ipc, 0, sizeof(ipc[0])); diff --git a/ir/be/bearch.h b/ir/be/bearch.h index c99ed1339..074c56a45 100644 --- a/ir/be/bearch.h +++ b/ir/be/bearch.h @@ -143,8 +143,10 @@ typedef enum arch_irn_flags_t { */ extern const char *arch_irn_flag_str(arch_irn_flags_t flag); +#if 0 extern const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn); +#endif extern void arch_set_frame_offset(const arch_env_t *env, ir_node *irn, int bias); diff --git a/ir/be/becopyheur2.c b/ir/be/becopyheur2.c index bd2a98eac..429145e29 100644 --- a/ir/be/becopyheur2.c +++ b/ir/be/becopyheur2.c @@ -135,7 +135,7 @@ typedef struct { } co2_t; struct _co2_irn_t { - ir_node *irn; + const ir_node *irn; affinity_node_t *aff; co2_irn_t *touched_next; col_t tmp_col; @@ -195,7 +195,7 @@ 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, ir_node *irn, void *data) +static void *co2_irn_init(ir_phase *ph, const ir_node *irn, void *data) { co2_t *env = (co2_t *) ph; affinity_node_t *a = get_affinity_info(env->co, irn); @@ -250,13 +250,13 @@ int cmp_edges(const void *a, const void *b) return QSORT_CMP(q->costs, p->costs); } -static col_t get_col(co2_t *env, ir_node *irn) +static col_t get_col(co2_t *env, const ir_node *irn) { co2_irn_t *ci = get_co2_irn(env, irn); return ci->tmp_fixed ? ci->tmp_col : ci->orig_col; } -static INLINE int color_is_fix(co2_t *env, ir_node *irn) +static INLINE int color_is_fix(co2_t *env, const ir_node *irn) { co2_irn_t *ci = get_co2_irn(env, irn); return ci->fixed || ci->tmp_fixed; @@ -306,7 +306,7 @@ static INLINE int is_constrained(co2_t *env, co2_irn_t *ci) return ci->is_constrained; } -static void incur_constraint_costs(co2_t *env, ir_node *irn, col_cost_pair_t *col_costs, int costs) +static void incur_constraint_costs(co2_t *env, const ir_node *irn, col_cost_pair_t *col_costs, int costs) { const arch_register_req_t *req; @@ -338,14 +338,14 @@ static void incur_constraint_costs(co2_t *env, ir_node *irn, col_cost_pair_t *co */ static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *col_costs) { - ir_node *irn = ci->irn; + const ir_node *irn = ci->irn; be_ifg_t *ifg = env->co->cenv->ifg; int n_regs = env->co->cls->n_regs; bitset_t *forb = bitset_alloca(n_regs); affinity_node_t *a = ci->aff; bitset_pos_t elm; - ir_node *pos; + const ir_node *pos; void *it; int i; @@ -426,9 +426,9 @@ static void materialize_coloring(struct list_head *h) } } -static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth); +static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth); -static int recolor(co2_t *env, ir_node *irn, col_cost_pair_t *col_list, struct list_head *parent_changed, int depth) +static int recolor(co2_t *env, const ir_node *irn, col_cost_pair_t *col_list, struct list_head *parent_changed, int depth) { int n_regs = env->co->cls->n_regs; be_ifg_t *ifg = env->co->cenv->ifg; @@ -446,7 +446,7 @@ static int recolor(co2_t *env, ir_node *irn, col_cost_pair_t *col_list, struct l int neigh_ok = 1; struct list_head changed; - ir_node *n; + const ir_node *n; void *it; DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying color %d(%d) on %+F\n", depth, tgt_col, costs, irn)); @@ -513,7 +513,7 @@ static int recolor(co2_t *env, ir_node *irn, col_cost_pair_t *col_list, struct l return res; } -static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth) +static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth) { co2_irn_t *ci = get_co2_irn(env, irn); int res = 0; @@ -554,7 +554,7 @@ static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list return res; } -static int change_color_single(co2_t *env, ir_node *irn, col_t tgt_col, struct list_head *parent_changed, int depth) +static int change_color_single(co2_t *env, const ir_node *irn, col_t tgt_col, struct list_head *parent_changed, int depth) { co2_irn_t *ci = get_co2_irn(env, irn); col_t col = get_col(env, irn); @@ -632,7 +632,7 @@ static void node_color_badness(co2_cloud_irn_t *ci, int *badness) bitset_t *bs = bitset_alloca(n_regs); bitset_pos_t elm; - ir_node *irn; + const ir_node *irn; void *it; admissible_colors(env, &ci->inh, bs); @@ -863,7 +863,7 @@ static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a) static void apply_coloring(co2_cloud_irn_t *ci, col_t col, int depth) { - ir_node *irn = ci->inh.irn; + const ir_node *irn = ci->inh.irn; int *front = FRONT_BASE(ci, col); int i, ok; struct list_head changed; @@ -1104,7 +1104,7 @@ static void writeback_colors(co2_t *env) for(irn = env->touched; irn; irn = irn->touched_next) { const arch_register_t *reg = arch_register_for_index(env->co->cls, irn->orig_col); - arch_set_irn_register(aenv, irn->irn, reg); + arch_set_irn_register(aenv, (ir_node *) irn->irn, reg); } } diff --git a/ir/be/becopyheur4.c b/ir/be/becopyheur4.c index d08819f77..42bdee7a1 100644 --- a/ir/be/becopyheur4.c +++ b/ir/be/becopyheur4.c @@ -91,23 +91,23 @@ typedef struct _col_cost_t { * An affinity chunk. */ typedef struct _aff_chunk_t { - ir_node **n; /**< An ARR_F containing all nodes of the chunk. */ - bitset_t *nodes; /**< A bitset containing all nodes inside this chunk. */ - bitset_t *interfere; /**< A bitset containing all interfering neighbours of the nodes in this chunk. */ - int weight; /**< Weight of this chunk */ - unsigned weight_consistent : 1; /**< Set if the weight is consistent. */ - unsigned deleted : 1; /**< Set if the was deleted. */ - int id; /**< For debugging: An id of this chunk. */ - int visited; - col_cost_t *color_affinity; + const ir_node **n; /**< An ARR_F containing all nodes of the chunk. */ + bitset_t *nodes; /**< A bitset containing all nodes inside this chunk. */ + bitset_t *interfere; /**< A bitset containing all interfering neighbours of the nodes in this chunk. */ + int weight; /**< Weight of this chunk */ + unsigned weight_consistent : 1; /**< Set if the weight is consistent. */ + unsigned deleted : 1; /**< Set if the was deleted. */ + int id; /**< For debugging: An id of this chunk. */ + int visited; + col_cost_t *color_affinity; } aff_chunk_t; /** * An affinity edge. */ typedef struct _aff_edge_t { - ir_node *src; /**< Source node. */ - ir_node *tgt; /**< Target node. */ + const ir_node *src; /**< Source node. */ + const ir_node *tgt; /**< Target node. */ double weight; /**< The weight of this edge. */ } aff_edge_t; @@ -128,7 +128,7 @@ typedef struct _co_mst_env_t { /* stores coalescing related information for a node */ typedef struct _co_mst_irn_t { - ir_node *irn; /**< the irn this information belongs to */ + const ir_node *irn; /**< the irn this information belongs to */ aff_chunk_t *chunk; /**< the chunk this irn belongs to */ bitset_t *adm_colors; /**< set of admissible colors for this irn */ ir_node **int_neighs; /**< array of all interfering neighbours (cached for speed reasons) */ @@ -253,7 +253,7 @@ static INLINE aff_chunk_t *new_aff_chunk(co_mst_env_t *env) { aff_chunk_t *c = xmalloc(sizeof(*c)); c->weight = -1; c->weight_consistent = 0; - c->n = NEW_ARR_F(ir_node *, 0); + c->n = NEW_ARR_F(const ir_node *, 0); c->nodes = bitset_irg_malloc(env->co->irg); c->interfere = bitset_irg_malloc(env->co->irg); c->color_affinity = xmalloc(env->n_regs * sizeof(c->color_affinity[0])); @@ -300,7 +300,7 @@ 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, ir_node *irn, void *old) { +static void *co_mst_irn_init(ir_phase *ph, const ir_node *irn, void *old) { co_mst_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0])); co_mst_env_t *env = ph->priv; @@ -358,7 +358,7 @@ static void *co_mst_irn_init(ir_phase *ph, ir_node *irn, void *old) { /** * Check if affinity chunk @p chunk interferes with node @p irn. */ -static INLINE int aff_chunk_interferes(co_mst_env_t *env, const aff_chunk_t *chunk, ir_node *irn) { +static INLINE int aff_chunk_interferes(co_mst_env_t *env, const aff_chunk_t *chunk, const ir_node *irn) { (void) env; return bitset_is_set(chunk->interfere, get_irn_idx(irn)); } @@ -383,7 +383,7 @@ static INLINE int aff_chunks_interfere(co_mst_env_t *env, const aff_chunk_t *c1, * Returns the affinity chunk of @p irn or creates a new * one with @p irn as element if there is none assigned. */ -static INLINE aff_chunk_t *get_aff_chunk(co_mst_env_t *env, ir_node *irn) { +static INLINE aff_chunk_t *get_aff_chunk(co_mst_env_t *env, const ir_node *irn) { co_mst_irn_t *node = get_co_mst_irn(env, irn); return node->chunk; } @@ -393,7 +393,7 @@ static INLINE aff_chunk_t *get_aff_chunk(co_mst_env_t *env, ir_node *irn) { * are no interference edges from chunk(src) to chunk(tgt)). * @return 1 if successful, 0 if not possible */ -static int aff_chunk_absorb(co_mst_env_t *env, ir_node *src, ir_node *tgt) { +static int aff_chunk_absorb(co_mst_env_t *env, const ir_node *src, const ir_node *tgt) { aff_chunk_t *c1 = get_aff_chunk(env, src); aff_chunk_t *c2 = get_aff_chunk(env, tgt); @@ -477,7 +477,7 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c) { } for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *n = c->n[idx]; + const ir_node *n = c->n[idx]; const affinity_node_t *an = get_affinity_info(env->co, n); co_mst_irn_t *node = get_co_mst_irn(env, n); @@ -517,7 +517,7 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c) { */ static int count_interfering_aff_neighs(co_mst_env_t *env, const affinity_node_t *an) { const neighb_t *neigh; - ir_node *irn = an->irn; + const ir_node *irn = an->irn; const co_mst_irn_t *node = get_co_mst_irn(env, irn); int res = 0; @@ -576,8 +576,8 @@ static void build_affinity_chunks(co_mst_env_t *env) { /* build the affinity edges */ co_gs_foreach_neighb(an, neigh) { - ir_node *m = neigh->irn; - int m_idx = get_irn_idx(m); + const ir_node *m = neigh->irn; + int m_idx = get_irn_idx(m); /* record the edge in only one direction */ if (n_idx < m_idx) { @@ -650,13 +650,13 @@ static void build_affinity_chunks(co_mst_env_t *env) { static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chunk_t *chunk) { pqueue *grow = new_pqueue(); - int i; + const ir_node *max_node = NULL; int max_weight = 0; - ir_node *max_node = NULL; + int i; for (i = ARR_LEN(chunk->n) - 1; i >= 0; i--) { - ir_node *irn = chunk->n[i]; - affinity_node_t *an = get_affinity_info(env->co, irn); + const ir_node *irn = chunk->n[i]; + affinity_node_t *an = get_affinity_info(env->co, irn); int w = 0; neighb_t *neigh; @@ -680,7 +680,7 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu for (i = ARR_LEN(chunk->n) - 1; i >= 0; --i) bitset_add_irn(visited, chunk->n[i]); - pqueue_put(grow, max_node, max_weight); + pqueue_put(grow, (void *) max_node, max_weight); bitset_remv_irn(visited, max_node); i = 0; while (!pqueue_empty(grow)) { @@ -701,7 +701,7 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu co_mst_irn_t *node = get_co_mst_irn(env, neigh->irn); if (bitset_contains_irn(visited, node->irn)) { - pqueue_put(grow, neigh->irn, neigh->costs); + pqueue_put(grow, (void *) neigh->irn, neigh->costs); bitset_remv_irn(visited, node->irn); } } @@ -737,8 +737,8 @@ static void expand_chunk_from(co_mst_env_t *env, co_mst_irn_t *node, bitset_t *v if (an != NULL) { neighb_t *neigh; co_gs_foreach_neighb(an, neigh) { - ir_node *m = neigh->irn; - int m_idx = get_irn_idx(m); + const ir_node *m = neigh->irn; + int m_idx = get_irn_idx(m); co_mst_irn_t *n2; /* skip ignore nodes */ @@ -785,7 +785,7 @@ static aff_chunk_t *fragment_chunk(co_mst_env_t *env, int col, aff_chunk_t *c, w aff_chunk_t *best = NULL; for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *irn; + const ir_node *irn; co_mst_irn_t *node; aff_chunk_t *tmp_chunk; decide_func_t *decider; @@ -1152,7 +1152,7 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { /* try to bring all nodes of given chunk to the current color. */ for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *irn = c->n[idx]; + const ir_node *irn = c->n[idx]; co_mst_irn_t *node = get_co_mst_irn(env, irn); int good; @@ -1244,8 +1244,8 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { DB((dbg, LEVEL_2, "using color %d\n", best_color)); for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx) { - ir_node *irn = best_chunk->n[idx]; - co_mst_irn_t *node = get_co_mst_irn(env, irn); + const ir_node *irn = best_chunk->n[idx]; + co_mst_irn_t *node = get_co_mst_irn(env, irn); int res; /* bring the node to the color. */ @@ -1264,7 +1264,7 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { /* remove the nodes in best chunk from original chunk */ bitset_andnot(c->nodes, best_chunk->nodes); for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *irn = c->n[idx]; + const ir_node *irn = c->n[idx]; if (bitset_is_set(best_chunk->nodes, get_irn_idx(irn))) { int last = ARR_LEN(c->n) - 1; @@ -1277,8 +1277,8 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { /* we have to get the nodes back into the original chunk because they are scattered over temporary chunks */ for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *n = c->n[idx]; - co_mst_irn_t *nn = get_co_mst_irn(env, n); + const ir_node *n = c->n[idx]; + co_mst_irn_t *nn = get_co_mst_irn(env, n); nn->chunk = c; } @@ -1286,7 +1286,7 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { visited = bitset_irg_malloc(env->co->irg); bitset_or(visited, best_chunk->nodes); for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { - ir_node *irn = c->n[idx]; + const ir_node *irn = c->n[idx]; if (! bitset_is_set(visited, get_irn_idx(irn))) { aff_chunk_t *new_chunk = new_aff_chunk(env); co_mst_irn_t *node = get_co_mst_irn(env, irn); @@ -1298,8 +1298,8 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { } for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx) { - ir_node *n = best_chunk->n[idx]; - co_mst_irn_t *nn = get_co_mst_irn(env, n); + const ir_node *n = best_chunk->n[idx]; + co_mst_irn_t *nn = get_co_mst_irn(env, n); nn->chunk = NULL; } @@ -1417,4 +1417,5 @@ void be_init_copyheur4(void) { FIRM_DBG_REGISTER(dbg, "firm.be.co.heur4"); } + BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur4); diff --git a/ir/be/becopyilp2.c b/ir/be/becopyilp2.c index 669d7ab42..35ec959aa 100644 --- a/ir/be/becopyilp2.c +++ b/ir/be/becopyilp2.c @@ -291,7 +291,7 @@ static void build_clique_star_cstr(ilp_env_t *ienv) { co_gs_foreach_aff_node(ienv->co, aff) { struct obstack ob; neighb_t *nbr; - ir_node *center = aff->irn; + const ir_node *center = aff->irn; ir_node **nodes; set *edges; int i, o, n_nodes, n_edges; @@ -398,7 +398,7 @@ static void build_clique_star_cstr(ilp_env_t *ienv) { } -static void extend_path(ilp_env_t *ienv, pdeq *path, ir_node *irn) { +static void extend_path(ilp_env_t *ienv, pdeq *path, const ir_node *irn) { be_ifg_t *ifg = ienv->co->cenv->ifg; int i, len; ir_node **curr_path; diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index a610d4098..e87a4cd70 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -870,7 +870,7 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) ir_node *irn; void *it, *nit; int n, n_regs; - unsigned i, j; + unsigned i; n_regs = 0; for(i = 0; i < co->cls->n_regs; ++i) { @@ -894,17 +894,6 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) fprintf(f, "%d %d\n", n, n_regs); -#if 0 - printf("debut\n"); - for (i = 0; i < n_regs; ++i) { - for (j = 0; j < i; ++j) { - fprintf(f, "%d %d -1\n", i, j); - printf("%d %d\n", i, j); - } - } - printf("fin\n"); -#endif - be_ifg_foreach_node(ifg, it, irn) { if(!arch_irn_is(co->aenv, irn, ignore)) { int idx = node_map[get_irn_idx(irn)]; @@ -946,333 +935,6 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f) xfree(node_map); } -typedef struct _appel_clique_walker_t { - ir_phase ph; - const copy_opt_t *co; - int curr_nr; - int node_count; - FILE *f; - int dumb; - int *color_map; - struct obstack obst; -} appel_clique_walker_t; - -typedef struct _appel_block_info_t { - int *live_end_nr; - int *live_in_nr; - int *phi_nr; - ir_node **live_end; - ir_node **live_in; - ir_node **phi; - int n_live_end; - int n_live_in; - int n_phi; -} appel_block_info_t; - -static int appel_aff_weight(const appel_clique_walker_t *env, ir_node *bl) -{ -#if 0 - double freq = get_block_execfreq(env->co->cenv->execfreq, bl); - int res = (int) freq; - return res == 0 ? 1 : res; -#else - ir_loop *loop = get_irn_loop(bl); - (void) env; - if(loop) { - int d = get_loop_depth(loop); - return 1 + d * d; - } - return 1; -#endif -} - -static void *appel_clique_walker_irn_init(ir_phase *phase, ir_node *irn, void *old) -{ - appel_block_info_t *res = NULL; - (void) old; - - if(is_Block(irn)) { - appel_clique_walker_t *d = (void *) phase; - res = phase_alloc(phase, sizeof(res[0])); - res->phi_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end_nr)); - res->live_end_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end_nr)); - res->live_in_nr = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in_nr)); - res->live_end = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_end)); - res->live_in = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in)); - res->phi = phase_alloc(phase, d->co->cls->n_regs * sizeof(res->live_in)); - } - - return res; -} - -typedef struct _insn_list_t { - be_insn_t *insn; - struct list_head list; -} insn_list_t; - -static int appel_get_live_end_nr(appel_clique_walker_t *env, ir_node *bl, ir_node *irn) -{ - appel_block_info_t *bli = phase_get_irn_data(&env->ph, bl); - int i; - - for(i = 0; i < bli->n_live_end; ++i) - if(bli->live_end[i] == irn) - return bli->live_end_nr[i]; - - return -1; -} - -static int appel_dump_clique(appel_clique_walker_t *env, const ir_nodeset_t *live, ir_node *bl, int curr_nr, int start_nr) -{ - ir_node **live_arr = alloca(env->co->cls->n_regs * sizeof(live_arr[0])); - ir_node *irn; - int n_live; - int j; - ir_nodeset_iterator_t iter; - - n_live = 0; - foreach_ir_nodeset(live, irn, iter) - live_arr[n_live++] = irn; - - /* dump the live after clique */ - if(!env->dumb) { - for(j = 0; j < n_live; ++j) { - int k; - - for(k = j + 1; k < n_live; ++k) { - fprintf(env->f, "%d %d -1 ", curr_nr + j, curr_nr + k); - } - fprintf(env->f, "\n"); - } - } - - /* dump the affinities */ - for(j = 0; !env->dumb && j < n_live; ++j) { - ir_node *irn = live_arr[j]; - int old_nr = PTR_TO_INT(get_irn_link(irn)); - - /* if the node was already live in the last insn dump the affinity */ - if(old_nr > start_nr) { - int weight = appel_aff_weight(env, bl); - fprintf(env->f, "%d %d %d\n", old_nr, curr_nr + j, weight); - } - } - - /* set the current numbers into the link field. */ - for(j = 0; j < n_live; ++j) { - ir_node *irn = live_arr[j]; - set_irn_link(irn, INT_TO_PTR(curr_nr + j)); - } - - return curr_nr + n_live; -} - -static void appel_walker(ir_node *bl, void *data) -{ - appel_clique_walker_t *env = data; - appel_block_info_t *bli = phase_get_or_set_irn_data(&env->ph, bl); - struct obstack *obst = &env->obst; - void *base = obstack_base(obst); - ir_nodeset_t live; - ir_nodeset_iterator_t iter; - be_lv_t *lv = env->co->cenv->birg->lv; - - int n_insns = 0; - int n_nodes = 0; - int start_nr = env->curr_nr; - int curr_nr = start_nr; - - be_insn_env_t insn_env; - int i, j; - ir_node *irn; - be_insn_t **insns; - - insn_env.aenv = env->co->aenv; - insn_env.cls = env->co->cls; - insn_env.obst = obst; - insn_env.ignore_colors = env->co->cenv->ignore_colors; - - /* Guess how many insns will be in this block. */ - sched_foreach(bl, irn) - n_nodes++; - - bli->n_phi = 0; - insns = xmalloc(n_nodes * sizeof(insns[0])); - - /* Put all insns in an array. */ - irn = sched_first(bl); - while(!sched_is_end(irn)) { - be_insn_t *insn; - insn = be_scan_insn(&insn_env, irn); - insns[n_insns++] = insn; - irn = insn->next_insn; - } - - DBG((dbg, LEVEL_2, "%+F\n", bl)); - ir_nodeset_init(&live); - be_liveness_end_of_block(lv, env->co->aenv, env->co->cls, bl, &live); - - /* Generate the bad and ugly. */ - for(i = n_insns - 1; i >= 0; --i) { - be_insn_t *insn = insns[i]; - - /* The first live set has to be saved in the block border set. */ - if(i == n_insns - 1) { - j = 0; - foreach_ir_nodeset(&live, irn, iter) { - bli->live_end[j] = irn; - bli->live_end_nr[j] = curr_nr + j; - ++j; - } - bli->n_live_end = j; - } - - if(!env->dumb) { - for(j = 0; j < insn->use_start; ++j) { - ir_node *op = insn->ops[j].carrier; - bitset_t *adm = insn->ops[j].regs; - unsigned k; - size_t nr; - - if(!insn->ops[j].has_constraints) - continue; - - nr = 0; - foreach_ir_nodeset(&live, irn, iter) { - if(irn == op) { - break; - } - ++nr; - } - - assert(nr < ir_nodeset_size(&live)); - - for(k = 0; k < env->co->cls->n_regs; ++k) { - int mapped_col = env->color_map[k]; - if(mapped_col >= 0 && !bitset_is_set(adm, k) && !bitset_is_set(env->co->cenv->ignore_colors, k)) - fprintf(env->f, "%d %d -1\n", curr_nr + nr, mapped_col); - } - } - } - - /* dump the clique and update the stuff. */ - curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr); - - /* remove all defs. */ - for(j = 0; j < insn->use_start; ++j) - ir_nodeset_remove(&live, insn->ops[j].carrier); - - if(is_Phi(insn->irn) && arch_irn_consider_in_reg_alloc(env->co->aenv, env->co->cls, insn->irn)) { - bli->phi[bli->n_phi] = insn->irn; - bli->phi_nr[bli->n_phi] = PTR_TO_INT(get_irn_link(insn->irn)); - bli->n_phi++; - } - - /* add all uses */ - else - for(j = insn->use_start; j < insn->n_ops; ++j) - ir_nodeset_insert(&live, insn->ops[j].carrier); - } - - /* print the start clique. */ - curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr); - - i = 0; - foreach_ir_nodeset(&live, irn, iter) { - bli->live_in[i] = irn; - bli->live_in_nr[i] = PTR_TO_INT(get_irn_link(irn)); - ++i; - } - bli->n_live_in = i; - - ir_nodeset_destroy(&live); - free(insns); - obstack_free(obst, base); - env->curr_nr = curr_nr; -} - -static void appel_inter_block_aff(ir_node *bl, void *data) -{ - appel_clique_walker_t *env = data; - appel_block_info_t *bli = phase_get_irn_data(&env->ph, bl); - - int i, j, n; - - for(i = 0; i < bli->n_live_in; ++i) { - ir_node *irn = bli->live_in[i]; - - for(j = 0, n = get_Block_n_cfgpreds(bl); j < n; ++j) { - ir_node *pred = get_Block_cfgpred_block(bl, j); - - int nr = appel_get_live_end_nr(env, pred, irn); - assert(nr >= 0); - fprintf(env->f, "%d %d 1\n", bli->live_in_nr[i], nr); - } - } - - for(i = 0; i < bli->n_phi; ++i) { - ir_node *irn = bli->phi[i]; - - for(j = 0, n = get_Block_n_cfgpreds(bl); j < n; ++j) { - ir_node *pred = get_Block_cfgpred_block(bl, j); - ir_node *op = get_irn_n(irn, j); - - int nr = appel_get_live_end_nr(env, pred, op); - assert(nr >= 0); - fprintf(env->f, "%d %d 1\n", bli->phi_nr[i], nr); - } - } - -} - -void co_dump_appel_graph_cliques(const copy_opt_t *co, FILE *f) -{ - unsigned i; - unsigned n_colors; - appel_clique_walker_t env; - bitset_t *adm = bitset_alloca(co->cls->n_regs); - be_lv_t *lv = co->cenv->birg->lv; - - be_liveness_recompute(lv); - obstack_init(&env.obst); - phase_init(&env.ph, "appel_clique_dumper", co->irg, PHASE_DEFAULT_GROWTH, appel_clique_walker_irn_init, NULL); - env.curr_nr = co->cls->n_regs; - env.co = co; - env.f = f; - - bitset_copy(adm, co->cenv->ignore_colors); - bitset_flip_all(adm); - - /* Make color map. */ - env.color_map = alloca(co->cls->n_regs * sizeof(env.color_map[0])); - for(i = 0, n_colors = 0; i < co->cls->n_regs; ++i) { - const arch_register_t *reg = &co->cls->regs[i]; - env.color_map[i] = arch_register_type_is(reg, ignore) ? -1 : (int) n_colors++; - } - - env.dumb = 1; - env.curr_nr = n_colors; - irg_block_walk_graph(co->irg, firm_clear_link, NULL, NULL); - irg_block_walk_graph(co->irg, appel_walker, NULL, &env); - - fprintf(f, "%d %d\n", env.curr_nr, n_colors); - - /* make the first k nodes interfere */ - for(i = 0; i < n_colors; ++i) { - unsigned j; - for(j = i + 1; j < n_colors; ++j) - fprintf(f, "%d %d -1 ", i, j); - fprintf(f, "\n"); - } - - env.dumb = 0; - env.curr_nr = n_colors; - irg_block_walk_graph(co->irg, firm_clear_link, NULL, NULL); - irg_block_walk_graph(co->irg, appel_walker, NULL, &env); - irg_block_walk_graph(co->irg, appel_inter_block_aff, NULL, &env); - obstack_free(&env.obst, NULL); -} - /* ___ _____ ____ ____ ___ _____ ____ _ |_ _| ___/ ___| | _ \ / _ \_ _| | _ \ _ _ _ __ ___ _ __ (_)_ __ __ _ diff --git a/ir/be/becopyopt_t.h b/ir/be/becopyopt_t.h index 422ee35ba..488372471 100644 --- a/ir/be/becopyopt_t.h +++ b/ir/be/becopyopt_t.h @@ -122,19 +122,19 @@ typedef struct _affinity_node_t affinity_node_t; struct _neighb_t { neighb_t *next; /** the next neighbour entry*/ - ir_node *irn; /** the neighbour itself */ + const ir_node *irn; /** the neighbour itself */ int costs; /** the costs of the edge (affinity_node_t->irn, neighb_t->irn) */ }; struct _affinity_node_t { - ir_node *irn; /** a node with affinity edges */ + const ir_node *irn; /** a node with affinity edges */ int degree; /** number of affinity edges in the linked list below */ neighb_t *neighbours; /** a linked list of all affinity neighbours */ void *data; /** stuff that is attachable. */ }; -static INLINE affinity_node_t *get_affinity_info(const copy_opt_t *co, ir_node *irn) { +static INLINE affinity_node_t *get_affinity_info(const copy_opt_t *co, const ir_node *irn) { affinity_node_t find; ASSERT_GS_AVAIL(co); diff --git a/ir/be/beifg.c b/ir/be/beifg.c index fd663f391..18177640e 100644 --- a/ir/be/beifg.c +++ b/ir/be/beifg.c @@ -78,7 +78,7 @@ size_t (be_ifg_cliques_iter_size)(const be_ifg_t *ifg) return ifg->impl->cliques_iter_size; } -static void *regs_irn_data_init(ir_phase *ph, ir_node *irn, void *data) +static void *regs_irn_data_init(ir_phase *ph, const ir_node *irn, void *data) { coloring_t *coloring = (coloring_t *) ph; (void) data; diff --git a/ir/be/beifg_pointer.c b/ir/be/beifg_pointer.c index 5f0b0e9ba..3d8dc01fa 100644 --- a/ir/be/beifg_pointer.c +++ b/ir/be/beifg_pointer.c @@ -85,7 +85,7 @@ typedef struct _ptr_iter_t { /* PRIVATE FUNCTIONS */ -static void *ptr_irn_data_init(ir_phase *ph, ir_node *irn, void *data) +static void *ptr_irn_data_init(ir_phase *ph, const ir_node *irn, void *data) { ptr_head_t *head = phase_alloc(ph, sizeof(*head)); (void) irn; diff --git a/ir/be/beilpsched.c b/ir/be/beilpsched.c index 8381899cb..1cd28a34e 100644 --- a/ir/be/beilpsched.c +++ b/ir/be/beilpsched.c @@ -139,7 +139,7 @@ typedef union _ilpsched_attr_ { /* A irn for the phase and it's attributes (either node or block) */ typedef struct { - ir_node *irn; + const ir_node *irn; ilpsched_attr_t attr; } be_ilpsched_irn_t; @@ -261,8 +261,8 @@ static int cmp_ilpsched_irn(const void *a, const void *b) { ilpsched_node_attr_t *n2_a = get_ilpsched_node_attr(n2); if (n1_a->sched_point == n2_a->sched_point) { - ir_node *irn_a = n1->irn; - ir_node *irn_b = n2->irn; + const ir_node *irn_a = n1->irn; + const ir_node *irn_b = n2->irn; if (heights_reachable_in_block(glob_heights, irn_a, irn_b)) return 1; @@ -282,7 +282,7 @@ static int cmp_ilpsched_irn(const void *a, const void *b) { /** * In case there is no phase information for irn, initialize it. */ -static void *init_ilpsched_irn(ir_phase *ph, ir_node *irn, void *old) { +static void *init_ilpsched_irn(ir_phase *ph, const ir_node *irn, void *old) { be_ilpsched_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0])); if (res == old) { @@ -686,7 +686,7 @@ static void refine_asap_alap_times(ir_node *irn, void *walk_env) { * *******************************************/ -static INLINE void check_for_keeps(waitq *keeps, ir_node *block, ir_node *irn) { +static INLINE void check_for_keeps(waitq *keeps, const ir_node *block, const ir_node *irn) { const ir_edge_t *edge; (void) block; @@ -704,7 +704,7 @@ static INLINE void check_for_keeps(waitq *keeps, ir_node *block, ir_node *irn) { * Inserts @p irn before @p before into schedule and notifies backend. */ static INLINE void notified_sched_add_before(be_ilpsched_env_t *env, - ir_node *before, ir_node *irn, unsigned cycle) + const ir_node *before, const ir_node *irn, unsigned cycle) { be_ilp_sched_node_scheduled(env->sel, irn, cycle, env->block_env); sched_add_before(before, irn); @@ -714,7 +714,7 @@ static INLINE void notified_sched_add_before(be_ilpsched_env_t *env, * Adds a node, it's Projs (in case of mode_T nodes) and * it's Keeps to schedule. */ -static void add_to_sched(be_ilpsched_env_t *env, ir_node *block, ir_node *irn, unsigned cycle) { +static void add_to_sched(be_ilpsched_env_t *env, const ir_node *block, const ir_node *irn, unsigned cycle) { const ir_edge_t *edge; waitq *keeps = new_waitq(); @@ -940,7 +940,7 @@ static int be_ilpsched_set_type_info(be_ilpsched_env_t *env, ir_node *irn, struc * Returns the largest alap time of a user of @p irn. * The user must be in block @p block. */ -static unsigned be_ilpsched_get_max_alap_user(be_ilpsched_env_t *env, ir_node *irn, ir_node *block) { +static unsigned be_ilpsched_get_max_alap_user(be_ilpsched_env_t *env, const ir_node *irn, const ir_node *block) { const ir_edge_t *edge; unsigned max_alap = 0; diff --git a/ir/be/beilpsched.h b/ir/be/beilpsched.h index 2b6a68240..e3c338b2f 100644 --- a/ir/be/beilpsched.h +++ b/ir/be/beilpsched.h @@ -94,7 +94,7 @@ struct _ilp_sched_selector_if_t { * @param cycle The cycle at which the node is scheduled. * @param block_env The block scheduling environment. */ - void (*node_scheduled)(const void *self, ir_node *irn, unsigned cycle, void *block_env); + void (*node_scheduled)(const void *self, const ir_node *irn, unsigned cycle, void *block_env); }; /** diff --git a/ir/be/beintlive_t.h b/ir/be/beintlive_t.h index 6126a56cd..ee02f2143 100644 --- a/ir/be/beintlive_t.h +++ b/ir/be/beintlive_t.h @@ -31,8 +31,8 @@ static INLINE int _value_dominates_intrablock(const ir_node *a, const ir_node *b) { /* TODO: ? : can be removed?! */ - sched_timestep_t as = is_Phi(a) ? 0 : sched_get_time_step(a); - sched_timestep_t bs = is_Phi(b) ? 0 : sched_get_time_step(b); + sched_timestep_t as = sched_is_scheduled(a) ? sched_get_time_step(a) : 0; + sched_timestep_t bs = sched_is_scheduled(b) ? sched_get_time_step(b) : 0; return as <= bs; } @@ -45,8 +45,8 @@ static INLINE int _value_dominates_intrablock(const ir_node *a, const ir_node *b static INLINE int _value_strictly_dominates_intrablock(const ir_node *a, const ir_node *b) { /* TODO: ? : can be removed?! */ - sched_timestep_t as = is_Phi(a) ? 0 : sched_get_time_step(a); - sched_timestep_t bs = is_Phi(b) ? 0 : sched_get_time_step(b); + sched_timestep_t as = sched_is_scheduled(a) ? sched_get_time_step(a) : 0; + sched_timestep_t bs = sched_is_scheduled(b) ? sched_get_time_step(b) : 0; return as < bs; } diff --git a/ir/be/belive.c b/ir/be/belive.c index b75d982ff..43174d72f 100644 --- a/ir/be/belive.c +++ b/ir/be/belive.c @@ -482,7 +482,7 @@ static void lv_dump_block(void *context, FILE *f, const ir_node *bl) } } -static void *lv_phase_data_init(ir_phase *phase, ir_node *irn, void *old) +static void *lv_phase_data_init(ir_phase *phase, const ir_node *irn, void *old) { struct _be_lv_info_t *info = phase_alloc(phase, LV_STD_SIZE * sizeof(info[0])); (void) irn; diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 56cc48a71..62d5d4cbc 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -452,6 +452,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) /* set the current graph (this is important for several firm functions) */ current_ir_graph = irg; + be_sched_init_phase(irg); + /* reset the phi handler. */ be_phi_handler_reset(env.phi_handler); @@ -725,6 +727,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) #undef LC_EMIT_RA #undef LC_EMIT + be_sched_free_phase(irg); + be_free_birg(birg); /* switched off due to statistics (statistic module needs all irgs) */ diff --git a/ir/be/besched.c b/ir/be/besched.c index 331c6261e..75901a691 100644 --- a/ir/be/besched.c +++ b/ir/be/besched.c @@ -55,12 +55,12 @@ FIRM_IMPL1(sched_prev, ir_node *, const ir_node *) FIRM_IMPL1(sched_is_scheduled, int, const ir_node *) FIRM_IMPL1(sched_first, ir_node *, const ir_node *) FIRM_IMPL1(sched_last, ir_node *, const ir_node *) -FIRM_IMPL2_VOID(sched_add_after, ir_node *, ir_node *) -FIRM_IMPL2_VOID(sched_add_before, ir_node *, ir_node *) -FIRM_IMPL1_VOID(sched_init_block, ir_node *) -FIRM_IMPL1_VOID(sched_reset, ir_node *) +FIRM_IMPL2_VOID(sched_add_after, const ir_node *, const ir_node *) +FIRM_IMPL2_VOID(sched_add_before, const ir_node *, const ir_node *) +FIRM_IMPL1_VOID(sched_init_block, const ir_node *) +FIRM_IMPL1_VOID(sched_reset, const ir_node *) FIRM_IMPL2(sched_comes_after, int, const ir_node *, const ir_node *) -FIRM_IMPL1_VOID(sched_remove, ir_node *) +FIRM_IMPL1_VOID(sched_remove, const ir_node *) size_t sched_irn_data_offset = 0; @@ -116,7 +116,7 @@ int sched_skip_phi_predicator(const ir_node *irn, void *data) { /* Skip nodes in a schedule. */ ir_node *sched_skip(ir_node *from, int forward, sched_predicator_t *predicator, void *data) { - const ir_node *bl = get_block(from); + const ir_node *bl = get_block_const(from); ir_node *curr; if (forward) { @@ -189,3 +189,24 @@ void be_remove_dead_nodes_from_schedule(be_irg_t *birg) // walk schedule and remove non-marked nodes irg_block_walk_graph(irg, remove_dead_nodes_walker, NULL, &env); } + +static void *sched_irn_init(ir_phase *ph, const ir_node *irn, void *old) +{ + sched_info_t *info = old ? old : phase_alloc(ph, sizeof(*info)); + + info->idx = get_irn_idx(irn); + INIT_LIST_HEAD(&info->list); + info->scheduled = 0; + info->time_step = 0; + return info; +} + +void be_sched_init_phase(ir_graph *irg) +{ + init_irg_phase(irg, PHASE_BE_SCHED, 0, sched_irn_init); +} + +void be_sched_free_phase(ir_graph *irg) +{ + free_irg_phase(irg, PHASE_BE_SCHED); +} diff --git a/ir/be/besched.h b/ir/be/besched.h index c7fbab2c3..9deda2a8b 100644 --- a/ir/be/besched.h +++ b/ir/be/besched.h @@ -47,11 +47,11 @@ ir_node *sched_next(const ir_node *irn); ir_node *sched_prev(const ir_node *irn); ir_node *sched_first(const ir_node *block); ir_node *sched_last(const ir_node *block); -void sched_add_before(ir_node *before, ir_node *irn); -void sched_add_after(ir_node *after, ir_node *irn); -void sched_init_block(ir_node *block); -void sched_reset(ir_node *node); -void sched_remove(ir_node *irn); +void sched_add_before(const ir_node *before, const ir_node *irn); +void sched_add_after(const ir_node *after, const ir_node *irn); +void sched_init_block(const ir_node *block); +void sched_reset(const ir_node *node); +void sched_remove(const ir_node *irn); #define sched_is_end(irn) is_Block(irn) #define sched_is_begin(irn) is_Block(irn) @@ -84,4 +84,7 @@ void sched_remove(ir_node *irn); */ void be_remove_dead_nodes_from_schedule(be_irg_t *birg); +void be_sched_init_phase(ir_graph *irg); +void be_sched_free_phase(ir_graph *irg); + #endif /* FIRM_BE_BESCHED_H */ diff --git a/ir/be/besched_t.h b/ir/be/besched_t.h index 70b653453..3e874f5c7 100644 --- a/ir/be/besched_t.h +++ b/ir/be/besched_t.h @@ -31,6 +31,8 @@ #include "list.h" #include "irnode_t.h" #include "irgraph_t.h" +#include "irphase_t.h" +#include "irphases_t.h" #include "beutil.h" #include "besched.h" @@ -47,16 +49,14 @@ extern size_t sched_irn_data_offset; */ typedef struct _sched_info_t { struct list_head list; /**< The list head to list the nodes in a schedule. */ - sched_timestep_t time_step; /**< If a is after b in a schedule, its time step is - larger than b's. */ + unsigned idx; /**< The node index of the nodes this schedule info belongs to. */ + sched_timestep_t time_step; /**< If a is after b in a schedule, its time step is larger than b's. */ unsigned scheduled : 1; /**< 1, if the node is in the schedule of the block, 0 else. */ } sched_info_t; -#define _sched_entry(list_head) (list_entry(list_head, sched_info_t, list)) - -#define get_irn_sched_info(irn) get_irn_data(skip_Proj_const(irn), sched_info_t, sched_irn_data_offset) - -#define get_sched_info_irn(sched_info) get_irn_data_base(sched_info, sched_irn_data_offset) +#define _sched_entry(list_head) (list_entry(list_head, sched_info_t, list)) +#define get_irn_sched_info(irn) ((sched_info_t *) get_or_set_irn_phase_info(skip_Proj_const(irn), PHASE_BE_SCHED)) +#define get_sched_info_irn(irg, sched_info) get_idx_irn((irg), (sched_info)->idx) /** * Check, if the node is scheduled. @@ -133,7 +133,7 @@ static INLINE int _sched_has_prev(const ir_node *irn) static INLINE ir_node *_sched_next(const ir_node *irn) { const sched_info_t *info = get_irn_sched_info(irn); - return get_sched_info_irn(_sched_entry(info->list.next)); + return get_sched_info_irn(get_irn_irg(irn), _sched_entry(info->list.next)); } /** @@ -145,7 +145,7 @@ static INLINE ir_node *_sched_next(const ir_node *irn) static INLINE ir_node *_sched_prev(const ir_node *irn) { const sched_info_t *info = get_irn_sched_info(irn); - return get_sched_info_irn(_sched_entry(info->list.prev)); + return get_sched_info_irn(get_irn_irg(irn), _sched_entry(info->list.prev)); } /** @@ -178,7 +178,7 @@ static INLINE ir_node *_sched_last(const ir_node *block) */ void sched_renumber(const ir_node *block); -static INLINE void _sched_set_time_stamp(ir_node *irn) +static INLINE void _sched_set_time_stamp(const ir_node *irn) { sched_info_t *inf = get_irn_sched_info(irn); sched_timestep_t before_ts = _sched_entry(inf->list.prev)->time_step; @@ -211,7 +211,7 @@ static INLINE void _sched_set_time_stamp(ir_node *irn) * @param irn The node to add. * @return The given node. */ -static INLINE void _sched_add_before(ir_node *before, ir_node *irn) +static INLINE void _sched_add_before(const ir_node *before, const ir_node *irn) { sched_info_t *info = get_irn_sched_info(irn); assert(_sched_is_scheduled(before)); @@ -228,7 +228,7 @@ static INLINE void _sched_add_before(ir_node *before, ir_node *irn) * @param irn The node to add. * @return The given node. */ -static INLINE void _sched_add_after(ir_node *after, ir_node *irn) +static INLINE void _sched_add_after(const ir_node *after, const ir_node *irn) { sched_info_t *info = get_irn_sched_info(irn); assert(_sched_is_scheduled(after)); @@ -239,7 +239,7 @@ static INLINE void _sched_add_after(ir_node *after, ir_node *irn) info->scheduled = 1; } -static INLINE void _sched_init_block(ir_node *block) +static INLINE void _sched_init_block(const ir_node *block) { sched_info_t *info = get_irn_sched_info(block); assert(info->scheduled == 0 && info->time_step == 0); @@ -247,7 +247,7 @@ static INLINE void _sched_init_block(ir_node *block) info->scheduled = 1; } -static INLINE void _sched_reset(ir_node *node) +static INLINE void _sched_reset(const ir_node *node) { sched_info_t *info = get_irn_sched_info(node); info->scheduled = 0; @@ -257,7 +257,7 @@ static INLINE void _sched_reset(ir_node *node) * Remove a node from the scheduled. * @param irn The node. */ -static INLINE void _sched_remove(ir_node *irn) +static INLINE void _sched_remove(const ir_node *irn) { sched_info_t *info; #ifndef SCHEDULE_PROJ @@ -336,8 +336,7 @@ int sched_skip_phi_predicator(const ir_node *irn, void *data); * @return The first node not rejected by the predicator or the block * itself if all nodes were rejected. */ -ir_node *sched_skip(ir_node *from, int forward, - sched_predicator_t *predicator, void *data); +ir_node *sched_skip(ir_node *from, int forward, sched_predicator_t *predicator, void *data); #define sched_get_time_step(irn) _sched_get_time_step(irn) #define sched_has_next(irn) _sched_has_next(irn) diff --git a/ir/be/beschedmris.c b/ir/be/beschedmris.c index 2d4488929..742f87884 100644 --- a/ir/be/beschedmris.c +++ b/ir/be/beschedmris.c @@ -79,7 +79,7 @@ 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, ir_node *irn, void *data) +static void *mris_irn_data_init(ir_phase *ph, const ir_node *irn, void *data) { mris_irn_t *mi = data ? data : phase_alloc(ph, sizeof(mi[0])); (void) irn; diff --git a/ir/be/beschedrss.c b/ir/be/beschedrss.c index 26857ccf5..6dfdfa1da 100644 --- a/ir/be/beschedrss.c +++ b/ir/be/beschedrss.c @@ -111,16 +111,16 @@ typedef struct _chain { typedef struct _rss_irn { plist_t *consumer_list; /**< List of consumers */ - ir_node **consumer; /**< Sorted consumer array (needed for faster access) */ + const ir_node **consumer; /**< Sorted consumer array (needed for faster access) */ plist_t *parent_list; /**< List of parents */ plist_t *pkiller_list; /**< List of potential killers */ plist_t *descendant_list; /**< List of descendants */ - ir_node **descendants; /**< Sorted descendant array (needed for faster access) */ + const ir_node **descendants; /**< Sorted descendant array (needed for faster access) */ - ir_node *killer; /**< The selected unique killer */ - ir_node *irn; /**< The corresponding firm node to this rss_irn */ + const ir_node *killer; /**< The selected unique killer */ + const ir_node *irn; /**< The corresponding firm node to this rss_irn */ chain_t *chain; /**< The chain, this node is associated to */ @@ -296,11 +296,11 @@ static int bsearch_for_index(int key, int *arr, size_t len, int force) { return -1; } -static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack *obst) { +static const ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack *obst) { plist_element_t *el; - int i = 0; - int len = plist_count(irn_list); - ir_node **arr = NEW_ARR_D(ir_node *, obst, len); + int i = 0; + int len = plist_count(irn_list); + const ir_node **arr = (const ir_node **) NEW_ARR_D(ir_node *, obst, len); /* copy the list into the array */ foreach_plist(irn_list, el) { @@ -579,7 +579,7 @@ 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, ir_node *irn, void *old) { +static void *init_rss_irn(ir_phase *ph, const ir_node *irn, void *old) { rss_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0])); res->descendant_list = plist_obstack_new(phase_obst(ph)); @@ -771,7 +771,7 @@ static void collect_node_info(rss_t *rss, ir_node *irn) { */ static int is_potential_killer(rss_t *rss, rss_irn_t *v, rss_irn_t *u) { plist_t *list; - ir_node **arr; + const ir_node **arr; plist_element_t *el; (void) rss; @@ -1243,29 +1243,29 @@ static void compute_killing_function(rss_t *rss) { /** * Adds the edge src -> tgt to the dvg. Checks if reverse edge is already there (asserts). */ -static INLINE void add_dvg_edge(rss_t *rss, dvg_t *dvg, ir_node *src, ir_node *tgt, int have_source) { +static INLINE void add_dvg_edge(rss_t *rss, dvg_t *dvg, const ir_node *src, const ir_node *tgt, int have_source) { rss_edge_t *dvg_edge; rss_edge_t key; if (! have_source) - ir_nodeset_insert(&dvg->nodes, src); + ir_nodeset_insert(&dvg->nodes, (ir_node *) src); else assert(ir_nodeset_contains(&dvg->nodes, src) && "Wrong assumption"); - ir_nodeset_insert(&dvg->nodes, tgt); + ir_nodeset_insert(&dvg->nodes, (ir_node *) tgt); - key.src = tgt; - key.tgt = src; + key.src = (ir_node *) tgt; + key.tgt = (ir_node *) src; assert(pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key)) == NULL && "DVG must be acyclic!"); - key.src = src; - key.tgt = tgt; + key.src = (ir_node *) src; + key.tgt = (ir_node *) tgt; if (NULL != pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) { /* add the edge to the DVG */ dvg_edge = obstack_alloc(phase_obst(&rss->ph), sizeof(*dvg_edge)); - dvg_edge->src = src; - dvg_edge->tgt = tgt; + dvg_edge->src = (ir_node *) src; + dvg_edge->tgt = (ir_node *) tgt; dvg_edge->next = NULL; DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", src, tgt)); @@ -1660,7 +1660,7 @@ static ir_nodeset_t *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int itera if (pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) { /* v[j] is descendant of u -> remove u and break */ - ir_nodeset_insert(temp, u->irn); + ir_nodeset_insert(temp, (ir_node *) u->irn); ir_nodeset_remove(values, u->irn); DBG((rss->dbg, LEVEL_3, "\t\t\tremoving %+F from values, adding it to temp\n", u->irn)); diff --git a/ir/be/bespillbelady2.c b/ir/be/bespillbelady2.c index 3cb41262a..53c6605d0 100644 --- a/ir/be/bespillbelady2.c +++ b/ir/be/bespillbelady2.c @@ -336,7 +336,7 @@ typedef struct _next_use_t { or NULL. */ } next_use_t; -static void *next_use_init(ir_phase *phase, ir_node *irn, void *old) +static void *next_use_init(ir_phase *phase, const ir_node *irn, void *old) { (void) phase; (void) irn; diff --git a/ir/ir/iredges.c b/ir/ir/iredges.c index f9208964a..9f6cccc40 100644 --- a/ir/ir/iredges.c +++ b/ir/ir/iredges.c @@ -589,8 +589,10 @@ static void verify_set_presence(ir_node *irn, void *data) e->present = 1; } else { w->problem_found = 1; +#if 0 ir_fprintf(stderr, "Edge Verifier: edge %+F,%d -> %+F (kind: \"%s\") is missing\n", irn, i, get_n(irn, i, w->kind), get_kind_str(w->kind)); +#endif } } } @@ -610,8 +612,10 @@ static void verify_list_presence(ir_node *irn, void *data) if (w->kind == EDGE_KIND_NORMAL && get_irn_arity(e->src) <= e->pos) { w->problem_found = 1; +#if 0 ir_fprintf(stderr, "Edge Verifier: edge(%ld) %+F -> %+F recorded at src position %d, but src has arity %d\n", edge_get_id(e), e->src, irn, e->pos, get_irn_arity(e->src)); +#endif continue; } @@ -619,8 +623,10 @@ static void verify_list_presence(ir_node *irn, void *data) if (irn != tgt) { w->problem_found = 1; +#if 0 ir_fprintf(stderr, "Edge Verifier: edge(%ld) %+F,%d (kind \"%s\") is no out edge of %+F but of %+F\n", edge_get_id(e), e->src, e->pos, get_kind_str(w->kind), irn, tgt); +#endif } } } diff --git a/ir/ir/irop.c b/ir/ir/irop.c index 410134333..d11935729 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -290,7 +290,7 @@ init_op(void) op_Start = new_ir_op(iro_Start, "Start", op_pin_state_pinned, X, oparity_zero, -1, 0, NULL); op_End = new_ir_op(iro_End, "End", op_pin_state_pinned, X, oparity_dynamic, -1, 0, NULL); op_Jmp = new_ir_op(iro_Jmp, "Jmp", op_pin_state_pinned, X, oparity_zero, -1, 0, NULL); - op_IJmp = new_ir_op(iro_IJmp, "IJmp", op_pin_state_pinned, X|K, oparity_unary, -1, 0, NULL); + op_IJmp = new_ir_op(iro_IJmp, "IJmp", op_pin_state_pinned, X|Y|K, oparity_unary, -1, 0, NULL); op_Cond = new_ir_op(iro_Cond, "Cond", op_pin_state_pinned, X|Y, oparity_any, -1, sizeof(cond_attr), NULL); op_Return = new_ir_op(iro_Return, "Return", op_pin_state_pinned, X, oparity_variable, -1, 0, NULL); diff --git a/ir/ir/irphase.c b/ir/ir/irphase.c index f041a4747..0f5b9fa7a 100644 --- a/ir/ir/irphase.c +++ b/ir/ir/irphase.c @@ -31,24 +31,62 @@ #endif #include "array.h" +#include "util.h" #include "irnode_t.h" +#include "irgraph_t.h" #include "irphase_t.h" -ir_phase *phase_init(ir_phase *ph, const char *name, ir_graph *irg, unsigned growth_factor, phase_irn_data_init_t *data_init, void *priv) +void *phase_irn_init_default(ir_phase *ph, const ir_node *irn, void *old) { - assert(growth_factor >= 256 && "growth factor must greater or equal to 256/256"); - assert(data_init && "You must provide a data constructor"); + (void) ph; + (void) irn; + (void) old; + return NULL; +} + +ir_phase *init_irg_phase(ir_graph *irg, ir_phase_id id, size_t size, phase_irn_init *data_init) +{ + ir_phase *ph; + + size = MAX(sizeof(*ph), size); + assert(id != PHASE_NOT_IRG_MANAGED && id < PHASE_LAST); + assert(irg->phases[id] == NULL && "you cannot overwrite another irg managed phase"); + + ph = xmalloc(size); + memset(ph, 0, size); + obstack_init(&ph->obst); + ph->id = id; + ph->growth_factor = PHASE_DEFAULT_GROWTH; + ph->data_init = data_init; + ph->irg = irg; + ph->n_data_ptr = 0; + ph->data_ptr = NULL; + + irg->phases[id] = ph; + + return ph; +} +void free_irg_phase(ir_graph *irg, ir_phase_id id) +{ + ir_phase *ph = get_irg_phase(irg, id); + phase_free(ph); + xfree(ph); + irg->phases[id] = NULL; +} + +ir_phase *phase_init(ir_phase *ph, const char *name, ir_graph *irg, unsigned growth_factor, phase_irn_init *data_init, void *priv) +{ obstack_init(&ph->obst); - ph->name = name; + (void) name; + ph->id = PHASE_NOT_IRG_MANAGED; ph->growth_factor = growth_factor; ph->data_init = data_init; ph->irg = irg; ph->n_data_ptr = 0; ph->data_ptr = NULL; ph->priv = priv; - return ph; } diff --git a/ir/ir/irphase_t.h b/ir/ir/irphase_t.h index f16135c51..2df6f34f8 100644 --- a/ir/ir/irphase_t.h +++ b/ir/ir/irphase_t.h @@ -30,6 +30,40 @@ #include "obst.h" #include "irgraph_t.h" #include "irtools.h" +#include "irphases_t.h" + +struct _ir_phase_info { + ir_phase_id id; + const char buf[128]; +}; + +typedef struct _ir_phase_info ir_phase_info; + +typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn, void *old); + +/** + * A default node initializer. + * It does nothing and returns NULL. + */ +extern phase_irn_init phase_irn_init_default; + +/** + * A phase object. + */ +struct _ir_phase { + struct obstack obst; /**< The obstack where the irn phase data will be stored on. */ + ir_phase_id id; /**< The phase ID. */ + const char *name; /**< The name of the phase. */ + ir_graph *irg; /**< The irg this phase will we applied to. */ + unsigned growth_factor; /**< The factor to leave room for additional nodes. 256 means 1.0. */ + void *priv; /**< Some pointer private to the user of the phase. */ + size_t n_data_ptr; /**< The length of the data_ptr array. */ + void **data_ptr; /**< Map node indexes to irn data on the obstack. */ + phase_irn_init *data_init; /**< A callback that is called to initialize newly created node data. */ +}; + +#define PHASE_DEFAULT_GROWTH (256) + /** * For statistics: A type containing statistic data of a phase object. @@ -49,40 +83,6 @@ typedef struct { */ phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat); -/** - * The type of a phase data init function. This callback is called to - * (re-) initialize the phase data for each new node. - * - * @param phase The phase. - * @param irn The node for which the phase data is (re-) initialized - * @param old The old phase data for this node. - * - * @return The new (or reinitialized) phase data for this node. - * - * If newly node data is allocated, old is equal to NULL, else points to the old data. - */ -typedef void *(phase_irn_data_init_t)(ir_phase *phase, ir_node *irn, void *old); - -/** - * The default grow factor. - * The node => data map does not speculatively allocate more slots. - */ -#define PHASE_DEFAULT_GROWTH (256) - -/** - * A phase object. - */ -struct _ir_phase { - struct obstack obst; /**< The obstack where the irn phase data will be stored on. */ - const char *name; /**< The name of the phase. */ - ir_graph *irg; /**< The irg this phase will we applied to. */ - unsigned growth_factor; /**< The factor to leave room for additional nodes. 256 means 1.0. */ - void *priv; /**< Some pointer private to the user of the phase. */ - size_t n_data_ptr; /**< The length of the data_ptr array. */ - void **data_ptr; /**< Map node indexes to irn data on the obstack. */ - phase_irn_data_init_t *data_init; /**< A callback that is called to initialize newly created node data. */ -}; - /** * Initialize a phase object. * @@ -96,7 +96,25 @@ struct _ir_phase { * @param priv Some private pointer which is kept in the phase and can be retrieved with phase_get_private(). * @return A new phase object. */ -ir_phase *phase_init(ir_phase *ph, const char *name, ir_graph *irg, unsigned growth_factor, phase_irn_data_init_t *data_init, void *priv); +ir_phase *phase_init(ir_phase *ph, const char *name, ir_graph *irg, unsigned growth_factor, phase_irn_init *data_init, void *priv); + +/** + * Init an irg managed phase. + * + * The first sizeof(ir_phase) bytes will be considered to be a phase object; + * they will be properly initialized. The remaining bytes are at the user's disposal. + * The returned phase object will be inserted in the phase slot of the @p irg designated by the phase ID (@p id). + * Note that you cannot allocate phases with an ID PHASE_NOT_IRG_MANAGED. + * + * @param ph The memory of the phase to initialize. + * @param irg The irg. + * @param id The ID of the irg-managed phase (see irphaselist.h). + * @param data_init The node data initialization function. + * @return The allocated phase object. + */ +ir_phase *init_irg_phase(ir_graph *irg, ir_phase_id id, size_t size, phase_irn_init *data_init); + +void free_irg_phase(ir_graph *irg, ir_phase_id id); /** * Free the phase and all node data associated with it. @@ -226,6 +244,32 @@ ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start); */ #define phase_set_irn_data(phase, irn, data) _phase_set_irn_data((phase), (irn), (data)) +/** + * Get the irg-managed phase for a givedn phase ID. + * @param irg The irg. + * @param id The ID. + * @return The corresponding phase, or NULL if there is none. + */ +#define get_irg_phase(irg, id) _get_irg_phase((irg), (id)) + +/** + * Get the information a phase holds about a node. + * @param irn The node. + * @param id The ID of the phase. + */ +#define get_irn_phase_info(irn, id) _get_phase_irn_info((irn), (id)) + +/** + * Get or set information a phase holds about a node. + * If the given phase does not hold information of the node, + * the information structure will be created, initialized (see the data_init function of ir_phase), and returned. + * @param irn The node. + * @param id The ID of the phase. + */ +#define get_or_set_irn_phase_info(irn, id) _get_or_set_irn_phase_info((irn), (id)) + +#define set_irn_phase_info(irn, id) _set_irn_phase_info((irn), (id)) + /** * This is private and only here for performance reasons. */ @@ -288,7 +332,7 @@ static INLINE void *_phase_set_irn_data(ir_phase *ph, const ir_node *irn, void * } -static INLINE void *_phase_get_or_set_irn_data(ir_phase *ph, ir_node *irn) +static INLINE void *_phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn) { unsigned idx = get_irn_idx(irn); void *res; @@ -300,7 +344,7 @@ static INLINE void *_phase_get_or_set_irn_data(ir_phase *ph, ir_node *irn) /* If there has no irn data allocated yet, do that now. */ if(!res) { - phase_irn_data_init_t *data_init = ph->data_init; + phase_irn_init *data_init = ph->data_init; /* call the node data structure allocator/constructor. */ res = ph->data_ptr[idx] = data_init(ph, irn, NULL); @@ -309,4 +353,34 @@ static INLINE void *_phase_get_or_set_irn_data(ir_phase *ph, ir_node *irn) return res; } +static INLINE ir_phase *_get_irg_phase(const ir_graph *irg, ir_phase_id id) +{ + return irg->phases[id]; +} + +static INLINE void *_get_irn_phase_info(const ir_node *irn, ir_phase_id id) +{ + const ir_graph *irg = get_irn_irg(irn); + const ir_phase *ph = get_irg_phase(irg, id); + assert(ph && "phase info has to be computed"); + return _phase_get_irn_data(ph, irn); +} + +static INLINE void *_get_or_set_irn_phase_info(const ir_node *irn, ir_phase_id id) +{ + const ir_graph *irg = get_irn_irg(irn); + ir_phase *ph = get_irg_phase(irg, id); + assert(ph && "phase info has to be computed"); + return _phase_get_or_set_irn_data(ph, irn); +} + +static INLINE void *_set_irn_phase_info(const ir_node *irn, ir_phase_id id, void *data) +{ + const ir_graph *irg = get_irn_irg(irn); + ir_phase *ph = get_irg_phase(irg, id); + assert(ph && "phase info has to be computed"); + return _phase_set_irn_data(ph, irn, data); +} + + #endif diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 22ccfa5d9..461300a01 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -38,11 +38,14 @@ #include "irmemory.h" #include "callgraph.h" #include "field_temperature.h" +#include "irphases_t.h" #include "pset.h" #include "set.h" #include "list.h" +struct ir_phase; + /** The type of an ir_op. */ struct ir_op { unsigned code; /**< The unique opcode of the op. */ @@ -479,6 +482,7 @@ struct ir_graph { ir_node **idx_irn_map; /**< Array mapping node indexes to nodes. */ int index; /**< a unique number for each graph */ + ir_phase *phases[PHASE_LAST]; /**< Phase information. */ #ifdef DEBUG_libfirm int n_outs; /**< Size wasted for outs */ long graph_nr; /**< a unique graph number for each @@ -548,5 +552,4 @@ struct ir_prog { #endif }; - #endif diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index c5892e3cf..055b6be11 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -1686,7 +1686,7 @@ static void do_dfs(ir_graph *irg, loop_env *env) { /** * Initialize new phase data. We do this always explicit, so return NULL here */ -static void *init_loop_data(ir_phase *ph, ir_node *irn, void *data) { +static void *init_loop_data(ir_phase *ph, const ir_node *irn, void *data) { (void)ph; (void)irn; (void)data; diff --git a/ir/stat/statev.h b/ir/stat/statev.h index 64c3fa47f..f888781f8 100644 --- a/ir/stat/statev.h +++ b/ir/stat/statev.h @@ -124,7 +124,7 @@ static INLINE __attribute__((unused)) void stat_ev_tim_pop(const char *name) { #define stat_ev_ctx_push(key) stat_ev_ctx_push_fmt((key), "X", NULL) #define stat_ev_dbl(name, val) stat_ev_emit((name), (val)) -#define stat_ev_int(name, val) stat_ev_dbl((name), (double)(val)) +#define stat_ev_int(name, val) stat_ev_dbl((name), (double) (val)) #define stat_ev(name) stat_ev_emit((name), 0.0) #define stat_ev_cnt_decl(var) int stat_ev_cnt_var_ ## var = 0