* @author Sebastian Hack, Daniel Grund, Matthias Braun, Christian Wuerdig,
* Sebastian Buchwald
* @date 04.05.2005
- * @version $Id$
*
* The problem: Given a value and a set of "copies" that are known to
* represent the same abstract value, rewire all usages of the original value
/* Last definition of a block. */
ir_node *last_definition;
- };
+ } u;
};
typedef struct constr_info constr_info;
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);
+ constr_info *info = ir_nodemap_get(constr_info, &env->infos, node);
if (info == NULL) {
info = OALLOCZ(&env->obst, constr_info);
ir_nodemap_insert(&env->infos, node, 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 ir_nodemap_get(constr_info, &env->infos, node);
}
/**
def_info->is_definition = true;
skip_info->is_definition = true;
- skip_info->definition = def;
+ skip_info->u.definition = def;
// Set the last definition if we only introduce one definition for the block
if (has_definition(block)) {
assert(!block_info->already_processed);
- block_info->last_definition = NULL;
+ block_info->u.last_definition = NULL;
} else {
mark_irn_visited(block);
- block_info->last_definition = def;
+ block_info->u.last_definition = def;
}
}
while (!waitq_empty(env->worklist)) {
int i;
ir_node *block = (ir_node*)waitq_get(env->worklist);
- ir_node **domfront = be_get_dominance_frontier(env->domfronts, block);
+ ir_node **domfront = ir_get_dominance_frontier(block);
int domfront_len = ARR_LEN(domfront);
for (i = 0; i < domfront_len; ++i) {
for (i = 0; i < n_preds; ++i) {
ins[i] = dummy;
}
- phi = be_new_Phi(block, n_preds, ins, env->mode, env->phi_cls);
+ phi = be_new_Phi(block, n_preds, ins, env->mode, env->phi_req);
sched_add_after(block, phi);
ARR_APP1(ir_node*, env->new_phis, phi);
*/
static void process_block(be_ssa_construction_env_t *env, ir_node *block)
{
- ir_node *node;
ir_node *def = NULL;
constr_info *block_info = get_or_set_info(env, block);
if (is_definition(env, node)) {
constr_info *info = get_info(env, node);
- def = info->definition;
+ def = info->u.definition;
DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
}
}
block_info->already_processed = true;
- block_info->last_definition = def;
+ block_info->u.last_definition = def;
}
/**
ir_node *block)
{
constr_info *block_info = get_or_set_info(env, block);
- ir_node *last_definition = block_info->last_definition;
+ ir_node *last_definition = block_info->u.last_definition;
if (last_definition != NULL)
return last_definition;
}
}
else {
- ir_node *def = NULL;
-
/* Search the last definition of the block. */
sched_foreach_reverse(block, def) {
if (is_definition(env, def)) {
constr_info *info = get_info(env, def);
- def = info->definition;
- DBG((dbg, LEVEL_3, "\t...found definition %+F\n", def));
-
+ DBG((dbg, LEVEL_3, "\t...found definition %+F\n", info->u.definition));
+ block_info->u.last_definition = info->u.definition;
break;
}
}
- assert(def && "No definition found");
-
- block_info->last_definition = def;
+ assert(block_info->u.last_definition && "No definition found");
}
- return block_info->last_definition;
+ return block_info->u.last_definition;
} else if (Block_block_visited(block)) {
ir_node *phi = insert_dummy_phi(env, block);
- block_info->last_definition = phi;
+ block_info->u.last_definition = phi;
return phi;
} else {
ir_node *def = get_def_at_idom(env, block);
- block_info->last_definition = def;
+ block_info->u.last_definition = def;
return def;
}
ir_node *sb = get_irg_start_block(irg);
int n_blocks = get_Block_dom_max_subtree_pre_num(sb);
- stat_ev_ctx_push_fobj("bessaconstr", irg);
+ stat_ev_ctx_push_fmt("bessaconstr", "%+F", irg);
stat_ev_tim_push();
(void) n_blocks;
stat_ev_dbl("bessaconstr_n_blocks", n_blocks);
memset(env, 0, sizeof(env[0]));
- be_assure_dom_front(irg);
env->irg = irg;
- env->domfronts = be_get_irg_dom_front(irg);
env->new_phis = NEW_ARR_F(ir_node*, 0);
env->worklist = new_waitq();
ir_nodemap_init(&env->infos, irg);
obstack_init(&env->obst);
+ assure_irg_properties(env->irg,
+ IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
+
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED
| IR_RESOURCE_BLOCK_VISITED | IR_RESOURCE_IRN_LINK);
stat_ev_ctx_pop("bessaconstr");
}
+static void determine_phi_req(be_ssa_construction_env_t *env, ir_node *value)
+{
+ const arch_register_req_t *req = arch_get_irn_register_req(value);
+ env->mode = get_irn_mode(value);
+ if (req->width == 1) {
+ env->phi_req = req->cls->class_req;
+ } else {
+ /* construct a new register req... */
+ ir_graph *irg = get_irn_irg(value);
+ struct obstack *obst = be_get_be_obst(irg);
+ arch_register_req_t *new_req = OALLOCZ(obst, arch_register_req_t);
+ new_req->cls = req->cls;
+ new_req->type = req->type & arch_register_req_type_aligned;
+ new_req->width = req->width;
+ env->phi_req = new_req;
+ }
+}
+
void be_ssa_construction_add_copy(be_ssa_construction_env_t *env,
ir_node *copy)
{
assert(env->iterated_domfront_calculated == 0);
if (env->mode == NULL) {
- env->mode = get_irn_mode(copy);
- env->phi_cls = arch_get_irn_reg_class(copy);
+ determine_phi_req(env, copy);
} else {
assert(env->mode == get_irn_mode(copy));
}
assert(env->iterated_domfront_calculated == 0);
if (env->mode == NULL) {
- env->mode = get_irn_mode(copies[0]);
- env->phi_cls = arch_get_irn_reg_class(copies[0]);
+ determine_phi_req(env, copies[0]);
}
for (i = 0; i < copies_len; ++i) {
stat_ev_tim_push();
for (i = 0; i < nodes_len; ++i) {
- const ir_edge_t *edge, *next;
ir_node *value = nodes[i];
DBG((dbg, LEVEL_3, "\tfixing users of %+F\n", value));
introduce_definition(env, value);
- foreach_out_edge_safe(value, edge, next) {
+ foreach_out_edge_safe(value, edge) {
ir_node *use = get_edge_src_irn(edge);
if (env->ignore_uses != NULL &&