#include "ircons_t.h"
#include "irprintf.h"
#include "execfreq.h"
+#include "dfs_t.h"
#include "xmalloc.h"
#include "beutil.h"
static int global_pass_enabled = 1;
static const lc_opt_table_entry_t options[] = {
- LC_OPT_ENT_ENUM_INT ("asf", "already spilled factor", &already_spilled_factor),
- LC_OPT_ENT_BOOL ("remat", "rematerializable ops get infinite long live ranges", &remat_live_range_ext),
- LC_OPT_ENT_BOOL ("global", "rematerializable ops get infinite long live ranges", &global_pass_enabled),
+ LC_OPT_ENT_INT ("asf", "already spilled factor", &already_spilled_factor),
+ LC_OPT_ENT_BOOL ("remat", "rematerializable ops get infinite long live ranges", &remat_live_range_ext),
+ LC_OPT_ENT_BOOL ("global", "enable/disable the global pass", &global_pass_enabled),
LC_OPT_LAST
};
typedef struct _belady_env_t {
struct obstack ob;
ir_graph *irg;
+ const dfs_t *dfs;
const arch_env_t *arch;
const arch_register_class_t *cls;
be_lv_t *lv;
use->next = curr;
use->irn = irn;
- if (curr)
+ if (curr) {
curr->is_first_use = 0;
+ assert(curr->step >= use->step);
+ }
phase_set_irn_data(&bi->next_uses, op, use);
}
static INLINE unsigned get_curr_distance(block_info_t *bi, const ir_node *irn, int is_usage)
{
belady_env_t *env = bi->bel;
+ int curr_step = sched_get_time_step(env->instr);
next_use_t *use = get_current_use(bi, irn);
- int curr_step = sched_get_time_step(irn);
int flags = arch_irn_get_flags(env->arch, irn);
assert(!(flags & arch_irn_flags_ignore));
use = use->next;
if (use) {
- unsigned res = use->step - curr_step;
+ unsigned res = use->step - curr_step;
assert(use->step >= curr_step);
return (diff > 0) - (diff < 0);
}
+static int block_order(const void *a, const void *b)
+{
+ const ir_node * const *p = a;
+ const ir_node * const *q = b;
+ block_info_t *pi = get_block_info(*p);
+ block_info_t *qi = get_block_info(*q);
+ double diff;
+
+ if (pi->exec_freq > 1.0 && qi->exec_freq > 1.0) {
+ const dfs_t *dfs = pi->bel->dfs;
+ int pp = dfs_get_post_num(dfs, pi->bl);
+ int pq = dfs_get_post_num(dfs, qi->bl);
+ return pq - pp;
+ }
+
+ diff = qi->exec_freq - pi->exec_freq;
+ return (diff > 0) - (diff < 0);
+}
+
enum {
irn_act_none = 0,
irn_act_reload,
* sort the blocks according to execution frequency.
* That's not necessary for belady() but for the global pass later on.
*/
- qsort(env->blocks, env->n_blocks, sizeof(env->blocks[0]), block_freq_gt);
+ qsort(env->blocks, env->n_blocks, sizeof(env->blocks[0]), block_order);
memset(&ges, 0, sizeof(ges));
obstack_init(&ges.obst);
/* init belady env */
obstack_init(&env.ob);
env.irg = irg;
- env.arch = birg->main_env->arch_env;
+ env.arch = be_get_birg_arch_env(birg);
env.cls = cls;
env.lv = be_get_birg_liveness(birg);
+ env.dfs = env.lv->dfs;
env.n_regs = n_regs;
env.ws = new_workset(&env, &env.ob);
env.senv = be_new_spill_env(birg);