#include "besched.h"
#include "belistsched.h"
#include "benode.h"
+#include "bemodule.h"
typedef struct usage_stats_t {
scheduled. */
} usage_stats_t;
-typedef struct {
- const list_sched_selector_t *vtab;
-} reg_pressure_main_env_t;
-
typedef struct {
struct obstack obst;
- const reg_pressure_main_env_t *main_env;
usage_stats_t *root;
ir_nodeset_t already_scheduled;
} reg_pressure_selector_env_t;
static inline usage_stats_t *get_or_set_usage_stats(reg_pressure_selector_env_t *env, ir_node *irn)
{
- usage_stats_t *us = get_irn_link(irn);
+ usage_stats_t *us = (usage_stats_t*)get_irn_link(irn);
if (!us) {
us = OALLOC(&env->obst, usage_stats_t);
static inline usage_stats_t *get_usage_stats(ir_node *irn)
{
- usage_stats_t *us = get_irn_link(irn);
+ usage_stats_t *us = (usage_stats_t*)get_irn_link(irn);
assert(us && "This node must have usage stats");
return us;
}
return res;
}
-static void *reg_pressure_graph_init(const list_sched_selector_t *vtab, ir_graph *irg)
+static void *reg_pressure_graph_init(ir_graph *irg)
{
- reg_pressure_main_env_t *main_env = XMALLOC(reg_pressure_main_env_t);
-
- main_env->vtab = vtab;
irg_walk_graph(irg, firm_clear_link, NULL, NULL);
- return main_env;
-}
-
-static inline int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn)
-{
- int res = -1;
-
- if (sel->to_appear_in_schedule)
- res = sel->to_appear_in_schedule(block_env, irn);
-
- return res >= 0 ? res : (to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_CopyKeep(irn) || be_is_Start(irn));
+ return NULL;
}
static void *reg_pressure_block_init(void *graph_env, ir_node *bl)
{
ir_node *irn;
reg_pressure_selector_env_t *env = XMALLOC(reg_pressure_selector_env_t);
+ (void) graph_env;
obstack_init(&env->obst);
ir_nodeset_init(&env->already_scheduled);
env->root = NULL;
- env->main_env = graph_env;
/*
* Collect usage statistics.
*/
sched_foreach(bl, irn) {
- if (must_appear_in_schedule(env->main_env->vtab, env, irn)) {
- int i, n;
+ int i, n;
+ if (is_Proj(irn)
+ || (arch_irn_get_flags(irn) & arch_irn_flags_not_scheduled))
+ continue;
- for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
- //ir_node *op = get_irn_n(irn, i);
- if (must_appear_in_schedule(env->main_env->vtab, env, irn)) {
- usage_stats_t *us = get_or_set_usage_stats(env, irn);
+ for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
+ usage_stats_t *us = get_or_set_usage_stats(env, irn);
#if 0 /* Liveness is not computed here! */
- if (is_live_end(bl, op))
- us->uses_in_block = 99999;
- else
+ if (is_live_end(bl, op))
+ us->uses_in_block = 99999;
+ else
#endif
- us->uses_in_block++;
- }
- }
+ us->uses_in_block++;
}
}
static void reg_pressure_block_free(void *block_env)
{
- reg_pressure_selector_env_t *env = block_env;
+ reg_pressure_selector_env_t *env = (reg_pressure_selector_env_t*)block_env;
usage_stats_t *us;
for (us = env->root; us; us = us->next)
for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
- if (must_appear_in_schedule(env->main_env->vtab, env, op))
- sum += compute_max_hops(env, op);
+ if (is_Proj(op)
+ || (arch_irn_get_flags(op) & arch_irn_flags_not_scheduled))
+ continue;
+
+ sum += compute_max_hops(env, op);
}
sum += get_result_hops_sum(env, irn);
return sum;
}
-static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set,
- ir_nodeset_t *live_set)
+static ir_node *reg_pressure_select(void *block_env, ir_nodeset_t *ready_set)
{
ir_nodeset_iterator_t iter;
- reg_pressure_selector_env_t *env = block_env;
+ reg_pressure_selector_env_t *env = (reg_pressure_selector_env_t*)block_env;
ir_node *irn, *res = NULL;
int curr_cost = INT_MAX;
- (void) live_set;
assert(ir_nodeset_size(ready_set) > 0);
return res;
}
-const list_sched_selector_t reg_pressure_selector = {
- reg_pressure_graph_init,
- reg_pressure_block_init,
- reg_pressure_select,
- NULL, /* to_appear_in_schedule */
- NULL, /* node_ready */
- NULL, /* node_selected */
- NULL, /* exectime */
- NULL, /* latency */
- reg_pressure_block_free,
- free
-};
+static void sched_reg_pressure(ir_graph *irg)
+{
+ static const list_sched_selector_t reg_pressure_selector = {
+ reg_pressure_graph_init,
+ reg_pressure_block_init,
+ reg_pressure_select,
+ NULL, /* node_ready */
+ NULL, /* node_selected */
+ reg_pressure_block_free,
+ free
+ };
+ be_list_sched_graph(irg, ®_pressure_selector);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_regpress)
+void be_init_sched_regpress(void)
+{
+ be_register_scheduler("regpress", sched_reg_pressure);
+}