/* Perform the following for each register class. */
for (j = 0, m = arch_isa_get_n_reg_class(isa); j < m; ++j) {
node_stat_t node_stat;
+ double spillcosts = 0;
chordal_env.cls = arch_isa_get_reg_class(isa, j);
chordal_env.border_heads = pmap_create();
be_pre_spill_prepare_constr(&chordal_env);
dump(BE_CH_DUMP_CONSTR, irg, chordal_env.cls, "-constr-pre", dump_ir_block_graph_sched);
+ if(be_stat_ev_is_active()) {
+ spillcosts = be_estimate_irg_costs(irg, main_env->arch_env, chordal_env.exec_freq);
+ }
+
BE_TIMER_PUSH(ra_timer.t_spill);
/* spilling */
BE_TIMER_POP(ra_timer.t_spill);
if(be_stat_ev_is_active()) {
+ spillcosts -= be_estimate_irg_costs(irg, main_env->arch_env, chordal_env.exec_freq);
+ be_stat_ev_l("spillcosts", (long) spillcosts);
+
node_stats(&chordal_env, &node_stat);
be_stat_ev("phis_after_spill", node_stat.n_phis);
be_stat_ev("mem_phis", node_stat.n_mem_phis);
if(be_stat_ev_is_active()) {
ir_snprintf(irg_name, sizeof(irg_name), "%F", irg);
+ be_stat_tags[STAT_TAG_CLS] = "<all>";
be_stat_tags[STAT_TAG_IRG] = irg_name;
be_stat_ev_push(be_stat_tags, STAT_TAG_LAST, be_stat_file);
}
arch_code_generator_before_ra(birg->cg);
BE_TIMER_POP(t_codegen);
+ if(be_stat_ev_is_active()) {
+ be_stat_ev_l("costs_before_ra",
+ (long) be_estimate_irg_costs(irg, env.arch_env, birg->execfreqs));
+ }
+
/* Do register allocation */
BE_TIMER_PUSH(t_regalloc);
ra_timer = ra->allocate(birg);
BE_TIMER_POP(t_regalloc);
+ if(be_stat_ev_is_active()) {
+ be_stat_ev_l("costs_after_ra",
+ (long) be_estimate_irg_costs(irg, env.arch_env, birg->execfreqs));
+ }
+
dump(DUMP_RA, irg, "-ra", dump_ir_block_graph_sched);
be_do_stat_nodes(irg, "06 Register Allocation");
}
}
-const char *be_stat_tags[STAT_TAG_LAST];
+typedef struct _estimate_irg_costs_env_t {
+ const arch_env_t *arch_env;
+ ir_exec_freq *execfreqs;
+ double costs;
+} estimate_irg_costs_env_t;
+
+static void estimate_block_costs(ir_node *block, void *data)
+{
+ estimate_irg_costs_env_t *env = data;
+ ir_node *node;
+ double costs = 0;
+
+ sched_foreach(block, node) {
+ costs += arch_get_op_estimated_cost(env->arch_env, node);
+ }
+
+ env->costs += costs * get_block_execfreq(env->execfreqs, block);
+}
+double be_estimate_irg_costs(ir_graph *irg, const arch_env_t *arch_env, ir_exec_freq *execfreqs)
+{
+ estimate_irg_costs_env_t env;
+ env.arch_env = arch_env;
+ env.execfreqs = execfreqs;
+ env.costs = 0;
+
+ irg_block_walk_graph(irg, estimate_block_costs, NULL, &env);
+
+ return env.costs;
+}
+
+const char *be_stat_tags[STAT_TAG_LAST];
FILE *be_stat_file = NULL;
void be_init_stat_file(const char *stat_file_name, const char *sourcefilename)
*/
void be_stat_init_irg(const arch_env_t *arch_env, ir_graph *irg);
+/**
+ * Gives a cost estimate for the program (based on execution frequencies)
+ * and backend op_estimated_cost
+ */
+double be_estimate_irg_costs(ir_graph *irg, const arch_env_t *arch_env, ir_exec_freq *execfreqs);
+
void be_init_stat_file(const char *filename, const char *sourcefilename);
void be_close_stat_file(void);
const ia32_irn_ops_t *ops = self;
if (is_Proj(irn))
- return 0;
+ return 0;
+ if (!is_ia32_irn(irn))
+ return 0;
assert(is_ia32_irn(irn));