static ir_graph *irg;
static const arch_register_class_t *cls;
static be_lv_t *lv;
-static const ir_exec_freq *execfreqs;
static unsigned n_regs;
static unsigned *normal_regs;
static int *congruence_classes;
unsigned last_uses[2]; /**< bitset indicating last uses (input pos) */
ir_node *current_value; /**< copy of the value that should be used */
ir_node *original_value; /**< for copies point to original value */
- float prefs[0]; /**< register preferences */
+ float prefs[]; /**< register preferences */
};
typedef struct allocation_info_t allocation_info_t;
/** per basic-block information */
struct block_info_t {
bool processed; /**< indicate whether block is processed */
- ir_node *assignments[0]; /**< register assignments at end of block */
+ ir_node *assignments[]; /**< register assignments at end of block */
};
typedef struct block_info_t block_info_t;
float penalty, const unsigned* limited,
ir_node *node)
{
- ir_nodeset_iterator_t iter;
- unsigned r;
- size_t n_allowed;
- allocation_info_t *info = get_allocation_info(node);
- ir_node *neighbor;
+ unsigned r;
+ size_t n_allowed;
+ allocation_info_t *info = get_allocation_info(node);
/* give penalty for all forbidden regs */
for (r = 0; r < n_regs; ++r) {
*/
static void analyze_block(ir_node *block, void *data)
{
- float weight = (float)get_block_execfreq(execfreqs, block);
- ir_nodeset_t live_nodes;
- ir_node *node;
+ float weight = (float)get_block_execfreq(block);
+ ir_nodeset_t live_nodes;
(void) data;
ir_nodeset_init(&live_nodes);
node_idx = uf_find(congruence_classes, node_idx);
for (i = 0; i < arity; ++i) {
- ir_node *live;
- ir_node *op;
- int op_idx;
- ir_nodeset_iterator_t iter;
- bool interferes = false;
+ ir_node *op;
+ int op_idx;
+ bool interferes = false;
if (!rbitset_is_set(&req->other_same, i))
continue;
static void create_congruence_class(ir_node *block, void *data)
{
- ir_nodeset_t live_nodes;
- ir_node *node;
+ ir_nodeset_t live_nodes;
(void) data;
ir_nodeset_init(&live_nodes);
be_liveness_end_of_block(lv, cls, block, &live_nodes);
/* check should be same constraints */
+ ir_node *last_phi = NULL;
sched_foreach_reverse(block, node) {
ir_node *value;
- if (is_Phi(node))
+ if (is_Phi(node)) {
+ last_phi = node;
break;
+ }
be_foreach_definition(node, cls, value,
congruence_def(&live_nodes, value);
);
be_liveness_transfer(cls, node, &live_nodes);
}
+ if (!last_phi)
+ return;
/* check phi congruence classes */
- sched_foreach_reverse_from(node, node) {
+ sched_foreach_reverse_from(last_phi, phi) {
int i;
int arity;
int node_idx;
- assert(is_Phi(node));
+ assert(is_Phi(phi));
- if (!arch_irn_consider_in_reg_alloc(cls, node))
+ if (!arch_irn_consider_in_reg_alloc(cls, phi))
continue;
- node_idx = get_irn_idx(node);
+ node_idx = get_irn_idx(phi);
node_idx = uf_find(congruence_classes, node_idx);
- arity = get_irn_arity(node);
+ arity = get_irn_arity(phi);
for (i = 0; i < arity; ++i) {
- bool interferes = false;
- ir_nodeset_iterator_t iter;
- unsigned r;
- int old_node_idx;
- ir_node *live;
- ir_node *phi;
- allocation_info_t *head_info;
- allocation_info_t *other_info;
- ir_node *op = get_Phi_pred(node, i);
- int op_idx = get_irn_idx(op);
+ bool interferes = false;
+ unsigned r;
+ int old_node_idx;
+ allocation_info_t *head_info;
+ allocation_info_t *other_info;
+ ir_node *op = get_Phi_pred(phi, i);
+ int op_idx = get_irn_idx(op);
op_idx = uf_find(congruence_classes, op_idx);
/* do we interfere with the value */
old_node_idx = node_idx;
node_idx = uf_union(congruence_classes, node_idx, op_idx);
DB((dbg, LEVEL_3, "Merge %+F and %+F congruence classes\n",
- node, op));
+ phi, op));
old_node_idx = node_idx == old_node_idx ? op_idx : old_node_idx;
head_info = get_allocation_info(get_idx_irn(irg, node_idx));
from_reg = arch_get_irn_register(to_split);
from_r = arch_register_get_index(from_reg);
block = get_nodes_block(before);
- split_threshold = (float)get_block_execfreq(execfreqs, block) * SPLIT_DELTA;
+ split_threshold = (float)get_block_execfreq(block) * SPLIT_DELTA;
if (pref_delta < split_threshold*0.5)
return false;
info = get_allocation_info(node);
in_node = skip_Proj(node);
if (req->type & arch_register_req_type_should_be_same) {
- float weight = (float)get_block_execfreq(execfreqs, block);
+ float weight = (float)get_block_execfreq(block);
int arity = get_irn_arity(in_node);
int i;
/* solve lpp */
{
- ir_graph *irg = get_irn_irg(node);
- be_options_t *options = be_get_irg_options(irg);
- unsigned *assignment;
- lpp_solve(lpp, options->ilp_server, options->ilp_solver);
+ unsigned *assignment;
+ lpp_solve(lpp, be_options.ilp_server, be_options.ilp_solver);
if (!lpp_is_sol_valid(lpp))
panic("ilp solution not valid!");
continue;
/* give bonus for already assigned register */
- weight = (float)get_block_execfreq(execfreqs, pred_block);
+ weight = (float)get_block_execfreq(pred_block);
r = arch_register_get_index(reg);
info->prefs[r] += weight * AFF_PHI;
}
ir_node *pred_block = get_Block_cfgpred_block(block, i);
unsigned r;
float weight
- = (float)get_block_execfreq(execfreqs, pred_block) * AFF_PHI;
+ = (float)get_block_execfreq(pred_block) * AFF_PHI;
if (info->prefs[assigned_r] >= weight)
continue;
int n;
int res;
unsigned *assignment;
- ir_node *node;
hungarian_problem_t *bp;
/* count phi nodes */
*/
static void allocate_coalesce_block(ir_node *block, void *data)
{
- int i;
ir_nodeset_t live_nodes;
- ir_node *node;
int n_preds;
block_info_t *block_info;
block_info_t **pred_block_infos;
/* gather regalloc infos of predecessor blocks */
n_preds = get_Block_n_cfgpreds(block);
pred_block_infos = ALLOCAN(block_info_t*, n_preds);
- for (i = 0; i < n_preds; ++i) {
+ for (int i = 0; i < n_preds; ++i) {
ir_node *pred = get_Block_cfgpred_block(block, i);
block_info_t *pred_info = get_block_info(pred);
pred_block_infos[i] = pred_info;
phi_ins = ALLOCAN(ir_node*, n_preds);
/* collect live-in nodes and preassigned values */
- be_lv_foreach(lv, block, be_lv_state_in, i) {
+ be_lv_foreach(lv, block, be_lv_state_in, node) {
bool need_phi = false;
const arch_register_req_t *req;
const arch_register_t *reg;
int p;
- node = be_lv_get_irn(lv, block, i);
req = arch_get_irn_register_req(node);
if (req->cls != cls)
continue;
if (need_phi) {
ir_mode *mode = get_irn_mode(node);
- ir_node *phi = be_new_Phi(block, n_preds, phi_ins, mode, cls);
+ ir_node *phi = be_new_Phi(block, n_preds, phi_ins, mode,
+ cls->class_req);
DB((dbg, LEVEL_3, "Create Phi %+F (for %+F) -", phi, node));
#ifdef DEBUG_libfirm
/* all live-ins must have a register */
#ifdef DEBUG_libfirm
- {
- ir_nodeset_iterator_t iter;
- foreach_ir_nodeset(&live_nodes, node, iter) {
- const arch_register_t *reg = arch_get_irn_register(node);
- assert(reg != NULL);
- }
+ foreach_ir_nodeset(&live_nodes, node, iter) {
+ const arch_register_t *reg = arch_get_irn_register(node);
+ assert(reg != NULL);
}
#endif
/* we may not use registers used for inputs for optimistic splits */
arity = get_irn_arity(node);
- for (i = 0; i < arity; ++i) {
+ for (int i = 0; i < arity; ++i) {
ir_node *op = get_irn_n(node, i);
const arch_register_t *reg;
if (!arch_irn_consider_in_reg_alloc(cls, op))
block_costs_t *cost_info;
ir_node *block = blocklist[--p];
- float execfreq = (float)get_block_execfreq(execfreqs, block);
+ float execfreq = (float)get_block_execfreq(block);
float costs = execfreq;
int n_cfgpreds = get_Block_n_cfgpreds(block);
int p2;
static void dump(int mask, ir_graph *irg, const char *suffix)
{
- if (be_get_irg_options(irg)->dump_flags & mask)
+ if (be_options.dump_flags & mask)
dump_ir_graph(irg, suffix);
}
obstack_init(&obst);
- irg = new_irg;
- execfreqs = be_get_irg_exec_freq(irg);
+ irg = new_irg;
/* determine a good coloring order */
determine_block_order();
/* verify schedule and register pressure */
be_timer_push(T_VERIFY);
- if (be_get_irg_options(irg)->verify_option == BE_VERIFY_WARN) {
+ if (be_options.verify_option == BE_VERIFY_WARN) {
be_verify_schedule(irg);
be_verify_register_pressure(irg, cls);
- } else if (be_get_irg_options(irg)->verify_option == BE_VERIFY_ASSERT) {
+ } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
assert(be_verify_schedule(irg) && "Schedule verification failed");
assert(be_verify_register_pressure(irg, cls)
&& "Register pressure verification failed");
be_timer_pop(T_RA_SPILL_APPLY);
be_timer_push(T_VERIFY);
- if (be_get_irg_options(irg)->verify_option == BE_VERIFY_WARN) {
+ if (be_options.verify_option == BE_VERIFY_WARN) {
be_verify_register_allocation(irg);
- } else if (be_get_irg_options(irg)->verify_option == BE_VERIFY_ASSERT) {
+ } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
assert(be_verify_register_allocation(irg)
&& "Register allocation invalid");
}