FIRM_API int heights_reachable_in_block(ir_heights_t *h, const ir_node *n,
const ir_node *m);
-/**
- * Recompute the height information.
- * This can be used to recompute the height information if the graph has changed since the last computation.
- * @param h The heights object.
- */
-FIRM_API void heights_recompute(ir_heights_t *h);
-
/**
* Recompute the height information for a certain block.
* This can be used to recompute the height information of a block.
/** VRP information */
typedef struct {
- int valid; /**< This node has valid vrp information */
- ir_tarval *bits_set; /**< The bits which, by analysis, are definitely set.
- 0: may be not set, 1: definitely set*/
+ ir_tarval *bits_set; /**< The bits which, by analysis, are
+ definitely set:
+ 0: may be not set, 1: definitely set */
ir_tarval *bits_not_set; /**< The bits which by analysis are definitely
- not set, 1 for may be set, 0: definitely not set */
+ not set:
+ 1 for may be set, 0: definitely not set */
enum range_types range_type; /**< The range represented by range_top, range_bottom */
ir_tarval *range_bottom;
ir_tarval *range_top;
*/
FIRM_API void set_vrp_data(ir_graph *irg);
+/**
+ * free vrp infos in an irg
+ */
+FIRM_API void free_vrp_data(ir_graph *irg);
+
/**
* Test, if the two nodes can be compared with their vrp information
*
/*
* Return the vrp data for this node
+ * Note: only allowed for nodes with an integer mode!
*
* @param n: the node for which to return the vrp information
- *
* @return a pointer to the vrp data or NULL if there is none
*/
FIRM_API vrp_attr *vrp_get_info(const ir_node *n);
#include "irdump.h"
#include "irgwalk.h"
#include "irtools.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
#include "iredges_t.h"
struct ir_heights_t {
- ir_phase phase;
- unsigned visited;
- void *dump_handle;
+ ir_nodemap data;
+ unsigned visited;
+ void *dump_handle;
+ struct obstack obst;
};
typedef struct {
unsigned visited;
} irn_height_t;
-static void *irn_height_init(ir_phase *phase, const ir_node *node)
+static irn_height_t *maybe_get_height_data(const ir_heights_t *heights,
+ const ir_node *node)
{
- irn_height_t *h = (irn_height_t*) phase_alloc(phase, sizeof(*h));
- (void) node;
- memset(h, 0, sizeof(*h));
- return h;
+ irn_height_t *height = (irn_height_t*)ir_nodemap_get(&heights->data, node);
+ return height;
}
-static void *irn_height_reinit(ir_phase *phase, const ir_node *node,
- void *old_data)
+static irn_height_t *get_height_data(ir_heights_t *heights, const ir_node *node)
{
- irn_height_t *h = (irn_height_t*) old_data;
- (void) node;
- (void) phase;
- memset(h, 0, sizeof(*h));
- return h;
+ irn_height_t *height = (irn_height_t*)ir_nodemap_get(&heights->data, node);
+ if (height == NULL) {
+ height = obstack_alloc(&heights->obst, sizeof(*height));
+ memset(height, 0, sizeof(*height));
+ ir_nodemap_insert(&heights->data, node, height);
+ }
+ return height;
}
static void height_dump_cb(void *data, FILE *f, const ir_node *irn)
{
- ir_heights_t *heights = (ir_heights_t*) data;
- irn_height_t *h = (irn_height_t*) phase_get_irn_data(&heights->phase, irn);
-
- if (h)
+ const ir_heights_t *heights = (const ir_heights_t*) data;
+ const irn_height_t *h = maybe_get_height_data(heights, irn);
+ if (h != NULL)
fprintf(f, "height: %u\n", h->height);
}
* @param tgt The node we try to reach.
* @return 1, one of tgt can be reached from curr, 0 else.
*/
-static bool search(const ir_heights_t *h, const ir_node *curr,
- const ir_node *tgt)
+static bool search(ir_heights_t *h, const ir_node *curr, const ir_node *tgt)
{
irn_height_t *h_curr;
irn_height_t *h_tgt;
return false;
/* Check, if we have already been here. Coming more often won't help :-) */
- h_curr = (irn_height_t*) phase_get_irn_data(&h->phase, curr);
+ h_curr = get_height_data(h, curr);
if (h_curr->visited >= h->visited)
return false;
/* If we are too deep into the DAG we won't find the target either. */
- h_tgt = (irn_height_t*) phase_get_irn_data(&h->phase, tgt);
+ h_tgt = get_height_data(h, tgt);
if (h_curr->height > h_tgt->height)
return false;
const ir_node *m)
{
int res = 0;
- irn_height_t *hn = (irn_height_t*) phase_get_irn_data(&h->phase, n);
- irn_height_t *hm = (irn_height_t*) phase_get_irn_data(&h->phase, m);
+ irn_height_t *hn = get_height_data(h, n);
+ irn_height_t *hm = get_height_data(h, m);
assert(get_nodes_block(n) == get_nodes_block(m));
assert(hn != NULL && hm != NULL);
*/
static unsigned compute_height(ir_heights_t *h, ir_node *irn, const ir_node *bl)
{
- irn_height_t *ih = (irn_height_t*) phase_get_or_set_irn_data(&h->phase, irn);
+ irn_height_t *ih = get_height_data(h, irn);
const ir_edge_t *edge;
unsigned get_irn_height(const ir_heights_t *heights, const ir_node *irn)
{
- const irn_height_t *h = (irn_height_t*) phase_get_irn_data(&heights->phase, irn);
- assert(h && "No height information for node");
- return h->height;
+ const irn_height_t *height = maybe_get_height_data(heights, irn);
+ assert(height != NULL && "No height information for node");
+ return height->height;
}
unsigned heights_recompute_block(ir_heights_t *h, ir_node *block)
{
+ ir_graph *irg = get_irn_irg(block);
const ir_edge_t *edge;
- edges_assure(phase_get_irg(&h->phase));
+ edges_assure(irg);
/* 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 = (irn_height_t*) phase_get_irn_data(&h->phase, irn);
+ irn_height_t *ih = get_height_data(h, irn);
memset(ih, 0, sizeof(*ih));
}
return compute_heights_in_block(block, h);
}
-void heights_recompute(ir_heights_t *h)
-{
- 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(irg, compute_heights_in_block_walker, NULL, h);
-}
-
ir_heights_t *heights_new(ir_graph *irg)
{
ir_heights_t *res = XMALLOC(ir_heights_t);
- phase_init(&res->phase, irg, irn_height_init);
+ ir_nodemap_init(&res->data, irg);
+ obstack_init(&res->obst);
res->dump_handle = dump_add_node_info_callback(height_dump_cb, res);
- heights_recompute(res);
+
+ edges_assure(irg);
+ irg_block_walk_graph(irg, compute_heights_in_block_walker, NULL, res);
return res;
}
void heights_free(ir_heights_t *h)
{
- phase_deinit(&h->phase);
dump_remove_node_info_callback(h->dump_handle);
+ obstack_free(&h->obst, NULL);
+ ir_nodemap_destroy(&h->data);
xfree(h);
}
#include "irgraph_t.h"
#include "irnode_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
#include "iredges_t.h"
#include "irprintf.h"
in the reduced graph. */
} bl_info_t;
-#define get_block_info(lv, bl) ((bl_info_t *) phase_get_irn_data(&(lv)->ph, bl))
-
struct lv_chk_t {
- ir_phase ph;
- const dfs_t *dfs;
- int n_blocks;
- bitset_t *back_edge_src;
- bitset_t *back_edge_tgt;
- bl_info_t **map;
+ ir_nodemap block_infos;
+ struct obstack obst;
+ const dfs_t *dfs;
+ int n_blocks;
+ bitset_t *back_edge_src;
+ bitset_t *back_edge_tgt;
+ bl_info_t **map;
DEBUG_ONLY(firm_dbg_module_t *dbg;)
};
-static void *init_block_data(ir_phase *ph, const ir_node *irn)
+static bl_info_t *get_block_info(lv_chk_t *lv, const ir_node *block)
{
- lv_chk_t *lv = firm_container_of(ph, lv_chk_t, ph);
- bl_info_t *bi = (bl_info_t*) phase_alloc(ph, sizeof(bi[0]));
-
- bi->id = get_Block_dom_tree_pre_num(irn);
- bi->block = irn;
- 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;
- return bi;
+ bl_info_t *info = ir_nodemap_get(&lv->block_infos, block);
+ if (info == NULL) {
+ info = obstack_alloc(&lv->obst, sizeof(*info));
+ info->id = get_Block_dom_tree_pre_num(block);
+ info->block = block;
+ info->red_reachable = bitset_obstack_alloc(&lv->obst, lv->n_blocks);
+ info->be_tgt_reach = bitset_obstack_alloc(&lv->obst, lv->n_blocks);
+ info->be_tgt_calc = 0;
+ ir_nodemap_insert(&lv->block_infos, block, info);
+ }
+ return info;
}
/**
lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
{
lv_chk_t *res = XMALLOC(lv_chk_t);
- struct obstack *obst;
int i;
assure_doms(irg);
stat_ev_tim_push();
- phase_init(&res->ph, irg, init_block_data);
- obst = phase_obst(&res->ph);
+ ir_nodemap_init(&res->block_infos, irg);
+ obstack_init(&res->obst);
FIRM_DBG_REGISTER(res->dbg, "ir.ana.lvchk");
res->dfs = dfs;
res->n_blocks = dfs_get_n_nodes(res->dfs);
- res->back_edge_src = bitset_obstack_alloc(obst, res->n_blocks);
- res->back_edge_tgt = bitset_obstack_alloc(obst, res->n_blocks);
- res->map = OALLOCNZ(obst, bl_info_t*, res->n_blocks);
+ res->back_edge_src = bitset_obstack_alloc(&res->obst, res->n_blocks);
+ res->back_edge_tgt = bitset_obstack_alloc(&res->obst, res->n_blocks);
+ res->map = OALLOCNZ(&res->obst, bl_info_t*, res->n_blocks);
/* fill the map which maps pre_num to block infos */
for (i = res->n_blocks - 1; i >= 0; --i) {
ir_node *irn = (ir_node *) dfs_get_pre_num_node(res->dfs, i);
- bl_info_t *bi = (bl_info_t*) phase_get_or_set_irn_data(&res->ph, irn);
+ bl_info_t *bi = get_block_info(res, irn);
assert(bi->id < res->n_blocks);
assert(res->map[bi->id] == NULL);
res->map[bi->id] = bi;
void lv_chk_free(lv_chk_t *lv)
{
- phase_deinit(&lv->ph);
+ obstack_free(&lv->obst, NULL);
+ ir_nodemap_destroy(&lv->block_infos);
xfree(lv);
}
* @param var The node to check for.
* @return A bitmask of lv_chk_state_XXX fields.
*/
-unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var)
+unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *var)
{
int res = 0;
ir_node *def_bl;
* @param irn The node to check for.
* @return A bitmask of <code>lv_chk_state_t</code>.
*/
-extern unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *irn);
+extern unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *irn);
#define lv_chk_bl_in(lv, bl, irn) ((lv_chk_bl_xxx((lv), (bl), (irn)) & lv_chk_state_in) != 0)
#define lv_chk_bl_end(lv, bl, irn) ((lv_chk_bl_xxx((lv), (bl), (irn)) & lv_chk_state_end) != 0)
#include "tv.h"
#include "irop.h"
#include "pdeq.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
#include "bitset.h"
#include "debug.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
typedef struct vrp_env_t {
- waitq *workqueue;
- bitset_t *visited;
+ waitq *workqueue;
+ bitset_t *visited;
+ ir_vrp_info *info;
} vrp_env_t;
-static vrp_attr *get_vrp_attr(const ir_node *node)
+static vrp_attr *vrp_get_or_set_info(ir_vrp_info *info, const ir_node *node)
{
- return (vrp_attr*) get_or_set_irn_phase_info(node, PHASE_VRP);
+ vrp_attr *attr = ir_nodemap_get(&info->infos, node);
+ if (attr == NULL) {
+ ir_mode *mode = get_irn_mode(node);
+ assert(mode_is_int(mode));
+
+ attr = obstack_alloc(&info->obst, sizeof(*attr));
+ memset(attr, 0, sizeof(*attr));
+ attr->range_type = VRP_UNDEFINED;
+ attr->bits_set = get_mode_null(mode);
+ attr->bits_not_set = get_mode_all_one(mode);
+ attr->range_bottom = get_tarval_top();
+ attr->range_top = get_tarval_top();
+
+ ir_nodemap_insert(&info->infos, node, attr);
+ }
+ return attr;
+}
+
+vrp_attr *vrp_get_info(const ir_node *node)
+{
+ ir_graph *irg = get_irn_irg(node);
+ if (irg->vrp.infos.data == NULL)
+ return NULL;
+ return (vrp_attr*) ir_nodemap_get(&irg->vrp.infos, node);
}
-static int vrp_update_node(ir_node *node)
+static int vrp_update_node(ir_vrp_info *info, ir_node *node)
{
ir_tarval *new_bits_set = get_tarval_bad();
ir_tarval *new_bits_not_set = get_tarval_bad();
return 0; /* we don't optimize for non-int-nodes*/
}
- vrp = get_vrp_attr(node);
+ vrp = vrp_get_or_set_info(info, node);
/* TODO: Check if all predecessors have valid VRP information*/
left = get_And_left(node);
right = get_And_right(node);
- vrp_left = get_vrp_attr(left);
- vrp_right = get_vrp_attr(right);
+ vrp_left = vrp_get_or_set_info(info, left);
+ vrp_right = vrp_get_or_set_info(info, right);
new_bits_set = tarval_and(vrp_left->bits_set, vrp_right->bits_set);
new_bits_not_set = tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set);
int overflow_top, overflow_bottom;
ir_tarval *new_top, *new_bottom;
const vrp_attr *vrp_left, *vrp_right;
- vrp_left = get_vrp_attr(get_Add_left(node));
- vrp_right = get_vrp_attr(get_Add_right(node));
+ vrp_left = vrp_get_or_set_info(info, get_Add_left(node));
+ vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
}
case iro_Sub: {
+ ir_node *left = get_Sub_left(node);
+ ir_node *right = get_Sub_right(node);
int overflow_top, overflow_bottom;
ir_tarval *new_top, *new_bottom;
const vrp_attr *vrp_left, *vrp_right;
- vrp_left = get_vrp_attr(get_Sub_left(node));
- vrp_right = get_vrp_attr(get_Sub_right(node));
+
+ if (!mode_is_int(get_irn_mode(left)))
+ return 0;
+
+ vrp_left = vrp_get_or_set_info(info, left);
+ vrp_right = vrp_get_or_set_info(info, right);
if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
case iro_Or: {
const vrp_attr *vrp_left, *vrp_right;
- vrp_left = get_vrp_attr(get_Or_left(node));
- vrp_right = get_vrp_attr(get_Or_right(node));
+ vrp_left = vrp_get_or_set_info(info, get_Or_left(node));
+ vrp_right = vrp_get_or_set_info(info, get_Or_right(node));
new_bits_set = tarval_or(vrp_left->bits_set, vrp_right->bits_set);
new_bits_not_set = tarval_or(vrp_left->bits_not_set, vrp_right->bits_not_set);
const vrp_attr *vrp_left;
const ir_node *right = get_Rotl_right(node);
- vrp_left = get_vrp_attr(get_Rotl_left(node));
+ vrp_left = vrp_get_or_set_info(info, get_Rotl_left(node));
/* We can only compute this if the right value is a constant*/
if (is_Const(right)) {
case iro_Shl: {
const vrp_attr *vrp_left;
const ir_node *right = get_Shl_right(node);
- vrp_left = get_vrp_attr(get_Shl_left(node));
+ vrp_left = vrp_get_or_set_info(info, get_Shl_left(node));
/* We can only compute this if the right value is a constant*/
if (is_Const(right)) {
const vrp_attr *vrp_left;
const ir_node *right = get_Shr_right(node);
- vrp_left = get_vrp_attr(get_Shr_left(node));
+ vrp_left = vrp_get_or_set_info(info, get_Shr_left(node));
/* We can only compute this if the right value is a constant*/
if (is_Const(right)) {
const vrp_attr *vrp_left;
const ir_node *right = get_Shrs_right(node);
- vrp_left = get_vrp_attr(get_Shrs_left(node));
+ vrp_left = vrp_get_or_set_info(info, get_Shrs_left(node));
/* We can only compute this if the right value is a constant*/
if (is_Const(right)) {
case iro_Eor: {
const vrp_attr *vrp_left, *vrp_right;
- vrp_left = get_vrp_attr(get_Eor_left(node));
- vrp_right = get_vrp_attr(get_Eor_right(node));
+ vrp_left = vrp_get_or_set_info(info, get_Eor_left(node));
+ vrp_right = vrp_get_or_set_info(info, get_Eor_right(node));
new_bits_set = tarval_or(
tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set)),
}
case iro_Id: {
- const vrp_attr *vrp_pred = get_vrp_attr(get_Id_pred(node));
+ const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Id_pred(node));
new_bits_set = vrp_pred->bits_set;
new_bits_not_set = vrp_pred->bits_not_set;
new_range_top = vrp_pred->range_top;
}
case iro_Not: {
- const vrp_attr *vrp_pred = get_vrp_attr(get_Not_op(node));
+ const vrp_attr *vrp_pred = vrp_get_or_set_info(info, get_Not_op(node));
new_bits_set = tarval_not(vrp_pred->bits_not_set);
new_bits_not_set = tarval_not(vrp_pred->bits_set);
break;
case iro_Conv: {
const ir_node *pred = get_Conv_op(node);
ir_mode *old_mode = get_irn_mode(pred);
- const vrp_attr *vrp_pred = get_vrp_attr(pred);
+ const vrp_attr *vrp_pred;
ir_mode *new_mode;
if (!mode_is_int(old_mode))
return 0;
+ vrp_pred = vrp_get_or_set_info(info, pred);
new_mode = get_irn_mode(node);
/* The second and is needed if target type is smaller*/
int i;
const ir_node *pred = get_Phi_pred(node,0);
- const vrp_attr *vrp_pred = get_vrp_attr(pred);
+ const vrp_attr *vrp_pred = vrp_get_or_set_info(info, pred);
new_range_top = vrp_pred->range_top;
new_range_bottom = vrp_pred->range_bottom;
new_range_type = vrp_pred->range_type;
for (i = 1; i < num; i++) {
pred = get_Phi_pred(node, i);
- vrp_pred = get_vrp_attr(pred);
+ vrp_pred = vrp_get_or_set_info(info, pred);
if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
VRP_RANGE) {
relation = tarval_cmp(new_range_top, vrp_pred->range_top);
bitset_set(env->visited, get_irn_idx(n));
- vrp_update_node(n);
+ vrp_update_node(env->info, n);
assure_irg_outs(get_current_ir_graph());
for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
}
}
-static void *vrp_init_node(ir_phase *phase, const ir_node *n)
-{
- ir_mode *mode;
- vrp_attr *vrp;
-
- DBG((dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n)));
- vrp = (vrp_attr*) phase_alloc(phase, sizeof(vrp_attr));
-
- memset(vrp, 0, sizeof(vrp_attr));
- /* Initialize the vrp information to default */
-
- mode = get_irn_mode(n);
-
- vrp->range_type = VRP_UNDEFINED;
-
- /* TODO: We might be able to optimize space usage if we do not allocate
- * vrp space for non-int nodes. (currently caught by vrp_update_node)
- */
- if (mode_is_int(mode)) {
- /* We are assuming that 0 is always represented as this modes null */
- vrp->valid = 1;
- vrp->bits_set = get_mode_null(mode);
- vrp->bits_not_set = get_mode_all_one(mode);
- vrp->range_bottom = get_tarval_top();
- vrp->range_top = get_tarval_top();
- } else {
- vrp->valid = 0;
- vrp->bits_set = get_tarval_bad();
- vrp->bits_not_set = get_tarval_bad();
- vrp->range_bottom = get_tarval_bad();
- vrp->range_top = get_tarval_bad();
- }
-
- /* TODO: We might be able to set better vrp info at this time, if this is
- * a node which is newly created in an already initialized irg
- *
- * maybe just call vrp_update_node and if it returns one, iterate over
- * successors
- */
- return vrp;
-}
-
void set_vrp_data(ir_graph *irg)
{
ir_node *succ, *node;
int i;
vrp_env_t *env;
- ir_phase *phase;
+ ir_vrp_info *info;
+
+ if (irg->vrp.infos.data != NULL)
+ free_vrp_data(irg);
FIRM_DBG_REGISTER(dbg, "ir.ana.vrp");
assure_irg_outs(irg); /* ensure that out edges are consistent*/
- phase = irg_get_phase(irg, PHASE_VRP);
- if (phase == NULL) {
- /* this is our first run */
- phase = new_phase(irg, vrp_init_node);
- irg_register_phase(irg, PHASE_VRP, phase);
- env = (vrp_env_t*) phase_alloc(phase, sizeof(*env));
- phase->priv = env;
- } else {
- env = (vrp_env_t*) phase->priv;
- }
+ ir_nodemap_init(&irg->vrp.infos, irg);
+ obstack_init(&irg->vrp.obst);
+ info = &irg->vrp;
+ env = obstack_alloc(&irg->vrp.obst, sizeof(*env));
env->workqueue = new_waitq();
+ env->info = info;
env->visited = bitset_malloc(get_irg_last_idx(irg));
irg_walk_graph(irg, NULL, vrp_first_pass, env);
while (!waitq_empty(env->workqueue)) {
node = (ir_node*) waitq_get(env->workqueue);
- if (vrp_update_node(node)) {
+ if (vrp_update_node(info, node)) {
/* if something changed, add successors to worklist*/
for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
succ = get_irn_out(node, i);
del_waitq(env->workqueue);
}
+void free_vrp_data(ir_graph *irg)
+{
+ if (irg->vrp.infos.data == NULL)
+ return;
+ obstack_free(&irg->vrp.obst, NULL);
+ ir_nodemap_destroy(&irg->vrp.infos);
+}
+
ir_graph_pass_t *set_vrp_pass(const char *name)
{
return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
{
vrp_attr *vrp_left, *vrp_right;
+ if (!mode_is_int(get_irn_mode(left)))
+ return ir_relation_true;
+
vrp_left = vrp_get_info(left);
vrp_right = vrp_get_info(right);
/* TODO: We can get way more information here*/
return ir_relation_true;
}
-
-vrp_attr *vrp_get_info(const ir_node *node)
-{
- const ir_graph *irg = get_irn_irg(node);
- const ir_phase *phase = irg_get_phase(irg, PHASE_VRP);
- vrp_attr *vrp;
-
- if (phase == NULL) {
- /* phase has not yet been initialized */
- return NULL;
- }
-
- vrp = (vrp_attr*) phase_get_irn_data(phase, node);
- if (vrp && vrp->valid) {
- return vrp;
- }
-
- return NULL;
-}
#include "ircons.h"
#include "iredges.h"
#include "irgwalk.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
+#include "irtools.h"
#include "heights.h"
/**
*/
static void process_ops_in_block(ir_node *block, void *data)
{
- ir_phase *phase = (ir_phase*)data;
- unsigned n;
- unsigned n_nodes;
- ir_node *node;
- ir_node **nodes;
+ ir_nodemap *map = (ir_nodemap*)data;
+ unsigned n;
+ unsigned n_nodes;
+ ir_node *node;
+ ir_node **nodes;
n_nodes = 0;
for (node = (ir_node*)get_irn_link(block); node != NULL;
ir_node *node = nodes[n];
ir_node *pred = nodes[n-1];
- phase_set_irn_data(phase, node, pred);
+ ir_nodemap_insert(map, node, pred);
}
xfree(nodes);
}
struct be_stackorder_t {
- ir_phase *stack_order; /**< a phase to handle stack dependencies. */
+ ir_nodemap stack_order; /**< a phase to handle stack dependencies. */
};
be_stackorder_t *be_collect_stacknodes(ir_graph *irg)
/* collect all potential^stack accessing nodes */
irg_walk_graph(irg, firm_clear_link, link_ops_in_block_walker, NULL);
- assert(env->stack_order == NULL);
- env->stack_order = new_phase(irg, phase_irn_init_default);
+ ir_nodemap_init(&env->stack_order, irg);
/* use heights to create a total order for those nodes: this order is stored
* in the created phase */
heights = heights_new(irg);
- irg_block_walk_graph(irg, NULL, process_ops_in_block, env->stack_order);
+ irg_block_walk_graph(irg, NULL, process_ops_in_block, &env->stack_order);
heights_free(heights);
ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
ir_node *be_get_stack_pred(const be_stackorder_t *env, const ir_node *node)
{
- return (ir_node*)phase_get_irn_data(env->stack_order, node);
+ return (ir_node*)ir_nodemap_get(&env->stack_order, node);
}
void be_free_stackorder(be_stackorder_t *env)
{
- phase_free(env->stack_order);
+ ir_nodemap_destroy(&env->stack_order);
free(env);
}
#include "debug.h"
#include "bitfiddle.h"
-#include "irphase_t.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "irprintf.h"
#include "irtools.h"
+#include "irnodemap.h"
#include "bemodule.h"
#include "beabi.h"
} col_cost_pair_t;
typedef struct {
- ir_phase ph;
+ ir_nodemap map;
+ struct obstack obst;
copy_opt_t *co;
bitset_t *allocatable_regs;
co2_irn_t *touched;
#define FRONT_BASE(ci,col) ((ci)->fronts + col * (ci)->mst_n_childs)
-#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 co2_irn_t *get_co2_irn(co2_t *env, const ir_node *node)
+{
+ co2_irn_t *ci = ir_nodemap_get(&env->map, node);
+ if (ci == NULL) {
+ ci = OALLOCZ(&env->obst, co2_irn_t);
+
+ INIT_LIST_HEAD(&ci->changed_list);
+ ci->touched_next = env->touched;
+ ci->orig_col = get_irn_col(node);
+ env->touched = ci;
+ ci->irn = node;
+ ci->aff = NULL;
+
+ ir_nodemap_insert(&env->map, node, ci);
+ }
+ return ci;
+}
-static void *co2_irn_init(ir_phase *ph, const ir_node *irn)
+static co2_cloud_irn_t *get_co2_cloud_irn(co2_t *env, const ir_node *node)
{
- 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 = (co2_irn_t*)phase_alloc(ph, size);
-
- memset(ci, 0, size);
- INIT_LIST_HEAD(&ci->changed_list);
- ci->touched_next = env->touched;
- ci->orig_col = get_irn_col(irn);
- env->touched = ci;
- ci->irn = irn;
- ci->aff = a;
+ co2_cloud_irn_t *ci = ir_nodemap_get(&env->map, node);
+ if (ci == NULL) {
+ ci = OALLOCZ(&env->obst, co2_cloud_irn_t);
- if (a) {
- co2_cloud_irn_t *cci = (co2_cloud_irn_t *) ci;
- INIT_LIST_HEAD(&cci->cloud_list);
- cci->mst_parent = cci;
- }
+ INIT_LIST_HEAD(&ci->inh.changed_list);
+ ci->inh.touched_next = env->touched;
+ ci->inh.orig_col = get_irn_col(node);
+ env->touched = &ci->inh;
+ ci->inh.irn = node;
+ ci->inh.aff = get_affinity_info(env->co, node);
+ INIT_LIST_HEAD(&ci->cloud_list);
+ ci->mst_parent = ci;
+
+ ir_nodemap_insert(&env->map, node, ci);
+ }
return ci;
}
{
if (ci->adm_cache == NULL) {
const arch_register_req_t *req;
- ci->adm_cache = bitset_obstack_alloc(phase_obst(&env->ph), env->n_regs);
+ ci->adm_cache = bitset_obstack_alloc(&env->obst, env->n_regs);
req = arch_get_irn_register_req(ci->irn);
if (arch_register_req_is(req, limited)) {
static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
{
- co2_cloud_t *cloud = (co2_cloud_t*)phase_alloc(&env->ph, sizeof(cloud[0]));
+ co2_cloud_t *cloud = OALLOC(&env->obst, co2_cloud_t);
co2_cloud_irn_t *ci;
int i;
cloud->freedom = (cloud->n_memb * env->n_regs) / cloud->freedom;
/* Also allocate space for the node sequence and compute that sequence. */
- cloud->seq = (co2_cloud_irn_t**)phase_alloc(&env->ph, cloud->n_memb * sizeof(cloud->seq[0]));
+ cloud->seq = OALLOCN(&env->obst, co2_cloud_irn_t*, cloud->n_memb);
i = 0;
list_for_each_entry(co2_cloud_irn_t, ci, &cloud->members_head, cloud_list) {
co2_t env;
FILE *f;
- phase_init(&env.ph, co->cenv->irg, co2_irn_init);
+ ir_nodemap_init(&env.map, co->irg);
+ obstack_init(&env.obst);
env.touched = NULL;
env.visited = 0;
env.co = co;
}
writeback_colors(&env);
- phase_deinit(&env.ph);
+ obstack_free(&env.obst, NULL);
+ ir_nodemap_destroy(&env.map);
return 0;
}
#include "irnode_t.h"
#include "bitset.h"
#include "raw_bitset.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
#include "pqueue.h"
#include "xmalloc.h"
#include "pdeq.h"
#include "irprintf.h"
#include "irbitset.h"
+#include "irtools.h"
#include "error.h"
#include "list.h"
#include "statev.h"
int n_regs; /**< number of regs in class */
int k; /**< number of non-ignore registers in class */
bitset_t *allocatable_regs; /**< set containing all global ignore registers */
- ir_phase ph; /**< phase object holding data for nodes */
+ ir_nodemap map; /**< phase object holding data for nodes */
+ struct obstack obst;
pqueue_t *chunks; /**< priority queue for chunks */
list_head chunklist; /**< list holding all chunks */
be_ifg_t *ifg; /**< the interference graph */
real_t constr_factor;
} co_mst_irn_t;
+/**
+ * In case there is no phase information for irn, initialize it.
+ */
+static co_mst_irn_t *co_mst_irn_init(co_mst_env_t *env, const ir_node *irn)
+{
+ co_mst_irn_t *res = OALLOC(&env->obst, co_mst_irn_t);
+
+ 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(&env->obst, env->n_regs);
+
+ /* Exclude colors not assignable to the irn */
+ req = arch_get_irn_register_req(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_and(res->adm_colors, env->allocatable_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(&env->obst, neigh);
+ ++len;
+ }
+ }
+ res->int_neighs = (ir_node**)obstack_finish(&env->obst);
+ res->n_neighs = len;
+ return res;
+}
+
static co_mst_irn_t *get_co_mst_irn(co_mst_env_t *env, const ir_node *node)
{
- return (co_mst_irn_t*)phase_get_or_set_irn_data(&env->ph, node);
+ co_mst_irn_t *res = (co_mst_irn_t*)ir_nodemap_get(&env->map, node);
+ if (res == NULL) {
+ res = co_mst_irn_init(env, node);
+ ir_nodemap_insert(&env->map, node, res);
+ }
+ return res;
}
typedef int decide_func_t(const co_mst_irn_t *node, int col);
}
}
-/**
- * In case there is no phase information for irn, initialize it.
- */
-static void *co_mst_irn_init(ir_phase *ph, const ir_node *irn)
-{
- co_mst_irn_t *res = (co_mst_irn_t*)phase_alloc(ph, sizeof(res[0]));
- co_mst_env_t *env = (co_mst_env_t*)ph->priv;
-
- 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_irn_register_req(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_and(res->adm_colors, env->allocatable_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 = (ir_node**)obstack_finish(phase_obst(ph));
- res->n_neighs = len;
- return res;
-}
-
/**
* Check if affinity chunk @p chunk interferes with node @p irn.
*/
ir_node *n;
int i, len;
aff_chunk_t *curr_chunk;
+ size_t pn;
/* at first we create the affinity edge objects */
be_ifg_foreach_node(env->ifg, &nodes_it, n) {
pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
}
- foreach_phase_irn(&env->ph, n) {
- co_mst_irn_t *mirn = get_co_mst_irn(env, n);
+ for (pn = 0; pn < ARR_LEN(env->map.data); ++pn) {
+ co_mst_irn_t *mirn = env->map.data[pn];
+ if (mirn == NULL)
+ continue;
+ if (mirn->chunk != NULL)
+ continue;
- if (mirn->chunk == NULL) {
- /* no chunk is allocated so far, do it now */
- aff_chunk_t *curr_chunk = new_aff_chunk(env);
- aff_chunk_add_node(curr_chunk, mirn);
+ /* no chunk is allocated so far, do it now */
+ aff_chunk_t *curr_chunk = new_aff_chunk(env);
+ aff_chunk_add_node(curr_chunk, mirn);
- aff_chunk_assure_weight(env, curr_chunk);
+ aff_chunk_assure_weight(env, curr_chunk);
- DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
- DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
- DBG((dbg, LEVEL_1, "\n"));
+ DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
+ DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
+ DBG((dbg, LEVEL_1, "\n"));
- pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
- }
+ pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
}
DEL_ARR_F(edges);
bitset_t *allocatable_regs = bitset_alloca(n_regs);
unsigned i, j;
size_t k;
+ size_t pn;
ir_node *irn;
co_mst_env_t mst_env;
stat_ev_tim_push();
/* init phase */
- phase_init(&mst_env.ph, co->irg, co_mst_irn_init);
- phase_set_private(&mst_env.ph, &mst_env);
+ ir_nodemap_init(&mst_env.map, co->irg);
+ obstack_init(&mst_env.obst);
be_put_allocatable_regs(co->cenv->irg, co->cls, allocatable_regs);
k = bitset_popcount(allocatable_regs);
mst_env.ifg = co->cenv->ifg;
INIT_LIST_HEAD(&mst_env.chunklist);
mst_env.chunk_visited = 0;
- mst_env.single_cols = (col_cost_t**)phase_alloc(&mst_env.ph, sizeof(*mst_env.single_cols) * n_regs);
+ mst_env.single_cols = OALLOCN(&mst_env.obst, col_cost_t*, n_regs);
for (i = 0; i < n_regs; ++i) {
- col_cost_t *vec = (col_cost_t*)phase_alloc(&mst_env.ph, sizeof(*vec) * n_regs);
+ col_cost_t *vec = OALLOCN(&mst_env.obst, col_cost_t, n_regs);
mst_env.single_cols[i] = vec;
for (j = 0; j < n_regs; ++j) {
}
/* apply coloring */
- foreach_phase_irn(&mst_env.ph, irn) {
- co_mst_irn_t *mirn;
+ for (pn = 0; pn < ARR_LEN(mst_env.map.data); ++pn) {
+ co_mst_irn_t *mirn = mst_env.map.data[pn];
const arch_register_t *reg;
-
+ if (mirn == NULL)
+ continue;
+ irn = get_idx_irn(co->irg, pn);
if (arch_irn_is_ignore(irn))
continue;
- mirn = get_co_mst_irn(&mst_env, irn);
- // assert(mirn->fixed && "Node should have fixed color");
-
/* skip nodes where color hasn't changed */
if (mirn->init_col == mirn->col)
continue;
/* free allocated memory */
del_pqueue(mst_env.chunks);
- phase_deinit(&mst_env.ph);
+ obstack_free(&mst_env.obst, NULL);
+ ir_nodemap_destroy(&mst_env.map);
stat_ev_tim_pop("heur4_total");
#include "irloop_t.h"
#include "iredges_t.h"
#include "irbitset.h"
-#include "irphase_t.h"
#include "irprintf_t.h"
+#include "irtools.h"
#include "bemodule.h"
#include "bearch.h"
#include "irtools.h"
#include "irbitset.h"
#include "beifg.h"
-#include "irphase_t.h"
#include "error.h"
#include "xmalloc.h"
#define _BELIVECHK_T_H
#include "irgraph_t.h"
-#include "irphase_t.h"
#include "iredges_t.h"
#include "statev.h"
#include "ircons.h"
#include "iredges_t.h"
-#include "irphase_t.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
ir_node *block);
struct constr_info {
- bool is_definition;
- bool is_use;
- bool already_processed;
+ bool is_definition : 1;
+ bool is_use : 1;
+ bool already_processed : 1;
union {
/* Since we only consider scheduled nodes,
* this points to the real definition (e.g. a Proj). */
/**
* @return Whether the block contains a definition.
*/
-static inline bool has_definition(be_ssa_construction_env_t *env, ir_node *block)
+static bool has_definition(const ir_node *block)
{
- (void)env;
-
return irn_visited(block);
}
+static constr_info *get_or_set_info(be_ssa_construction_env_t *env,
+ const ir_node *node)
+{
+ constr_info *info = ir_nodemap_get(&env->infos, node);
+ if (info == NULL) {
+ info = OALLOCZ(&env->obst, constr_info);
+ ir_nodemap_insert(&env->infos, node, info);
+ }
+ return info;
+}
+
+static constr_info *get_info(const be_ssa_construction_env_t *env,
+ const ir_node *node)
+{
+ return (constr_info*)ir_nodemap_get(&env->infos, node);
+}
+
/**
* @return Whether the block contains a use.
*/
static inline bool has_use(be_ssa_construction_env_t *env, ir_node *block)
{
- constr_info *info = phase_get_or_set_irn_data(env->phase, block);
-
+ constr_info *info = get_or_set_info(env, block);
return info->is_use;
}
/**
* @return Whether the node is a definition.
*/
-static inline bool is_definition(be_ssa_construction_env_t *env, ir_node *node)
+static bool is_definition(be_ssa_construction_env_t *env, ir_node *node)
{
- constr_info *info = phase_get_irn_data(env->phase, node);
-
- return info && info->is_definition;
+ constr_info *info = get_info(env, node);
+ return info != NULL && info->is_definition;
}
/**
* @return Whether the node is a use.
*/
-static inline bool is_use(const be_ssa_construction_env_t *env, ir_node *node)
+static bool is_use(const be_ssa_construction_env_t *env, ir_node *node)
{
- constr_info *info = phase_get_irn_data(env->phase, node);
-
- return info && info->is_use;
+ constr_info *info = get_info(env, node);
+ return info != NULL && info->is_use;
}
/**
static void introduce_definition(be_ssa_construction_env_t *env, ir_node *def)
{
ir_node *block = get_nodes_block(def);
- ir_phase *phase = env->phase;
- constr_info *def_info = phase_get_or_set_irn_data(phase, def);
+ constr_info *def_info = get_or_set_info(env, def);
ir_node *skip = skip_Proj(def);
- constr_info *skip_info = phase_get_or_set_irn_data(phase, skip);
- constr_info *block_info = phase_get_or_set_irn_data(phase, block);
+ constr_info *skip_info = get_or_set_info(env, skip);
+ constr_info *block_info = get_or_set_info(env, block);
DBG((dbg, LEVEL_2, "\tintroducing definition %+F in %+F\n", def, block));
skip_info->definition = def;
// Set the last definition if we only introduce one definition for the block
- if (has_definition(env, block)) {
+ if (has_definition(block)) {
assert(!block_info->already_processed);
block_info->last_definition = NULL;
- }
- else {
+ } else {
mark_irn_visited(block);
block_info->last_definition = def;
}
static void introduce_use(be_ssa_construction_env_t *env, ir_node *use)
{
ir_node *block = get_nodes_block(use);
- ir_phase *phase = env->phase;
- constr_info *info = phase_get_or_set_irn_data(phase, use);
- constr_info *block_info = phase_get_or_set_irn_data(phase, block);
+ constr_info *info = get_or_set_info(env, use);
+ constr_info *block_info = get_or_set_info(env, block);
DBG((dbg, LEVEL_2, "\tintroducing use %+F in %+F\n", use, block));
* frontier to the block itself.
*/
static void mark_iterated_dominance_frontiers(
- const be_ssa_construction_env_t *env)
+ const be_ssa_construction_env_t *env)
{
stat_ev_cnt_decl(blocks);
DBG((dbg, LEVEL_3, "Dominance Frontier:"));
*/
static void set_operands(be_ssa_construction_env_t *env, ir_node *use, ir_node *def)
{
- constr_info *info = phase_get_irn_data(env->phase, use);
+ constr_info *info = get_info(env, use);
int arity = get_irn_arity(use);
int i;
{
ir_node *node;
ir_node *def = NULL;
- constr_info *block_info = phase_get_or_set_irn_data(env->phase, block);
+ constr_info *block_info = get_or_set_info(env, block);
- assert(has_definition(env, block));
+ assert(has_definition(block));
assert(!block_info->already_processed && "Block already processed");
DBG((dbg, LEVEL_3, "\tprocessing block %+F\n", block));
}
if (is_definition(env, node)) {
- constr_info *info = phase_get_irn_data(env->phase, node);
+ constr_info *info = get_info(env, node);
def = info->definition;
DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
}
static ir_node *search_def_end_of_block(be_ssa_construction_env_t *env,
ir_node *block)
{
- constr_info *block_info = phase_get_or_set_irn_data(env->phase, block);
+ constr_info *block_info = get_or_set_info(env, block);
ir_node *last_definition = block_info->last_definition;
if (last_definition != NULL)
return last_definition;
- if (has_definition(env, block)) {
+ if (has_definition(block)) {
if (has_use(env, block)) {
if (!block_info->already_processed) {
process_block(env, block);
/* Search the last definition of the block. */
sched_foreach_reverse(block, def) {
if (is_definition(env, def)) {
- constr_info *info = phase_get_irn_data(env->phase, def);
+ constr_info *info = get_info(env, def);
def = info->definition;
DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
static void search_def_at_block(be_ssa_construction_env_t *env, ir_node *use)
{
ir_node *block = get_nodes_block(use);
- constr_info *block_info = phase_get_or_set_irn_data(env->phase, block);
+ constr_info *block_info = get_or_set_info(env, block);
if (block_info->already_processed)
return;
- if (has_definition(env, block)) {
+ if (has_definition(block)) {
process_block(env, block);
} else if (Block_block_visited(block)) {
ir_node *phi = insert_dummy_phi(env, block);
}
}
-static void *init_constr_info(ir_phase *phase, const ir_node *node)
-{
- constr_info *info = phase_alloc(phase, sizeof(constr_info));
- (void)node;
-
- info->is_definition = false;
- info->is_use = false;
- info->already_processed = false;
- info->definition = NULL;
-
- return info;
-}
-
void be_ssa_construction_init(be_ssa_construction_env_t *env, ir_graph *irg)
{
ir_node *sb = get_irg_start_block(irg);
env->domfronts = be_get_irg_dom_front(irg);
env->new_phis = NEW_ARR_F(ir_node*, 0);
env->worklist = new_waitq();
- env->phase = new_phase(irg, init_constr_info);
+ ir_nodemap_init(&env->infos, irg);
+ obstack_init(&env->obst);
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED
| IR_RESOURCE_BLOCK_VISITED | IR_RESOURCE_IRN_LINK);
void be_ssa_construction_destroy(be_ssa_construction_env_t *env)
{
stat_ev_int("bessaconstr_phis", ARR_LEN(env->new_phis));
- phase_free(env->phase);
+ obstack_free(&env->obst, NULL);
+ ir_nodemap_destroy(&env->infos);
del_waitq(env->worklist);
DEL_ARR_F(env->new_phis);
block = get_nodes_block(copy);
- if (!has_definition(env, block)) {
+ if (!has_definition(block)) {
waitq_put(env->worklist, block);
}
introduce_definition(env, copy);
ir_node *block = get_nodes_block(copy);
assert(env->mode == get_irn_mode(copy));
- if (!has_definition(env, block)) {
+ if (!has_definition(block)) {
waitq_put(env->worklist, block);
}
introduce_definition(env, copy);
*/
static void fix_phi_arguments(be_ssa_construction_env_t *env, ir_node *phi)
{
- constr_info *info = phase_get_irn_data(env->phase, phi);
+ constr_info *info = get_info(env, phi);
ir_node *block = get_nodes_block(phi);
int i;
int n_preds = get_Block_n_cfgpreds(block);
while (!waitq_empty(env->worklist)) {
ir_node *use = (ir_node *)waitq_get(env->worklist);
- constr_info *info = phase_get_irn_data(env->phase, use);
+ constr_info *info = get_info(env, use);
if (info->already_processed)
continue;
#include "bitset.h"
#include "beirg.h"
#include "pdeq.h"
-#include "irphase.h"
+#include "irnodemap.h"
+#include "obst.h"
typedef struct be_ssa_construction_env_t {
ir_graph *irg;
const ir_nodeset_t *ignore_uses;
ir_node **new_phis;
int iterated_domfront_calculated;
- ir_phase *phase;
+ ir_nodemap infos;
+ struct obstack obst;
} be_ssa_construction_env_t;
/**
irg->obst = new_obst;
irg->last_node_idx = 0;
- /* invalidate phase info as (at least vrp info) is used inside the
- * equivalent/compute_value functions and might replace our newly
- * created nodes with middleend nodes */
- irg_invalidate_phases(irg);
+ free_vrp_data(irg);
/* create new value table for CSE */
new_identities(irg);
#include "iredges_t.h"
#include "type_t.h"
#include "irmemory.h"
-#include "irphase.h"
#define INITIAL_IDX_IRN_MAP_SIZE 1024
return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
}
-void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase)
-{
- assert(id <= PHASE_LAST);
- assert(irg->phases[id] == NULL);
- irg->phases[id] = phase;
-}
-
-void irg_invalidate_phases(ir_graph *irg)
-{
- int p;
- for (p = 0; p <= PHASE_LAST; ++p) {
- ir_phase *phase = irg->phases[p];
- if (phase == NULL)
- continue;
-
- phase_free(phase);
- irg->phases[p] = NULL;
- }
-}
-
#ifndef NDEBUG
void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
{
}
-
-/**
- * Register a phase on an irg.
- * The phase will then be managed by the irg. This means you can easily
- * access the phase when you only have a graph handle, the memory will be
- * freed when the graph is freed and some care is taken that the phase data
- * will be invalidated/preserved on events like dead code elemination and
- * code selection.
- */
-void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase);
-
-/**
- * Frees all phase infos attached to an irg
- */
-void irg_invalidate_phases(ir_graph *irg);
-
-/**
- * return phase with given id
- */
-static inline ir_phase *irg_get_phase(const ir_graph *irg, ir_phase_id id)
-{
- assert(id <= PHASE_LAST);
- return irg->phases[id];
-}
-
-
#define is_ir_graph(thing) _is_ir_graph(thing)
#define get_irg_start_block(irg) _get_irg_start_block(irg)
#define set_irg_start_block(irg, node) _set_irg_start_block(irg, node)
--- /dev/null
+/*
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief A nodemap. This variant is a thin wrapper around an ARR_F which
+ * uses node-indices for access. It is preferable over ir_nodehashmap
+ * if the info is dense (i.e. something is mapped for most nodes in
+ * the graph)
+ * @author Matthias Braun
+ */
+#ifndef FIRM_IRNODEMAP_H
+#define FIRM_IRNODEMAP_H
+
+#include "firm_types.h"
+#include "irgraph_t.h"
+#include "array.h"
+
+typedef struct ir_nodemap ir_nodemap;
+
+/**
+ * Allocate and initialize a new nodemap object
+ *
+ * @param irg The graph the nodemap will run on.
+ * @return A new nodemap object.
+ */
+static inline void ir_nodemap_init(ir_nodemap *nodemap, const ir_graph *irg)
+{
+ unsigned max_idx = get_irg_last_idx(irg) + 32;
+ nodemap->data = NEW_ARR_F(void*, max_idx);
+ memset(nodemap->data, 0, max_idx * sizeof(nodemap->data[0]));
+}
+
+/**
+ * frees all internal memory used by the nodemap but does not free the
+ * nodemap struct itself.
+ */
+static inline void ir_nodemap_destroy(ir_nodemap *nodemap)
+{
+ DEL_ARR_F(nodemap->data);
+ nodemap->data = NULL;
+}
+
+/**
+ * Insert a mapping from @p node to @p data.
+ */
+static inline void ir_nodemap_insert(ir_nodemap *nodemap, const ir_node *node,
+ void *data)
+{
+ unsigned idx = get_irn_idx(node);
+ size_t len = ARR_LEN(nodemap->data);
+ if (idx >= len) {
+ ARR_RESIZE(void*, nodemap->data, idx+1);
+ memset(nodemap->data + len, 0, (idx-len) * sizeof(nodemap->data[0]));
+ }
+ nodemap->data[idx] = data;
+}
+
+/**
+ * Insert a mapping from @p node to @p data (fast version).
+ *
+ * @attention You must only use this version if you can be sure that the nodemap
+ * already has enough space to store the mapping. This is the case if @p node
+ * already existed at nodemap_init() time or ir_nodemap_insert() has been used
+ * for this node)
+ */
+static inline void ir_nodemap_insert_fast(ir_nodemap *nodemap,
+ const ir_node *node, void *data)
+{
+ unsigned idx = get_irn_idx(node);
+ nodemap->data[idx] = data;
+}
+
+/**
+ * Removed mapping for @p node.
+ *
+ * This is really a shorthand form for ir_nodemap_insert(nodemap, node, NULL);
+ */
+static inline void ir_nodemap_remove(ir_nodemap *nodemap, const ir_node *node)
+{
+ ir_nodemap_insert(nodemap, node, NULL);
+}
+
+/**
+ * Get mapping for @p node. Returns NULL if nothing is mapped.
+ */
+static inline void *ir_nodemap_get(const ir_nodemap *nodemap,
+ const ir_node *node)
+{
+ unsigned idx = get_irn_idx(node);
+ if (idx >= ARR_LEN(nodemap->data))
+ return NULL;
+ return nodemap->data[idx];
+}
+
+/**
+ * Get mapping for @p node (fast version). Returns NULL if nothing is mapped.
+ *
+ * @attention You must only use this function if you can be sure that the
+ * nodemap has enough space to potentially contain the mapping. This is the
+ * case if @p node already existed at nodemap_init() time or ir_nodemap_insert()
+ * has been used for this node)
+ */
+static inline void *ir_nodemap_get_fast(const ir_nodemap *nodemap,
+ const ir_node *node)
+{
+ unsigned idx = get_irn_idx(node);
+ return nodemap->data[idx];
+}
+
+#endif
ir_tarval *computed_value(const ir_node *n)
{
vrp_attr *vrp = vrp_get_info(n);
- if (vrp && vrp->valid && tarval_cmp(vrp->bits_set, vrp->bits_not_set) == ir_relation_equal) {
+ if (vrp != NULL && vrp->bits_set == vrp->bits_not_set)
return vrp->bits_set;
- }
+
if (n->op->ops.computed_value)
return n->op->ops.computed_value(n);
return tarval_bad;
return n;
}
- if (mode_is_int(mode)) {
- vrp_attr *a_vrp = vrp_get_info(a);
- vrp_attr *b_vrp = vrp_get_info(b);
- if (a_vrp != NULL && b_vrp != NULL) {
- ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
-
- if (tarval_is_null(vrp_val)) {
- dbg_info *dbgi = get_irn_dbg_info(n);
- return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
- }
+ {
+ vrp_attr *a_vrp = vrp_get_info(a);
+ vrp_attr *b_vrp = vrp_get_info(b);
+ if (a_vrp != NULL && b_vrp != NULL) {
+ ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
+
+ if (tarval_is_null(vrp_val)) {
+ dbg_info *dbgi = get_irn_dbg_info(n);
+ return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
}
}
+ }
n = transform_bitwise_distributive(n, transform_node_Eor);
if (is_Eor(n))
if (n != oldn)
return n;
- if (mode_is_int(mode)) {
- vrp_attr *a_vrp = vrp_get_info(a);
- vrp_attr *b_vrp = vrp_get_info(b);
- if (a_vrp != NULL && b_vrp != NULL) {
- ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
-
- if (tarval_is_null(vrp_val)) {
- dbg_info *dbgi = get_irn_dbg_info(n);
- return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
- }
+ {
+ vrp_attr *a_vrp = vrp_get_info(a);
+ vrp_attr *b_vrp = vrp_get_info(b);
+ if (a_vrp != NULL && b_vrp != NULL) {
+ ir_tarval *vrp_val = tarval_and(a_vrp->bits_not_set, b_vrp->bits_not_set);
+
+ if (tarval_is_null(vrp_val)) {
+ dbg_info *dbgi = get_irn_dbg_info(n);
+ return new_rd_Add(dbgi, get_nodes_block(n), a, b, mode);
}
}
+ }
return n;
} /* transform_node_Or */
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Phase information handling using node indexes.
- * @author Sebastian Hack
- * @version $Id$
- * @brief
- * A phase contains a link to private data for each node in an ir graph.
- * A phase is independent from the globally visible link field of ir nodes.
- */
-#include "config.h"
-
-#include "array.h"
-#include "util.h"
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irphase_t.h"
-
-void *phase_irn_init_default(ir_phase *ph, const ir_node *irn)
-{
- (void) ph;
- (void) irn;
- return NULL;
-}
-
-void phase_init(ir_phase *phase, ir_graph *irg, phase_irn_init *data_init)
-{
- memset(phase, 0, sizeof(*phase));
-
- obstack_init(&phase->obst);
- phase->data_init = data_init;
- phase->irg = irg;
- phase->n_data_ptr = 0;
- phase->data_ptr = NULL;
-}
-
-ir_phase *new_phase(ir_graph *irg, phase_irn_init *data_init)
-{
- ir_phase *phase = XMALLOC(ir_phase);
- phase_init(phase, irg, data_init);
- return phase;
-}
-
-void phase_deinit(ir_phase *phase)
-{
- obstack_free(&phase->obst, NULL);
- if (phase->data_ptr)
- xfree(phase->data_ptr);
-}
-
-void phase_free(ir_phase *phase)
-{
- phase_deinit(phase);
- xfree(phase);
-}
-
-phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat)
-{
- size_t i, n;
- memset(stat, 0, sizeof(stat[0]));
-
- stat->node_map_bytes = phase->n_data_ptr * sizeof(phase->data_ptr[0]);
- stat->node_slots = phase->n_data_ptr;
- for (i = 0, n = phase->n_data_ptr; i < n; ++i) {
- if (phase->data_ptr[i] != NULL) {
- stat->node_slots_used++;
- }
- }
- stat->overall_bytes = stat->node_map_bytes + obstack_memory_used(&((ir_phase *)phase)->obst);
- return stat;
-}
-
-void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit)
-{
- size_t 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 *node = get_idx_irn(irg, i);
- phase->data_ptr[i] = data_reinit(phase, node, phase->data_ptr[i]);
- }
- }
-}
-
-ir_node *phase_get_first_node(const ir_phase *phase)
-{
- unsigned i;
-
- for (i = 0; i < phase->n_data_ptr; ++i)
- if (phase->data_ptr[i])
- return get_idx_irn(phase->irg, i);
-
- return NULL;
-}
-
-ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start)
-{
- unsigned i;
-
- for (i = get_irn_idx(start) + 1; i < phase->n_data_ptr; ++i)
- if (phase->data_ptr[i])
- return get_idx_irn(phase->irg, i);
-
- return NULL;
-}
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Phase information handling using node indexes.
- * @author Sebastian Hack
- * @version $Id: irphase_t.h 27270 2010-03-07 22:20:43Z matze $
- */
-#ifndef FIRM_IR_PHASE_H
-#define FIRM_IR_PHASE_H
-
-#include "firm_types.h"
-
-typedef struct ir_phase ir_phase;
-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
- *
- * @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);
-
-/**
- * Variant for custom memory-management/classes. Just initialize given phase
- * structure (performs no allocation, you do not need to call this for phases
- * allocated with new_phase)
- */
-void phase_init(ir_phase *phase, ir_graph *irg, phase_irn_init *data_init);
-
-/**
- * frees all internal memory used by the phase but does not free the
- * phase struct itself.
- */
-void phase_deinit(ir_phase *phase);
-
-/**
- * free memory allocated by a phase
- */
-void phase_free(ir_phase *phase);
-
-/**
- * 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 called to reinitialize phase data.
- */
-void phase_reinit_irn_data(ir_phase *phase, phase_irn_reinit *data_reinit);
-
-/**
- * A default node initializer.
- * It does nothing and returns NULL.
- */
-extern phase_irn_init phase_irn_init_default;
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Phase information handling using node indexes.
- * @author Sebastian Hack
- * @version $Id$
- */
-#ifndef FIRM_IR_PHASE_T_H
-#define FIRM_IR_PHASE_T_H
-
-#include "firm_types.h"
-#include "obst.h"
-#include "irgraph_t.h"
-#include "irtools.h"
-#include "irphase.h"
-
-/**
- * A phase object.
- */
-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. */
- 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. */
-};
-
-/**
- * For statistics: A type containing statistic data of a phase object.
- */
-typedef struct {
- size_t node_slots; /**< The number of allocated node slots. */
- size_t node_slots_used; /**< The number of used node slots, i.e. nodes that have node data. */
- size_t node_map_bytes; /**< Number of used bytes for the node map. */
- size_t overall_bytes; /**< Overall number of used bytes for the phase. */
-} phase_stat_t;
-
-/**
- * Collect Phase statistics.
- *
- * @param phase The phase.
- * @param stat Will be filled with the statistical data.
- */
-phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat);
-
-
-/**
- * Re-initialize the irn data for the given node.
- *
- * @param phase The phase.
- * @param irn The irn.
- */
-static inline void phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn,
- phase_irn_reinit *reinit)
-{
- int idx;
-
- if (! phase->data_init)
- return;
-
- idx = get_irn_idx(irn);
- if (phase->data_ptr[idx])
- phase->data_ptr[idx] = reinit(phase, irn, phase->data_ptr[idx]);
-}
-
-/**
- * Returns the first node of the phase having some data assigned.
- *
- * @param phase The phase.
- *
- * @return The first irn having some data assigned, NULL otherwise
- */
-ir_node *phase_get_first_node(const ir_phase *phase);
-
-/**
- * Returns the next node after @p start having some data assigned.
- *
- * @param phase The phase.
- * @param start The node to start from
- *
- * @return The next node after start having some data assigned, NULL otherwise
- */
-ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start);
-
-/**
- * Convenience macro to iterate over all nodes of a phase
- * having some data assigned.
- *
- * @param phase The phase.
- * @param irn A local variable that will hold the current node inside the loop.
- */
-#define foreach_phase_irn(phase, irn) \
- for (irn = phase_get_first_node(phase); irn; irn = phase_get_next_node(phase, irn))
-
-/**
- * Get the irg the phase runs on.
- *
- * @param phase The phase.
- */
-static inline ir_graph *phase_get_irg(const ir_phase *phase)
-{
- return phase->irg;
-}
-
-/**
- * Get private data pointer as passed on creating the phase.
- *
- * @param phase The phase.
- */
-static inline void *phase_get_private(const ir_phase *phase)
-{
- return phase->priv;
-}
-
-/**
- * Attach pointer with private data to phase
- */
-static inline void phase_set_private(ir_phase *phase, void *priv)
-{
- phase->priv = priv;
-}
-
-static inline void *phase_alloc(ir_phase *phase, size_t size)
-{
- return obstack_alloc(&phase->obst, size);
-}
-
-/**
- * Get the obstack of a phase.
- *
- * @param phase The phase.
- */
-static inline struct obstack *phase_obst(ir_phase *phase)
-{
- return &phase->obst;
-}
-
-/**
- * Get the phase node data for an irn.
- *
- * @param phase The phase.
- * @param irn The irn to get data for.
- *
- * @return A pointer to the node data or NULL if the irn has no phase data allocated yet.
- */
-static inline void *phase_get_irn_data(const ir_phase *ph, const ir_node *irn)
-{
- unsigned idx = get_irn_idx(irn);
- return idx < ph->n_data_ptr ? ph->data_ptr[idx] : NULL;
-}
-
-/**
- * This is private and just here for performance reasons.
- */
-static inline void private_phase_enlarge(ir_phase *phase, unsigned max_idx)
-{
- unsigned last_irg_idx = get_irg_last_idx(phase->irg);
- size_t old_cap = phase->n_data_ptr;
- size_t new_cap;
-
- /* make the maximum index at least as big as the largest index in the graph. */
- max_idx = MAX(max_idx, last_irg_idx);
- new_cap = (size_t) (max_idx + 256);
-
- phase->data_ptr = XREALLOC(phase->data_ptr, void*, new_cap);
-
- /* initialize the newly allocated memory. */
- memset(phase->data_ptr + old_cap, 0, (new_cap - old_cap) * sizeof(phase->data_ptr[0]));
- phase->n_data_ptr = new_cap;
-}
-
-/*
- * This is private and only here for performance reasons.
- */
-static inline void private_phase_assure_capacity(ir_phase *ph, unsigned max_idx)
-{
- if (max_idx >= ph->n_data_ptr)
- private_phase_enlarge(ph, max_idx);
-}
-
-
-/**
- * Get or set phase data for an irn.
- *
- * @param phase The phase.
- * @param irn The irn to get (or set) node data for.
- *
- * @return A (non-NULL) pointer to phase data for the irn. Either existent one or newly allocated one.
- */
-static inline void *phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn)
-{
- unsigned idx = get_irn_idx(irn);
- void *res;
-
- /* Assure that there's a sufficient amount of slots. */
- private_phase_assure_capacity(ph, idx + 1);
-
- res = ph->data_ptr[idx];
-
- /* If there has no irn data allocated yet, do that now. */
- if(!res) {
- phase_irn_init *data_init = ph->data_init;
-
- /* call the node data structure allocator/constructor. */
- res = ph->data_ptr[idx] = data_init(ph, irn);
- }
- return res;
-}
-
-/**
- * Set the node data for an irn.
- *
- * @param phase The phase.
- * @param irn The node.
- * @param data The node data.
- *
- * @return The old data or NULL if there was none.
- */
-static inline void *phase_set_irn_data(ir_phase *ph, const ir_node *irn,
- void *data)
-{
- unsigned idx = get_irn_idx(irn);
- void *res;
-
- /* Assure that there's a sufficient amount of slots. */
- private_phase_assure_capacity(ph, idx + 1);
-
- res = ph->data_ptr[idx];
- ph->data_ptr[idx] = data;
-
- return res;
-}
-
-/**
- * convenience function that returns phase information attached to a node
- */
-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 = irg_get_phase(irg, id);
- return phase_get_irn_data(ph, irn);
-}
-
-/**
- * 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.
- */
-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 = irg_get_phase(irg, id);
- 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 = irg_get_phase(irg, id);
- return phase_set_irn_data(ph, irn, data);
-}
-
-#endif
#include "irmemory.h"
#include "callgraph.h"
#include "irprog.h"
-#include "irphase.h"
#include "bitset.h"
#include "pset.h"
#include "obst.h"
#include "vrp.h"
-/**
- * List of phases. (We will add a register/unregister interface if managing
- * this gets too tedious)
- */
-typedef enum ir_phase_id {
- PHASE_FIRST,
- PHASE_VRP = PHASE_FIRST,
- PHASE_LAST = PHASE_VRP
-} ir_phase_id;
-ENUM_COUNTABLE(ir_phase_id)
+struct ir_nodemap {
+ void **data; /**< maps node indices to void* */
+};
/** The type of an ir_op. */
struct ir_op {
size_t max_depth; /**< Maximum depth of all Call nodes to irg. */
} cg_callee_entry;
+typedef struct ir_vrp_info {
+ struct ir_nodemap infos;
+ struct obstack obst;
+} ir_vrp_info;
+
/**
* An ir_graph holds all information for a procedure.
*/
pset *value_table; /**< Hash table for global value numbering (cse)
for optimizing use in iropt.c */
ir_def_use_edge *outs; /**< Space for the Def-Use arrays. */
+ ir_vrp_info vrp; /**< vrp info */
ir_loop *loop; /**< The outermost loop for this graph. */
void *link; /**< A void* field to link any information to
ir_node **idx_irn_map; /**< Array mapping node indexes to nodes. */
size_t index; /**< a unique number for each graph */
- ir_phase *phases[PHASE_LAST+1]; /**< Phase information. */
+ /** extra info which should survive accross multiple passes */
void *be_data; /**< backend can put in private data here */
unsigned dump_nr; /**< number of graph dumps */
transformed = conv_transform(pred, mode);
if (node != transformed) {
- vrp_attr *vrp;
-
exchange(node, transformed);
- vrp = vrp_get_info(transformed);
- if (vrp && vrp->valid) {
- vrp->range_type = VRP_VARYING;
- vrp->bits_set = tarval_convert_to(vrp->bits_set, mode);
- vrp->bits_not_set = tarval_convert_to(vrp->bits_not_set, mode);
- }
-
*changed = true;
}
}
#include "iroptimize.h"
#include "irnode_t.h"
#include "irgraph_t.h"
-#include "irphase_t.h"
#include "iredges_t.h"
#include "irhooks.h"
#include "irtools.h"
#include "irpass.h"
#include "pmap.h"
-/** a pointer to the new phases */
-static ir_phase *new_phases[PHASE_LAST + 1];
-
/**
* Reroute the inputs of a node from nodes in the old graph to copied nodes in
* the new graph
static void copy_node_dce(ir_node *node, void *env)
{
- ir_phase_id i;
- ir_node *new_node = exact_copy(node);
- ir_graph *irg = get_irn_irg(new_node);
+ ir_node *new_node = exact_copy(node);
+ ir_graph *irg = get_irn_irg(new_node);
(void) env;
/* preserve the node numbers for easier debugging */
new_node->node_nr = node->node_nr;
- /* copy phase information for this node */
- for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
- ir_phase *phase = irg_get_phase(irg, i);
- if (phase == NULL)
- continue;
- if (!phase_get_irn_data(phase, node))
- continue;
- phase_set_irn_data(new_phases[i], new_node,
- phase_get_irn_data(phase, node));
- }
-
set_irn_link(node, new_node);
hook_dead_node_elim_subst(irg, node, new_node);
}
*/
static void copy_graph_env(ir_graph *irg)
{
- ir_node *new_anchor;
- ir_phase_id i;
-
- /* init the new_phases array */
- /* TODO: this is wrong, it should only allocate a new data_ptr inside
- * the phase! */
- for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
- ir_phase *old_ph = irg_get_phase(irg, i);
- if (old_ph == NULL) {
- new_phases[i] = NULL;
- } else {
- new_phases[i] = new_phase(irg, old_ph->data_init);
- new_phases[i]->priv = old_ph->priv;
- }
- }
+ ir_node *new_anchor;
/* copy nodes */
irg_walk_anchors(irg, copy_node_dce, rewire_inputs, NULL);
new_anchor = (ir_node*)get_irn_link(irg->anchor);
assert(new_anchor != NULL);
irg->anchor = new_anchor;
-
- /* copy the new phases into the irg */
- for (i = PHASE_FIRST; i <= PHASE_LAST; ++i) {
- ir_phase *old_ph = irg_get_phase(irg, i);
- if (old_ph == NULL)
- continue;
-
- /* Matze: commented out for now: This is a memory leak, but for a real
- * fix we must not create new phases here, but reuse the old phases
- * and just create a new data array */
- /* phase_free(old_ph); */
- irg->phases[i] = new_phases[i];
- }
}
/**
free_irg_outs(irg);
free_trouts();
free_loop_information(irg);
+ free_vrp_data(irg);
clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE);
/* A quiet place, where the old obstack can rest in peace,
#include "ircons_t.h"
#include "irgmod.h"
#include "irgwalk.h"
+#include "irtools.h"
#include "tv_t.h"
#include "dbginfo_t.h"
#include "iropt_dbg.h"
#include "irpass.h"
#include "opt_polymorphy.h"
#include "irmemory.h"
-#include "irphase_t.h"
+#include "irnodehashmap.h"
#include "irgopt.h"
#include "set.h"
#include "be.h"
/** A loop entry. */
typedef struct loop_env {
- ir_phase ph; /**< the phase object */
- ir_node **stack; /**< the node stack */
- size_t tos; /**< tos index */
- unsigned nextDFSnum; /**< the current DFS number */
- unsigned POnum; /**< current post order number */
-
- unsigned changes; /**< a bitmask of graph changes */
+ ir_nodehashmap_t map;
+ struct obstack obst;
+ ir_node **stack; /**< the node stack */
+ size_t tos; /**< tos index */
+ unsigned nextDFSnum; /**< the current DFS number */
+ unsigned POnum; /**< current post order number */
+
+ unsigned changes; /**< a bitmask of graph changes */
} loop_env;
/**
*/
static node_entry *get_irn_ne(ir_node *irn, loop_env *env)
{
- ir_phase *ph = &env->ph;
- node_entry *e = (node_entry*)phase_get_irn_data(&env->ph, irn);
+ node_entry *e = (node_entry*)ir_nodehashmap_get(&env->map, irn);
- if (! e) {
- e = (node_entry*)phase_alloc(ph, sizeof(*e));
+ if (e == NULL) {
+ e = OALLOC(&env->obst, node_entry);
memset(e, 0, sizeof(*e));
- phase_set_irn_data(ph, irn, e);
+ ir_nodehashmap_insert(&env->map, irn, e);
}
return e;
} /* get_irn_ne */
if (pe->pscc != ne->pscc) {
/* not in the same SCC, is region const */
- phi_entry *pe = (phi_entry*)phase_alloc(&env->ph, sizeof(*pe));
+ phi_entry *pe = OALLOC(&env->obst, phi_entry);
pe->phi = phi;
pe->pos = j;
DB((dbg, LEVEL_1, " Created %+F in %+F\n", irn, pred));
}
pe->load = irn;
- ninfo = get_ldst_info(irn, phase_obst(&env->ph));
+ ninfo = get_ldst_info(irn, &env->obst);
ninfo->projs[pn_Load_M] = mem = new_r_Proj(irn, mode_M, pn_Load_M);
if (res == NULL) {
}
if (node->low == node->DFSnum) {
- scc *pscc = (scc*)phase_alloc(&env->ph, sizeof(*pscc));
+ scc *pscc = OALLOC(&env->obst, scc);
ir_node *x;
pscc->head = NULL;
env.nextDFSnum = 0;
env.POnum = 0;
env.changes = 0;
- phase_init(&env.ph, irg, phase_irn_init_default);
+ ir_nodehashmap_init(&env.map);
+ obstack_init(&env.obst);
/* calculate the SCC's and drive loop optimization. */
do_dfs(irg, &env);
DEL_ARR_F(env.stack);
- phase_deinit(&env.ph);
+ obstack_free(&env.obst, NULL);
+ ir_nodehashmap_destroy(&env.map);
return env.changes;
} /* optimize_loops */
#include <math.h>
#include "irbackedge_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
#include "irloop_t.h"
-
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
/**
/* Number of unrolls to perform */
static int unroll_nr;
/* Phase is used to keep copies of nodes. */
-static ir_phase *phase;
+static ir_nodemap map;
+static struct obstack obst;
/* Loop operations. */
typedef enum loop_op_t {
unrolling_node_info *info;
assert(nr != 0 && "0 reserved");
- info = (unrolling_node_info *)phase_get_irn_data(phase, n);
+ info = (unrolling_node_info*)ir_nodemap_get(&map, n);
if (! info) {
- ir_node **arr;
+ ir_node **arr = NEW_ARR_D(ir_node*, &obst, unroll_nr);
+ memset(arr, 0, unroll_nr * sizeof(ir_node*));
- info = XMALLOCZ(unrolling_node_info);
- arr = NEW_ARR_F(ir_node *, unroll_nr);
+ info = OALLOCZ(&obst, unrolling_node_info);
info->copies = arr;
- memset(info->copies, 0, (unroll_nr) * sizeof(ir_node *));
-
- phase_set_irn_data(phase, n, info);
+ ir_nodemap_insert(&map, n, info);
}
/* Original node */
info->copies[0] = n;
static ir_node *get_unroll_copy(ir_node *n, int nr)
{
ir_node *cp;
- unrolling_node_info *info = (unrolling_node_info *)phase_get_irn_data(phase, n);
+ unrolling_node_info *info = (unrolling_node_info *)ir_nodemap_get(&map, n);
if (! info)
return NULL;
/* Sets copy cp of node n. */
static void set_inversion_copy(ir_node *n, ir_node *cp)
{
- phase_set_irn_data(phase, n, cp);
+ ir_nodemap_insert(&map, n, cp);
}
/* Getter of copy of n for inversion */
static ir_node *get_inversion_copy(ir_node *n)
{
- ir_node *cp = (ir_node *)phase_get_irn_data(phase, n);
+ ir_node *cp = (ir_node *)ir_nodemap_get(&map, n);
return cp;
}
inversion_blocks_in_cc = 0;
/* Use phase to keep copy of nodes from the condition chain. */
- phase = new_phase(irg, phase_irn_init_default);
+ ir_nodemap_init(&map, irg);
+ obstack_init(&obst);
/* Search for condition chains and temporarily save the blocks in an array. */
cc_blocks = NEW_ARR_F(ir_node *, 0);
}
/* free */
- phase_free(phase);
+ obstack_free(&obst, NULL);
+ ir_nodemap_destroy(&map);
DEL_ARR_F(cond_chain_entries);
DEL_ARR_F(head_df_loop);
}
/* Use phase to keep copy of nodes from the condition chain. */
- phase = new_phase(current_ir_graph, phase_irn_init_default);
+ ir_nodemap_init(&map, current_ir_graph);
+ obstack_init(&obst);
/* Copies the loop */
copy_loop(loop_entries, unroll_nr - 1);
clear_irg_state(current_ir_graph, IR_GRAPH_STATE_CONSISTENT_DOMINANCE);
DEL_ARR_F(loop_entries);
+ obstack_free(&obst, NULL);
+ ir_nodemap_destroy(&map);
}
}
#include "irtools.h"
#include "iropt_dbg.h"
#include "irpass_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)