- ir_node **blocks; /**< Array of all blocks. */
- int n_blocks; /**< Number of blocks in the graph. */
- int n_regs; /**< number of regs in this reg-class */
- workset_t *ws; /**< the main workset used while processing a block. ob-allocated */
- ir_node *instr; /**< current instruction */
- int instr_nr; /**< current instruction number (relative to block start) */
+ ir_node **blocks; /**< Array of all blocks. */
+ int n_blocks; /**< Number of blocks in the graph. */
+ int n_regs; /**< number of regs in this reg-class */
+ workset_t *ws; /**< the main workset used while processing a block. ob-allocated */
+ ir_node *instr; /**< current instruction */
+ int instr_nr; /**< current instruction number (relative to block start) */
- spill_env_t *senv; /**< see bespill.h */
- bitset_t *spilled; /**< bitset to keep all the irns which have already been spilled. */
+ spill_env_t *senv; /**< see bespill.h */
+ bitset_t *spilled; /**< bitset to keep all the irns which have already been spilled. */
+ ir_nodeset_t *extra_spilled; /** All nodes for which a special spill location has been computed. */
workset_t *res;
size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
res = obstack_alloc(ob, size);
workset_t *res;
size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
res = obstack_alloc(ob, size);
workset_t *res;
size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
res = obstack_alloc(ob, size);
workset_t *res;
size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
res = obstack_alloc(ob, size);
* Inserts the value @p val into the workset, iff it is not
* already contained. The workset must not be full.
*/
* Inserts the value @p val into the workset, iff it is not
* already contained. The workset must not be full.
*/
// DBG((dbg, DBG_WORKSET, "Skipped %+F\n", val));
return;
}
// DBG((dbg, DBG_WORKSET, "Skipped %+F\n", val));
return;
}
{
ir_node *bl = bel->blocks[id];
block_info_t *res = obstack_alloc(&bel->ob, sizeof(*res));
{
ir_node *bl = bel->blocks[id];
block_info_t *res = obstack_alloc(&bel->ob, sizeof(*res));
#define get_block_info(block) ((block_info_t *)get_irn_link(block))
#define set_block_info(block, info) set_irn_link(block, info)
#define get_block_info(block) ((block_info_t *)get_irn_link(block))
#define set_block_info(block, info) set_irn_link(block, info)
block_info_t *bi; /**< The block to which bring in should happen. */
int pressure_so_far; /**< The maximal pressure till the first use of irn in bl. */
ir_node *first_use; /**< The first user of irn in bl. */
block_info_t *bi; /**< The block to which bring in should happen. */
int pressure_so_far; /**< The maximal pressure till the first use of irn in bl. */
ir_node *first_use; /**< The first user of irn in bl. */
int is_remat : 1; /**< Is rematerializable. */
int sect_pressure; /**< Offset to maximum pressure in block. */
int is_remat : 1; /**< Is rematerializable. */
int sect_pressure; /**< Offset to maximum pressure in block. */
{
belady_env_t *env = bi->bel;
sched_timestep_t curr_step = sched_get_time_step(env->instr);
next_use_t *use = get_current_use(bi, irn);
{
belady_env_t *env = bi->bel;
sched_timestep_t curr_step = sched_get_time_step(env->instr);
next_use_t *use = get_current_use(bi, irn);
* @param irn The node in question.
* @return 1, if node is something transported into @p bl, 0 if not.
* @note The function will only give correct answers in the case
* @param irn The node in question.
* @return 1, if node is something transported into @p bl, 0 if not.
* @note The function will only give correct answers in the case
static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) {
belady_env_t *env = bi->bel;
workset_t *ws = env->ws;
static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) {
belady_env_t *env = bi->bel;
workset_t *ws = env->ws;
int i, len, max_allowed, demand, iter;
ir_node *val;
int i, len, max_allowed, demand, iter;
ir_node *val;
* Phis are no real instr (see insert_starters())
* instr_nr does not increase */
if (is_Proj(irn) || is_Phi(irn))
* Phis are no real instr (see insert_starters())
* instr_nr does not increase */
if (is_Proj(irn) || is_Phi(irn))
if (is_op_forking(get_irn_op(env->instr))) {
for (i = get_irn_arity(env->instr) - 1; i >= 0; --i) {
ir_node *op = get_irn_n(env->instr, i);
if (is_op_forking(get_irn_op(env->instr))) {
for (i = get_irn_arity(env->instr) - 1; i >= 0; --i) {
ir_node *op = get_irn_n(env->instr, i);
{
int id = bi->id;
assert(!ver_is_younger(ges->bs_tops_vers[id], ges->version));
return ver_is_older(ges->bs_tops_vers[id], ges->version) ? NULL : ges->bs_tops[bi->id];
}
{
int id = bi->id;
assert(!ver_is_younger(ges->bs_tops_vers[id], ges->version));
return ver_is_older(ges->bs_tops_vers[id], ges->version) ? NULL : ges->bs_tops[bi->id];
}
{
block_state_t *bs = get_block_state(ges, bi);
return bs ? bs->end_state : bi->ws_end;
{
block_state_t *bs = get_block_state(ges, bi);
return bs ? bs->end_state : bi->ws_end;
if (is_transport_in(bl, irn)) {
int i, n = get_irn_arity(bl);
if (is_transport_in(bl, irn)) {
int i, n = get_irn_arity(bl);
c = can_make_available_at_end(ges, pr, op, limit - glob_costs, level + 1);
else
c = 0.0;
c = can_make_available_at_end(ges, pr, op, limit - glob_costs, level + 1);
else
c = 0.0;
*
* If the second is larger than the first,
* we have to increment the total block pressure and hence
*
* If the second is larger than the first,
* we have to increment the total block pressure and hence
DBG((dbg, DBG_GLOBAL, "\t-> use blocked. local reload: %+F, try spill at: %+F\n",
br->first_use, better_spill_loc));
be_add_reload(env->senv, irn, br->first_use, env->cls, 1);
DBG((dbg, DBG_GLOBAL, "\t-> use blocked. local reload: %+F, try spill at: %+F\n",
br->first_use, better_spill_loc));
be_add_reload(env->senv, irn, br->first_use, env->cls, 1);
- be_add_spill(env->senv, irn, sched_next(better_spill_loc));
+ be_add_spill(env->senv, irn, better_spill_loc);
+ ir_nodeset_insert(env->extra_spilled, irn);
* which additionally live through the block to their pressure.
* at the point were the actually treated use is, we have to increase
* which additionally live through the block to their pressure.
* at the point were the actually treated use is, we have to increase
for (br = determine_global_order(env); *br; ++br)
optimize_variable(&ges, *br);
for (br = determine_global_order(env); *br; ++br)
optimize_variable(&ges, *br);
&& !bitset_contains_irn(ges.succ_phis, irn))
be_spill_phi(env->senv, irn);
}
}
&& !bitset_contains_irn(ges.succ_phis, irn))
be_spill_phi(env->senv, irn);
}
}
+
+ /* check dominance for specially spilled nodes. */
+ foreach_ir_nodeset (env->extra_spilled, irn, iter)
+ make_spill_locations_dominate_irn(env->senv, irn);
env.senv = be_new_spill_env(birg);
env.ef = be_get_birg_exec_freq(birg);
env.spilled = bitset_irg_obstack_alloc(&env.ob, irg);
env.senv = be_new_spill_env(birg);
env.ef = be_get_birg_exec_freq(birg);
env.spilled = bitset_irg_obstack_alloc(&env.ob, irg);
env.n_blocks = 0;
irg_block_walk_graph(irg, NULL, collect_blocks, &env);
env.n_blocks = 0;
irg_block_walk_graph(irg, NULL, collect_blocks, &env);
+ /* check dominance for specially spilled nodes. */
+ {
+ ir_nodeset_iterator_t iter;
+ ir_node *irn;
+
+ foreach_ir_nodeset (env.extra_spilled, irn, iter)
+ make_spill_locations_dominate_irn(env.senv, irn);
+ }
+
/* Insert spill/reload nodes into the graph and fix usages */
be_insert_spills_reloads(env.senv);
/* clean up */
be_delete_spill_env(env.senv);
/* Insert spill/reload nodes into the graph and fix usages */
be_insert_spills_reloads(env.senv);
/* clean up */
be_delete_spill_env(env.senv);