typedef struct reloader_t reloader_t;
struct reloader_t {
reloader_t *next;
+ ir_node *can_spill_after;
ir_node *reloader;
ir_node *rematted_node;
int remat_cost_delta; /** costs needed for rematerialization,
to_spill, before));
}
-void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before,
+void be_add_reload2(spill_env_t *env, ir_node *to_spill, ir_node *before, ir_node *can_spill_after,
const arch_register_class_t *reload_cls, int allow_remat)
{
spill_info_t *info;
assert(!is_Proj(before) && !be_is_Keep(before));
/* put reload into list */
- rel = obstack_alloc(&env->obst, sizeof(rel[0]));
- rel->next = info->reloaders;
- rel->reloader = before;
- rel->rematted_node = NULL;
- if(!allow_remat) {
- rel->remat_cost_delta = REMAT_COST_INFINITE;
- } else {
- rel->remat_cost_delta = 0;
- }
+ rel = obstack_alloc(&env->obst, sizeof(rel[0]));
+ rel->next = info->reloaders;
+ rel->reloader = before;
+ rel->rematted_node = NULL;
+ rel->can_spill_after = can_spill_after;
+ rel->remat_cost_delta = allow_remat ? 0 : REMAT_COST_INFINITE;
info->reloaders = rel;
assert(info->reload_cls == NULL || info->reload_cls == reload_cls);
to_spill, before, allow_remat ? "" : " not"));
}
+void be_add_reload(spill_env_t *senv, ir_node *to_spill, ir_node *before,
+ const arch_register_class_t *reload_cls, int allow_remat)
+{
+ be_add_reload2(senv, to_spill, before, to_spill, reload_cls, allow_remat);
+
+}
+
ir_node *be_get_end_of_block_insertion_point(const ir_node *block)
{
ir_node *last = sched_last(block);
* @returns 1 if value is available, 0 otherwise
*/
static
-int is_value_available(spill_env_t *env, ir_node *arg, ir_node *reloader)
+int is_value_available(spill_env_t *env, const ir_node *arg, const ir_node *reloader)
{
if(is_Unknown(arg) || arg == new_NoMem())
return 1;
* Checks whether the node can principally be rematerialized
*/
static
-int is_remat_node(spill_env_t *env, ir_node *node)
+int is_remat_node(spill_env_t *env, const ir_node *node)
{
const arch_env_t *arch_env = env->arch_env;
* >= REMAT_COST_INFINITE if remat is not possible.
*/
static
-int check_remat_conditions_costs(spill_env_t *env, ir_node *spilled,
- ir_node *reloader, int parentcosts)
+int check_remat_conditions_costs(spill_env_t *env, const ir_node *spilled,
+ const ir_node *reloader, int parentcosts)
{
int i, arity;
int argremats;
if(parentcosts + costs >= env->reload_cost + env->spill_cost) {
return REMAT_COST_INFINITE;
}
+ if(arch_irn_is(env->arch_env, spilled, modify_flags)) {
+ return REMAT_COST_INFINITE;
+ }
argremats = 0;
for(i = 0, arity = get_irn_arity(spilled); i < arity; ++i) {
return env->reload_cost * freq;
}
+int be_is_rematerializable(spill_env_t *env, const ir_node *to_remat, const ir_node *before)
+{
+ return check_remat_conditions_costs(env, to_remat, before, 0) < REMAT_COST_INFINITE;
+}
+
double be_get_reload_costs_on_edge(spill_env_t *env, ir_node *to_spill,
ir_node *block, int pos)
{