#include "irprintf_t.h"
#include "array.h"
#include "debug.h"
+#include "irtools.h"
#include "besched_t.h"
#include "beutil.h"
#include "belive_t.h"
#include "belistsched.h"
+#include "beschedmris.h"
#include "bearch.h"
#include "bestat.h"
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-#define MIN(x,y) ((x) < (y) ? (x) : (y))
-
/**
* All scheduling info needed per node.
*/
static INLINE int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn)
{
- int res = 0;
+ int res = -1;
if(sel->to_appear_in_schedule)
res = sel->to_appear_in_schedule(block_env, irn);
- return res || to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_RegParams(irn);
+ return res >= 0 ? res : (to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_RegParams(irn));
}
static const list_sched_selector_t trivial_selector_struct = {
int i, n;
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
- ir_node *op = get_irn_n(irn, 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);
+#if 0 /* Liveness is not computed here! */
if(is_live_end(bl, op))
us->uses_in_block = 99999;
else
+#endif
us->uses_in_block++;
}
}
}
}
-/**
- * Compare to nodes using pointer equality.
- * @param p1 Node one.
- * @param p2 Node two.
- * @return 0 if they are identical.
- */
-static int node_cmp_func(const void *p1, const void *p2)
-{
- return p1 != p2;
-}
-
/**
* Append an instruction to a schedule.
* @param env The block scheduling environment.
assert(get_irn_mode(irn) == mode_T && "Mode of node must be tuple");
+ if(is_Bad(irn))
+ return;
+
foreach_out_edge(irn, edge) {
ir_node *out = edge->src;
if (is_Block(succ))
continue;
+ /* Phi nodes are always in "another block */
+ if (is_Phi(succ))
+ continue;
if (get_nodes_block(succ) == block)
return 0;
}
static char _mark;
#define MARK &_mark
+static firm_dbg_module_t *xxxdbg;
+
/**
* descent into a dag and create a pre-order list.
*/
for (i = get_irn_arity(root) - 1; i >= 0; --i) {
ir_node *pred = get_irn_n(root, i);
+ DBG((xxxdbg, LEVEL_3, " node %+F\n", pred));
/* Blocks may happen as predecessors of End nodes */
if (is_Block(pred))
continue;
if (get_nodes_block(pred) != block)
continue;
+ set_irn_link(pred, NULL);
+
descent(pred, block, list);
}
}
be.selector = selector;
be.sched_env = env;
FIRM_DBG_REGISTER(be.dbg, "firm.be.sched");
+ FIRM_DBG_REGISTER(xxxdbg, "firm.be.sched");
// firm_dbg_set_mask(be.dbg, SET_LEVEL_3);
preord = NULL;
for (curr = root; curr; curr = irn) {
irn = get_irn_link(curr);
+ DBG((be.dbg, LEVEL_2, " DAG root %+F\n", curr));
descent(curr, block, &preord);
}
root = preord;
const list_sched_selector_t *reg_pressure_selector = ®_pressure_selector_struct;
/* List schedule a graph. */
-void list_sched(const arch_env_t *arch_env, ir_graph *irg)
+void list_sched(const be_irg_t *birg, int enable_mris)
{
+ const arch_env_t *arch_env = birg->main_env->arch_env;
+ ir_graph *irg = birg->irg;
+
+ int num_nodes;
sched_env_t env;
- int num_nodes = get_irg_last_idx(irg);
+ mris_env_t *mris;
+
+ /* Assure, that the out edges are computed */
+ edges_assure(irg);
+
+ if(enable_mris)
+ mris = be_sched_mris_preprocess(birg);
+
+ num_nodes = get_irg_last_idx(irg);
memset(&env, 0, sizeof(env));
env.selector = arch_env->isa->impl->get_list_sched_selector(arch_env->isa);
if (env.selector->init_graph)
env.selector_env = env.selector->init_graph(env.selector, arch_env, irg);
- /* Assure, that the out edges are computed */
- edges_assure(irg);
-
/* Schedule each single block. */
irg_block_walk_graph(irg, list_sched_block, NULL, &env);
if (env.selector->finish_graph)
env.selector->finish_graph(env.selector_env);
+ if(enable_mris)
+ be_sched_mris_free(mris);
+
DEL_ARR_F(env.sched_info);
}